aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.travis.yml14
-rw-r--r--CHANGELOG.md93
-rw-r--r--CREDITS.md20
-rw-r--r--FAQ.md14
-rw-r--r--README.md12
-rw-r--r--client/package.json42
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.html67
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.scss16
-rw-r--r--client/src/app/+about/about-instance/about-instance.component.ts27
-rw-r--r--client/src/app/+about/about-instance/contact-admin-modal.component.html50
-rw-r--r--client/src/app/+about/about-instance/contact-admin-modal.component.scss11
-rw-r--r--client/src/app/+about/about-instance/contact-admin-modal.component.ts77
-rw-r--r--client/src/app/+about/about.module.ts4
-rw-r--r--client/src/app/+accounts/account-about/account-about.component.ts4
-rw-r--r--client/src/app/+accounts/account-videos/account-videos.component.ts4
-rw-r--r--client/src/app/+accounts/accounts.component.ts12
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html493
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts210
-rw-r--r--client/src/app/+admin/follows/followers-list/followers-list.component.ts8
-rw-r--r--client/src/app/+admin/follows/following-add/following-add.component.ts8
-rw-r--r--client/src/app/+admin/follows/following-list/following-list.component.ts13
-rw-r--r--client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts21
-rw-r--r--client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts6
-rw-r--r--client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts11
-rw-r--r--client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts11
-rw-r--r--client/src/app/+admin/moderation/moderation.component.scss1
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.html9
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts27
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html8
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts23
-rw-r--r--client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html10
-rw-r--r--client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts25
-rw-r--r--client/src/app/+admin/users/user-edit/user-create.component.ts10
-rw-r--r--client/src/app/+admin/users/user-edit/user-update.component.ts9
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.html5
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.scss4
-rw-r--r--client/src/app/+admin/users/user-list/user-list.component.ts42
-rw-r--r--client/src/app/+my-account/my-account-blocklist/my-account-blocklist.component.ts13
-rw-r--r--client/src/app/+my-account/my-account-blocklist/my-account-server-blocklist.component.ts11
-rw-r--r--client/src/app/+my-account/my-account-history/my-account-history.component.html27
-rw-r--r--client/src/app/+my-account/my-account-history/my-account-history.component.scss99
-rw-r--r--client/src/app/+my-account/my-account-history/my-account-history.component.ts107
-rw-r--r--client/src/app/+my-account/my-account-notifications/my-account-notifications.component.html13
-rw-r--r--client/src/app/+my-account/my-account-notifications/my-account-notifications.component.scss25
-rw-r--r--client/src/app/+my-account/my-account-notifications/my-account-notifications.component.ts14
-rw-r--r--client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.html3
-rw-r--r--client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts9
-rw-r--r--client/src/app/+my-account/my-account-ownership/my-account-ownership.component.html4
-rw-r--r--client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts15
-rw-r--r--client/src/app/+my-account/my-account-routing.module.ts20
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts7
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts8
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-notification-preferences/index.ts1
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html19
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.scss25
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts99
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts6
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-settings.component.html11
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-settings.component.ts8
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts8
-rw-r--r--client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts6
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts9
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts14
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html2
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.scss2
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts21
-rw-r--r--client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.ts6
-rw-r--r--client/src/app/+my-account/my-account-videos/my-account-videos.component.html6
-rw-r--r--client/src/app/+my-account/my-account-videos/my-account-videos.component.scss13
-rw-r--r--client/src/app/+my-account/my-account-videos/my-account-videos.component.ts20
-rw-r--r--client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html3
-rw-r--r--client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts14
-rw-r--r--client/src/app/+my-account/my-account.component.html37
-rw-r--r--client/src/app/+my-account/my-account.component.scss15
-rw-r--r--client/src/app/+my-account/my-account.component.ts105
-rw-r--r--client/src/app/+my-account/my-account.module.ts12
-rw-r--r--client/src/app/+my-account/shared/actor-avatar-info.component.ts6
-rw-r--r--client/src/app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts11
-rw-r--r--client/src/app/+verify-account/verify-account-email/verify-account-email.component.html2
-rw-r--r--client/src/app/+verify-account/verify-account-email/verify-account-email.component.ts8
-rw-r--r--client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts2
-rw-r--r--client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts6
-rw-r--r--client/src/app/+video-channels/video-channels-routing.module.ts2
-rw-r--r--client/src/app/+video-channels/video-channels.component.ts4
-rw-r--r--client/src/app/app-routing.module.ts3
-rw-r--r--client/src/app/app.component.html19
-rw-r--r--client/src/app/app.component.scss5
-rw-r--r--client/src/app/app.component.ts13
-rw-r--r--client/src/app/app.module.ts4
-rw-r--r--client/src/app/core/auth/auth-user.model.ts10
-rw-r--r--client/src/app/core/auth/auth.service.ts16
-rw-r--r--client/src/app/core/auth/index.ts1
-rw-r--r--client/src/app/core/confirm/index.ts1
-rw-r--r--client/src/app/core/core.module.ts25
-rw-r--r--client/src/app/core/index.ts1
-rw-r--r--client/src/app/core/notification/index.ts2
-rw-r--r--client/src/app/core/notification/notifier.service.ts41
-rw-r--r--client/src/app/core/notification/user-notification-socket.service.ts41
-rw-r--r--client/src/app/core/routing/login-guard.service.ts10
-rw-r--r--client/src/app/core/routing/redirect.service.ts21
-rw-r--r--client/src/app/core/routing/user-right-guard.service.ts2
-rw-r--r--client/src/app/core/server/server.service.ts16
-rw-r--r--client/src/app/header/header.component.html2
-rw-r--r--client/src/app/header/header.component.scss11
-rw-r--r--client/src/app/login/login.component.html10
-rw-r--r--client/src/app/login/login.component.ts29
-rw-r--r--client/src/app/menu/avatar-notification.component.html23
-rw-r--r--client/src/app/menu/avatar-notification.component.scss91
-rw-r--r--client/src/app/menu/avatar-notification.component.ts65
-rw-r--r--client/src/app/menu/index.ts2
-rw-r--r--client/src/app/menu/language-chooser.component.html7
-rw-r--r--client/src/app/menu/language-chooser.component.scss7
-rw-r--r--client/src/app/menu/menu.component.html6
-rw-r--r--client/src/app/menu/menu.component.scss11
-rw-r--r--client/src/app/reset-password/reset-password.component.ts13
-rw-r--r--client/src/app/search/search-filters.component.ts6
-rw-r--r--client/src/app/search/search.component.html2
-rw-r--r--client/src/app/search/search.component.scss4
-rw-r--r--client/src/app/search/search.component.ts18
-rw-r--r--client/src/app/shared/actor/actor.model.ts2
-rw-r--r--client/src/app/shared/buttons/action-dropdown.component.html2
-rw-r--r--client/src/app/shared/buttons/action-dropdown.component.scss9
-rw-r--r--client/src/app/shared/buttons/button.component.html2
-rw-r--r--client/src/app/shared/buttons/button.component.scss35
-rw-r--r--client/src/app/shared/buttons/button.component.ts3
-rw-r--r--client/src/app/shared/buttons/delete-button.component.html2
-rw-r--r--client/src/app/shared/buttons/edit-button.component.html2
-rw-r--r--client/src/app/shared/confirm/confirm.component.html (renamed from client/src/app/core/confirm/confirm.component.html)3
-rw-r--r--client/src/app/shared/confirm/confirm.component.scss (renamed from client/src/app/core/confirm/confirm.component.scss)0
-rw-r--r--client/src/app/shared/confirm/confirm.component.ts (renamed from client/src/app/core/confirm/confirm.component.ts)2
-rw-r--r--client/src/app/shared/forms/form-reactive.ts48
-rw-r--r--client/src/app/shared/forms/form-validators/form-validator.service.ts33
-rw-r--r--client/src/app/shared/forms/form-validators/index.ts1
-rw-r--r--client/src/app/shared/forms/form-validators/instance-validators.service.ts48
-rw-r--r--client/src/app/shared/forms/form-validators/user-validators.service.ts20
-rw-r--r--client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts8
-rw-r--r--client/src/app/shared/forms/form-validators/video-channel-validators.service.ts20
-rw-r--r--client/src/app/shared/forms/markdown-textarea.component.ts2
-rw-r--r--client/src/app/shared/forms/peertube-checkbox.component.html4
-rw-r--r--client/src/app/shared/forms/peertube-checkbox.component.ts5
-rw-r--r--client/src/app/shared/forms/reactive-file.component.ts17
-rw-r--r--client/src/app/shared/icons/global-icon.component.html0
-rw-r--r--client/src/app/shared/icons/global-icon.component.scss4
-rw-r--r--client/src/app/shared/icons/global-icon.component.ts48
-rw-r--r--client/src/app/shared/instance/instance.service.ts36
-rw-r--r--client/src/app/shared/menu/top-menu-dropdown.component.html21
-rw-r--r--client/src/app/shared/menu/top-menu-dropdown.component.scss18
-rw-r--r--client/src/app/shared/menu/top-menu-dropdown.component.ts83
-rw-r--r--client/src/app/shared/misc/help.component.html5
-rw-r--r--client/src/app/shared/misc/help.component.scss43
-rw-r--r--client/src/app/shared/misc/help.component.ts2
-rw-r--r--client/src/app/shared/misc/utils.ts13
-rw-r--r--client/src/app/shared/moderation/user-ban-modal.component.html7
-rw-r--r--client/src/app/shared/moderation/user-ban-modal.component.ts12
-rw-r--r--client/src/app/shared/moderation/user-moderation-dropdown.component.ts130
-rw-r--r--client/src/app/shared/renderer/html-renderer.service.ts35
-rw-r--r--client/src/app/shared/renderer/index.ts3
-rw-r--r--client/src/app/shared/renderer/linkifier.service.ts (renamed from client/src/app/videos/+video-watch/comment/linkifier.service.ts)0
-rw-r--r--client/src/app/shared/renderer/markdown.service.ts (renamed from client/src/app/videos/shared/markdown.service.ts)0
-rw-r--r--client/src/app/shared/rest/component-pagination.model.ts11
-rw-r--r--client/src/app/shared/rest/rest-extractor.service.ts1
-rw-r--r--client/src/app/shared/shared.module.ts30
-rw-r--r--client/src/app/shared/user-subscription/remote-subscribe.component.ts23
-rw-r--r--client/src/app/shared/user-subscription/subscribe-button.component.ts30
-rw-r--r--client/src/app/shared/users/index.ts1
-rw-r--r--client/src/app/shared/users/user-history.service.ts45
-rw-r--r--client/src/app/shared/users/user-notification.model.ts155
-rw-r--r--client/src/app/shared/users/user-notification.service.ts86
-rw-r--r--client/src/app/shared/users/user-notifications.component.html101
-rw-r--r--client/src/app/shared/users/user-notifications.component.scss51
-rw-r--r--client/src/app/shared/users/user-notifications.component.ts87
-rw-r--r--client/src/app/shared/users/user.model.ts37
-rw-r--r--client/src/app/shared/video-abuse/video-abuse.service.ts4
-rw-r--r--client/src/app/shared/video-blacklist/video-blacklist.service.ts7
-rw-r--r--client/src/app/shared/video/abstract-video-list.html5
-rw-r--r--client/src/app/shared/video/abstract-video-list.scss2
-rw-r--r--client/src/app/shared/video/abstract-video-list.ts7
-rw-r--r--client/src/app/shared/video/feed.component.html9
-rw-r--r--client/src/app/shared/video/feed.component.scss17
-rw-r--r--client/src/app/shared/video/video-miniature.component.scss4
-rw-r--r--client/src/app/shared/video/video.model.ts4
-rw-r--r--client/src/app/signup/signup.component.html2
-rw-r--r--client/src/app/signup/signup.component.ts10
-rw-r--r--client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.html2
-rw-r--r--client/src/app/videos/+video-edit/shared/video-edit.component.html3
-rw-r--r--client/src/app/videos/+video-edit/shared/video-edit.component.scss28
-rw-r--r--client/src/app/videos/+video-edit/shared/video-edit.component.ts5
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.html6
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.scss53
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts12
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html6
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts11
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-send.scss (renamed from client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss)29
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-send.ts5
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-upload.component.html13
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss48
-rw-r--r--client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts33
-rw-r--r--client/src/app/videos/+video-edit/video-add.component.ts14
-rw-r--r--client/src/app/videos/+video-edit/video-update.component.html4
-rw-r--r--client/src/app/videos/+video-edit/video-update.component.ts37
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment-add.component.ts9
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment.component.scss6
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment.component.ts27
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comment.service.ts6
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comments.component.ts34
-rw-r--r--client/src/app/videos/+video-watch/modal/video-blacklist.component.html9
-rw-r--r--client/src/app/videos/+video-watch/modal/video-blacklist.component.ts19
-rw-r--r--client/src/app/videos/+video-watch/modal/video-download.component.html2
-rw-r--r--client/src/app/videos/+video-watch/modal/video-download.component.ts6
-rw-r--r--client/src/app/videos/+video-watch/modal/video-report.component.html7
-rw-r--r--client/src/app/videos/+video-watch/modal/video-report.component.scss4
-rw-r--r--client/src/app/videos/+video-watch/modal/video-report.component.ts24
-rw-r--r--client/src/app/videos/+video-watch/modal/video-share.component.html2
-rw-r--r--client/src/app/videos/+video-watch/modal/video-share.component.ts6
-rw-r--r--client/src/app/videos/+video-watch/modal/video-support.component.html2
-rw-r--r--client/src/app/videos/+video-watch/modal/video-support.component.ts3
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.html24
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.scss80
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts46
-rw-r--r--client/src/app/videos/+video-watch/video-watch.module.ts4
-rw-r--r--client/src/app/videos/shared/index.ts1
-rw-r--r--client/src/app/videos/video-list/video-local.component.ts4
-rw-r--r--client/src/app/videos/video-list/video-overview.component.ts10
-rw-r--r--client/src/app/videos/video-list/video-recently-added.component.ts4
-rw-r--r--client/src/app/videos/video-list/video-trending.component.ts23
-rw-r--r--client/src/app/videos/video-list/video-user-subscriptions.component.ts4
-rw-r--r--client/src/assets/images/global/add.html (renamed from client/src/assets/images/global/add.svg)6
-rw-r--r--client/src/assets/images/global/alert.html (renamed from client/src/assets/images/video/alert.svg)9
-rw-r--r--client/src/assets/images/global/circle-tick.html12
-rw-r--r--client/src/assets/images/global/cloud-download.html11
-rw-r--r--client/src/assets/images/global/cloud-error.html11
-rw-r--r--client/src/assets/images/global/cog.html9
-rw-r--r--client/src/assets/images/global/cross.html (renamed from client/src/assets/images/global/cross.svg)6
-rw-r--r--client/src/assets/images/global/delete-black.svg14
-rw-r--r--client/src/assets/images/global/delete-grey.svg14
-rw-r--r--client/src/assets/images/global/delete.html (renamed from client/src/assets/images/global/delete-white.svg)14
-rw-r--r--client/src/assets/images/global/download.html (renamed from client/src/assets/images/video/download-black.svg)9
-rw-r--r--client/src/assets/images/global/edit-black.svg15
-rw-r--r--client/src/assets/images/global/edit.html (renamed from client/src/assets/images/global/edit-grey.svg)9
-rw-r--r--client/src/assets/images/global/help.html (renamed from client/src/assets/images/global/help.svg)12
-rw-r--r--client/src/assets/images/global/im-with-her.html (renamed from client/src/assets/images/global/im-with-her.svg)13
-rw-r--r--client/src/assets/images/global/no.html10
-rw-r--r--client/src/assets/images/global/sparkle.html11
-rw-r--r--client/src/assets/images/global/syndication.html (renamed from client/src/assets/images/global/syndication.svg)4
-rw-r--r--client/src/assets/images/global/tick.html (renamed from client/src/assets/images/global/tick.svg)6
-rw-r--r--client/src/assets/images/global/undo.html9
-rw-r--r--client/src/assets/images/global/undo.svg11
-rw-r--r--client/src/assets/images/global/user-add.html11
-rw-r--r--client/src/assets/images/global/validate.html (renamed from client/src/assets/images/global/validate.svg)6
-rw-r--r--client/src/assets/images/video/blacklist.svg15
-rw-r--r--client/src/assets/images/video/dislike-white.svg14
-rw-r--r--client/src/assets/images/video/dislike.html (renamed from client/src/assets/images/video/dislike-grey.svg)6
-rw-r--r--client/src/assets/images/video/download-grey.svg16
-rw-r--r--client/src/assets/images/video/download-white.svg16
-rw-r--r--client/src/assets/images/video/heart.html (renamed from client/src/assets/images/video/heart.svg)8
-rw-r--r--client/src/assets/images/video/like-white.svg15
-rw-r--r--client/src/assets/images/video/like.html (renamed from client/src/assets/images/video/like-grey.svg)9
-rw-r--r--client/src/assets/images/video/more.html (renamed from client/src/assets/images/video/more.svg)6
-rw-r--r--client/src/assets/images/video/share.html (renamed from client/src/assets/images/video/share.svg)9
-rw-r--r--client/src/assets/images/video/upload.html (renamed from client/src/assets/images/header/upload-white.svg)9
-rw-r--r--client/src/assets/images/video/upload.svg16
-rw-r--r--client/src/assets/player/peertube-player-local-storage.ts12
-rw-r--r--client/src/assets/player/peertube-player.ts44
-rw-r--r--client/src/assets/player/peertube-videojs-plugin.ts49
-rw-r--r--client/src/assets/player/peertube-videojs-typings.ts1
-rw-r--r--client/src/assets/player/settings-menu-item.ts13
-rw-r--r--client/src/assets/player/utils.ts1
-rw-r--r--client/src/environments/environment.ts7
-rw-r--r--client/src/locale/source/angular_en_US.xml1717
-rw-r--r--client/src/locale/source/server_en_US.xml16
-rw-r--r--client/src/locale/target/angular_ar_001.xml639
-rw-r--r--client/src/locale/target/angular_ca_ES.xml331
-rw-r--r--client/src/locale/target/angular_cs_CZ.xml705
-rw-r--r--client/src/locale/target/angular_de_DE.xml970
-rw-r--r--client/src/locale/target/angular_eo.xml407
-rw-r--r--client/src/locale/target/angular_es_ES.xml2444
-rw-r--r--client/src/locale/target/angular_eu_ES.xml942
-rw-r--r--client/src/locale/target/angular_fa_IR.xml88
-rw-r--r--client/src/locale/target/angular_fr_FR.xml1191
-rw-r--r--client/src/locale/target/angular_gl_ES.xml154
-rw-r--r--client/src/locale/target/angular_it_IT.xml685
-rw-r--r--client/src/locale/target/angular_ja_JP.xml290
-rw-r--r--client/src/locale/target/angular_jbo.xml262
-rw-r--r--client/src/locale/target/angular_nl_NL.xml4533
-rw-r--r--client/src/locale/target/angular_oc.xml813
-rw-r--r--client/src/locale/target/angular_pl_PL.xml462
-rw-r--r--client/src/locale/target/angular_pt_BR.xml569
-rw-r--r--client/src/locale/target/angular_ru_RU.xml355
-rw-r--r--client/src/locale/target/angular_sv_SE.xml764
-rw-r--r--client/src/locale/target/angular_ta.xml22
-rw-r--r--client/src/locale/target/angular_zh_Hans_CN.xml604
-rw-r--r--client/src/locale/target/angular_zh_Hant_TW.xml654
-rw-r--r--client/src/locale/target/iso639_nl_NL.xml22
-rw-r--r--client/src/locale/target/iso639_pl_PL.xml695
-rw-r--r--client/src/locale/target/player_ar_001.xml2
-rw-r--r--client/src/locale/target/player_it_IT.json1
-rw-r--r--client/src/locale/target/player_nl_NL.xml4
-rw-r--r--client/src/locale/target/player_pl_PL.json1
-rw-r--r--client/src/locale/target/player_pl_PL.xml383
-rw-r--r--client/src/locale/target/player_ru_RU.json1
-rw-r--r--client/src/locale/target/server_cs_CZ.json2
-rw-r--r--client/src/locale/target/server_fr_FR.json2
-rw-r--r--client/src/locale/target/server_it_IT.json1
-rw-r--r--client/src/locale/target/server_nl_NL.xml34
-rw-r--r--client/src/locale/target/server_pl_PL.json1
-rw-r--r--client/src/locale/target/server_pl_PL.xml147
-rw-r--r--client/src/locale/target/server_ru_RU.json1
-rw-r--r--client/src/manifest.webmanifest2
-rw-r--r--client/src/polyfills.ts8
-rw-r--r--client/src/sass/application.scss13
-rw-r--r--client/src/sass/include/_bootstrap-variables.scss3
-rw-r--r--client/src/sass/include/_mixins.scss54
-rw-r--r--client/src/sass/include/_variables.scss9
-rw-r--r--client/src/sass/primeng-custom.scss180
-rw-r--r--client/src/standalone/videos/embed.html2
-rw-r--r--client/src/standalone/videos/embed.ts58
-rw-r--r--client/yarn.lock1624
-rw-r--r--config/default.yaml15
-rw-r--r--config/production.yaml.example13
-rw-r--r--config/test-1.yaml2
-rw-r--r--config/test-2.yaml3
-rw-r--r--config/test-3.yaml2
-rw-r--r--config/test-4.yaml2
-rw-r--r--config/test-5.yaml2
-rw-r--r--config/test-6.yaml2
-rw-r--r--config/test.yaml6
-rw-r--r--package.json15
-rwxr-xr-xscripts/build/client.sh2
-rwxr-xr-xscripts/clean/server/test.sh1
-rwxr-xr-xscripts/generate-code-contributors.ts10
-rwxr-xr-xscripts/i18n/create-custom-files.ts8
-rwxr-xr-xscripts/prune-storage.ts7
-rwxr-xr-xscripts/upgrade.sh10
-rw-r--r--server.ts19
-rw-r--r--server/controllers/api/accounts.ts11
-rw-r--r--server/controllers/api/config.ts63
-rw-r--r--server/controllers/api/server/contact.ts28
-rw-r--r--server/controllers/api/server/index.ts2
-rw-r--r--server/controllers/api/server/stats.ts7
-rw-r--r--server/controllers/api/users/index.ts9
-rw-r--r--server/controllers/api/users/me.ts163
-rw-r--r--server/controllers/api/users/my-history.ts57
-rw-r--r--server/controllers/api/users/my-notifications.ts108
-rw-r--r--server/controllers/api/users/my-subscriptions.ts170
-rw-r--r--server/controllers/api/video-channel.ts14
-rw-r--r--server/controllers/api/videos/abuse.ts3
-rw-r--r--server/controllers/api/videos/blacklist.ts31
-rw-r--r--server/controllers/api/videos/captions.ts4
-rw-r--r--server/controllers/api/videos/comment.ts3
-rw-r--r--server/controllers/api/videos/import.ts21
-rw-r--r--server/controllers/api/videos/index.ts45
-rw-r--r--server/controllers/bots.ts101
-rw-r--r--server/controllers/client.ts21
-rw-r--r--server/controllers/feeds.ts2
-rw-r--r--server/controllers/index.ts1
-rw-r--r--server/controllers/static.ts15
-rw-r--r--server/controllers/tracker.ts21
-rw-r--r--server/helpers/activitypub.ts4
-rw-r--r--server/helpers/captions-utils.ts4
-rw-r--r--server/helpers/core-utils.ts20
-rw-r--r--server/helpers/custom-validators/activitypub/activity.ts99
-rw-r--r--server/helpers/custom-validators/activitypub/actor.ts29
-rw-r--r--server/helpers/custom-validators/activitypub/announce.ts13
-rw-r--r--server/helpers/custom-validators/activitypub/cache-file.ts16
-rw-r--r--server/helpers/custom-validators/activitypub/flag.ts14
-rw-r--r--server/helpers/custom-validators/activitypub/misc.ts24
-rw-r--r--server/helpers/custom-validators/activitypub/rate.ts15
-rw-r--r--server/helpers/custom-validators/activitypub/undo.ts20
-rw-r--r--server/helpers/custom-validators/activitypub/video-comments.ts11
-rw-r--r--server/helpers/custom-validators/activitypub/videos.ts19
-rw-r--r--server/helpers/custom-validators/activitypub/view.ts10
-rw-r--r--server/helpers/custom-validators/misc.ts5
-rw-r--r--server/helpers/custom-validators/servers.ts11
-rw-r--r--server/helpers/custom-validators/user-notifications.ts23
-rw-r--r--server/helpers/custom-validators/users.ts5
-rw-r--r--server/helpers/custom-validators/video-captions.ts4
-rw-r--r--server/helpers/custom-validators/video-imports.ts4
-rw-r--r--server/helpers/custom-validators/videos.ts13
-rw-r--r--server/helpers/express-utils.ts4
-rw-r--r--server/helpers/ffmpeg-utils.ts10
-rw-r--r--server/helpers/image-utils.ts14
-rw-r--r--server/helpers/regexp.ts23
-rw-r--r--server/helpers/requests.ts9
-rw-r--r--server/helpers/utils.ts12
-rw-r--r--server/helpers/webtorrent.ts6
-rw-r--r--server/helpers/youtube-dl.ts4
-rw-r--r--server/initializers/checker-after-init.ts14
-rw-r--r--server/initializers/checker-before-init.ts5
-rw-r--r--server/initializers/constants.ts134
-rw-r--r--server/initializers/database.ts6
-rw-r--r--server/initializers/migrations/0295-video-file-extname.ts49
-rw-r--r--server/initializers/migrations/0300-user-videos-history-enabled.ts27
-rw-r--r--server/initializers/migrations/0305-fix-unfederated-videos.ts52
-rw-r--r--server/initializers/migrations/0310-drop-unused-video-indexes.ts32
-rw-r--r--server/initializers/migrations/0315-user-notifications.ts47
-rw-r--r--server/initializers/migrations/0320-blacklist-unfederate.ts27
-rw-r--r--server/initializers/migrations/0325-video-abuse-fields.ts37
-rw-r--r--server/lib/activitypub/actor.ts137
-rw-r--r--server/lib/activitypub/process/process-accept.ts1
-rw-r--r--server/lib/activitypub/process/process-announce.ts8
-rw-r--r--server/lib/activitypub/process/process-create.ts125
-rw-r--r--server/lib/activitypub/process/process-dislike.ts52
-rw-r--r--server/lib/activitypub/process/process-flag.ts49
-rw-r--r--server/lib/activitypub/process/process-follow.ts14
-rw-r--r--server/lib/activitypub/process/process-like.ts3
-rw-r--r--server/lib/activitypub/process/process-undo.ts8
-rw-r--r--server/lib/activitypub/process/process-update.ts2
-rw-r--r--server/lib/activitypub/process/process-view.ts35
-rw-r--r--server/lib/activitypub/process/process.ts14
-rw-r--r--server/lib/activitypub/share.ts20
-rw-r--r--server/lib/activitypub/video-comments.ts4
-rw-r--r--server/lib/activitypub/video-rates.ts4
-rw-r--r--server/lib/activitypub/videos.ts54
-rw-r--r--server/lib/cache/actor-follow-score-cache.ts46
-rw-r--r--server/lib/cache/index.ts1
-rw-r--r--server/lib/client-html.ts61
-rw-r--r--server/lib/emailer.ts261
-rw-r--r--server/lib/job-queue/handlers/activitypub-follow.ts9
-rw-r--r--server/lib/job-queue/handlers/activitypub-http-broadcast.ts3
-rw-r--r--server/lib/job-queue/handlers/activitypub-http-unicast.ts6
-rw-r--r--server/lib/job-queue/handlers/activitypub-refresher.ts26
-rw-r--r--server/lib/job-queue/handlers/email.ts3
-rw-r--r--server/lib/job-queue/handlers/video-file.ts47
-rw-r--r--server/lib/job-queue/handlers/video-import.ts23
-rw-r--r--server/lib/job-queue/handlers/video-views.ts4
-rw-r--r--server/lib/job-queue/job-queue.ts5
-rw-r--r--server/lib/notifier.ts455
-rw-r--r--server/lib/oauth-model.ts3
-rw-r--r--server/lib/peertube-socket.ts52
-rw-r--r--server/lib/redis.ts33
-rw-r--r--server/lib/schedulers/abstract-scheduler.ts18
-rw-r--r--server/lib/schedulers/actor-follow-scheduler.ts (renamed from server/lib/schedulers/bad-actor-follow-scheduler.ts)23
-rw-r--r--server/lib/schedulers/remove-old-jobs-scheduler.ts6
-rw-r--r--server/lib/schedulers/update-videos-scheduler.ts32
-rw-r--r--server/lib/schedulers/videos-redundancy-scheduler.ts17
-rw-r--r--server/lib/schedulers/youtube-dl-update-scheduler.ts2
-rw-r--r--server/lib/user.ts23
-rw-r--r--server/lib/video-transcoding.ts4
-rw-r--r--server/middlewares/csp.ts44
-rw-r--r--server/middlewares/dnt.ts2
-rw-r--r--server/middlewares/index.ts2
-rw-r--r--server/middlewares/oauth.ts22
-rw-r--r--server/middlewares/validators/config.ts19
-rw-r--r--server/middlewares/validators/index.ts1
-rw-r--r--server/middlewares/validators/server.ts49
-rw-r--r--server/middlewares/validators/sort.ts5
-rw-r--r--server/middlewares/validators/user-history.ts26
-rw-r--r--server/middlewares/validators/user-notifications.ts63
-rw-r--r--server/middlewares/validators/users.ts11
-rw-r--r--server/middlewares/validators/videos/video-blacklist.ts15
-rw-r--r--server/middlewares/validators/videos/video-watch.ts7
-rw-r--r--server/models/account/account-blocklist.ts31
-rw-r--r--server/models/account/account.ts25
-rw-r--r--server/models/account/user-notification-setting.ts150
-rw-r--r--server/models/account/user-notification.ts472
-rw-r--r--server/models/account/user-video-history.ts33
-rw-r--r--server/models/account/user.ts180
-rw-r--r--server/models/activitypub/actor-follow.ts58
-rw-r--r--server/models/activitypub/actor.ts1
-rw-r--r--server/models/redundancy/video-redundancy.ts10
-rw-r--r--server/models/utils.ts6
-rw-r--r--server/models/video/video-abuse.ts24
-rw-r--r--server/models/video/video-blacklist.ts31
-rw-r--r--server/models/video/video-channel.ts25
-rw-r--r--server/models/video/video-comment.ts45
-rw-r--r--server/models/video/video-file.ts26
-rw-r--r--server/models/video/video-format-utils.ts6
-rw-r--r--server/models/video/video-import.ts4
-rw-r--r--server/models/video/video.ts112
-rw-r--r--server/tests/api/activitypub/client.ts6
-rw-r--r--server/tests/api/activitypub/fetch.ts9
-rw-r--r--server/tests/api/activitypub/helpers.ts10
-rw-r--r--server/tests/api/activitypub/refresher.ts19
-rw-r--r--server/tests/api/activitypub/security.ts12
-rw-r--r--server/tests/api/check-params/accounts.ts14
-rw-r--r--server/tests/api/check-params/blocklist.ts8
-rw-r--r--server/tests/api/check-params/config.ts6
-rw-r--r--server/tests/api/check-params/contact-form.ts96
-rw-r--r--server/tests/api/check-params/follows.ts8
-rw-r--r--server/tests/api/check-params/index.ts3
-rw-r--r--server/tests/api/check-params/jobs.ts18
-rw-r--r--server/tests/api/check-params/redundancy.ts2
-rw-r--r--server/tests/api/check-params/search.ts8
-rw-r--r--server/tests/api/check-params/services.ts10
-rw-r--r--server/tests/api/check-params/user-notifications.ts297
-rw-r--r--server/tests/api/check-params/user-subscriptions.ts11
-rw-r--r--server/tests/api/check-params/users.ts31
-rw-r--r--server/tests/api/check-params/video-abuses.ts14
-rw-r--r--server/tests/api/check-params/video-blacklist.ts126
-rw-r--r--server/tests/api/check-params/video-captions.ts4
-rw-r--r--server/tests/api/check-params/video-channels.ts8
-rw-r--r--server/tests/api/check-params/video-comments.ts10
-rw-r--r--server/tests/api/check-params/video-imports.ts10
-rw-r--r--server/tests/api/check-params/videos-filter.ts2
-rw-r--r--server/tests/api/check-params/videos-history.ts72
-rw-r--r--server/tests/api/check-params/videos.ts17
-rw-r--r--server/tests/api/redundancy/redundancy.ts36
-rw-r--r--server/tests/api/search/search-activitypub-video-channels.ts6
-rw-r--r--server/tests/api/search/search-activitypub-videos.ts4
-rw-r--r--server/tests/api/search/search-videos.ts2
-rw-r--r--server/tests/api/server/config.ts56
-rw-r--r--server/tests/api/server/contact-form.ts86
-rw-r--r--server/tests/api/server/email.ts16
-rw-r--r--server/tests/api/server/follow-constraints.ts20
-rw-r--r--server/tests/api/server/follows.ts27
-rw-r--r--server/tests/api/server/handle-down.ts16
-rw-r--r--server/tests/api/server/index.ts1
-rw-r--r--server/tests/api/server/jobs.ts12
-rw-r--r--server/tests/api/server/no-client.ts4
-rw-r--r--server/tests/api/server/reverse-proxy.ts4
-rw-r--r--server/tests/api/server/stats.ts14
-rw-r--r--server/tests/api/server/tracker.ts4
-rw-r--r--server/tests/api/users/blocklist.ts12
-rw-r--r--server/tests/api/users/index.ts3
-rw-r--r--server/tests/api/users/user-notifications.ts1017
-rw-r--r--server/tests/api/users/user-subscriptions.ts19
-rw-r--r--server/tests/api/users/users-multiple-servers.ts10
-rw-r--r--server/tests/api/users/users-verification.ts13
-rw-r--r--server/tests/api/users/users.ts12
-rw-r--r--server/tests/api/videos/index.ts1
-rw-r--r--server/tests/api/videos/multiple-servers.ts15
-rw-r--r--server/tests/api/videos/services.ts12
-rw-r--r--server/tests/api/videos/single-server.ts2
-rw-r--r--server/tests/api/videos/video-abuse.ts6
-rw-r--r--server/tests/api/videos/video-blacklist-management.ts192
-rw-r--r--server/tests/api/videos/video-blacklist.ts305
-rw-r--r--server/tests/api/videos/video-captions.ts15
-rw-r--r--server/tests/api/videos/video-change-ownership.ts4
-rw-r--r--server/tests/api/videos/video-channels.ts6
-rw-r--r--server/tests/api/videos/video-comments.ts6
-rw-r--r--server/tests/api/videos/video-description.ts6
-rw-r--r--server/tests/api/videos/video-imports.ts6
-rw-r--r--server/tests/api/videos/video-nsfw.ts17
-rw-r--r--server/tests/api/videos/video-privacy.ts12
-rw-r--r--server/tests/api/videos/video-schedule-update.ts4
-rw-r--r--server/tests/api/videos/video-transcoder.ts34
-rw-r--r--server/tests/api/videos/videos-filter.ts2
-rw-r--r--server/tests/api/videos/videos-history.ts87
-rw-r--r--server/tests/api/videos/videos-overview.ts4
-rw-r--r--server/tests/cli/create-import-video-file-job.ts4
-rw-r--r--server/tests/cli/create-transcoding-job.ts4
-rw-r--r--server/tests/cli/index.ts1
-rw-r--r--server/tests/cli/optimize-old-videos.ts4
-rw-r--r--server/tests/cli/peertube.ts2
-rw-r--r--server/tests/cli/reset-password.ts2
-rw-r--r--server/tests/cli/update-host.ts8
-rw-r--r--server/tests/client.ts2
-rw-r--r--server/tests/feeds/feeds.ts6
-rw-r--r--server/tests/fixtures/video_short.avibin0 -> 584656 bytes
-rw-r--r--server/tests/fixtures/video_short.mkvbin0 -> 40642 bytes
-rw-r--r--server/tests/fixtures/video_short_240p.mp4bin0 -> 14082 bytes
-rw-r--r--server/tests/helpers/comment-model.ts25
-rw-r--r--server/tests/helpers/core-utils.ts52
-rw-r--r--server/tests/helpers/index.ts1
-rw-r--r--server/tests/misc-endpoints.ts82
-rw-r--r--server/tests/real-world/populate-database.ts2
-rw-r--r--server/tests/real-world/real-world.ts4
-rw-r--r--server/tests/utils/miscs/email.ts25
-rw-r--r--server/tests/utils/videos/video-history.ts14
-rw-r--r--server/tools/peertube-get-access-token.ts2
-rw-r--r--server/tools/peertube-import-videos.ts26
-rw-r--r--server/tools/peertube-upload.ts4
-rw-r--r--shared/models/activitypub/activity.ts31
-rw-r--r--shared/models/activitypub/objects/object.model.ts1
-rw-r--r--shared/models/actors/actor.model.ts2
-rw-r--r--shared/models/i18n/i18n.ts9
-rw-r--r--shared/models/server/contact-form.model.ts5
-rw-r--r--shared/models/server/custom-config.model.ts5
-rw-r--r--shared/models/server/index.ts6
-rw-r--r--shared/models/server/server-config.model.ts14
-rw-r--r--shared/models/server/server-stats.model.ts1
-rw-r--r--shared/models/users/index.ts2
-rw-r--r--shared/models/users/user-notification-setting.model.ts17
-rw-r--r--shared/models/users/user-notification.model.ts83
-rw-r--r--shared/models/users/user-right.enum.ts5
-rw-r--r--shared/models/users/user-role.ts3
-rw-r--r--shared/models/users/user-update-me.model.ts7
-rw-r--r--shared/models/users/user.model.ts6
-rw-r--r--shared/models/videos/blacklist/video-blacklist-create.model.ts1
-rw-r--r--shared/models/videos/blacklist/video-blacklist.model.ts1
-rw-r--r--shared/models/videos/video.model.ts4
-rw-r--r--shared/utils/cli/cli.ts (renamed from server/tests/utils/cli/cli.ts)0
-rw-r--r--shared/utils/feeds/feeds.ts (renamed from server/tests/utils/feeds/feeds.ts)0
-rw-r--r--shared/utils/index.ts (renamed from server/tests/utils/index.ts)4
-rw-r--r--shared/utils/miscs/email-child-process.js27
-rw-r--r--shared/utils/miscs/email.ts64
-rw-r--r--shared/utils/miscs/miscs.ts (renamed from server/tests/utils/miscs/miscs.ts)8
-rw-r--r--shared/utils/miscs/sql.ts (renamed from server/tests/utils/miscs/sql.ts)0
-rw-r--r--shared/utils/miscs/stubs.ts (renamed from server/tests/utils/miscs/stubs.ts)0
-rw-r--r--shared/utils/overviews/overviews.ts (renamed from server/tests/utils/overviews/overviews.ts)0
-rw-r--r--shared/utils/requests/activitypub.ts (renamed from server/tests/utils/requests/activitypub.ts)8
-rw-r--r--shared/utils/requests/check-api-params.ts (renamed from server/tests/utils/requests/check-api-params.ts)0
-rw-r--r--shared/utils/requests/requests.ts (renamed from server/tests/utils/requests/requests.ts)4
-rw-r--r--shared/utils/search/video-channels.ts (renamed from server/tests/utils/search/video-channels.ts)0
-rw-r--r--shared/utils/search/videos.ts (renamed from server/tests/utils/search/videos.ts)2
-rw-r--r--shared/utils/server/activitypub.ts (renamed from server/tests/utils/server/activitypub.ts)0
-rw-r--r--shared/utils/server/clients.ts (renamed from server/tests/utils/server/clients.ts)0
-rw-r--r--shared/utils/server/config.ts (renamed from server/tests/utils/server/config.ts)6
-rw-r--r--shared/utils/server/contact-form.ts28
-rw-r--r--shared/utils/server/follows.ts (renamed from server/tests/utils/server/follows.ts)0
-rw-r--r--shared/utils/server/jobs.ts (renamed from server/tests/utils/server/jobs.ts)22
-rw-r--r--shared/utils/server/redundancy.ts (renamed from server/tests/utils/server/redundancy.ts)0
-rw-r--r--shared/utils/server/servers.ts (renamed from server/tests/utils/server/servers.ts)29
-rw-r--r--shared/utils/server/stats.ts (renamed from server/tests/utils/server/stats.ts)0
-rw-r--r--shared/utils/socket/socket-io.ts13
-rw-r--r--shared/utils/users/accounts.ts (renamed from server/tests/utils/users/accounts.ts)2
-rw-r--r--shared/utils/users/blocklist.ts (renamed from server/tests/utils/users/blocklist.ts)0
-rw-r--r--shared/utils/users/login.ts (renamed from server/tests/utils/users/login.ts)0
-rw-r--r--shared/utils/users/user-notifications.ts437
-rw-r--r--shared/utils/users/user-subscriptions.ts (renamed from server/tests/utils/users/user-subscriptions.ts)0
-rw-r--r--shared/utils/users/users.ts (renamed from server/tests/utils/users/users.ts)20
-rw-r--r--shared/utils/videos/services.ts (renamed from server/tests/utils/videos/services.ts)0
-rw-r--r--shared/utils/videos/video-abuses.ts (renamed from server/tests/utils/videos/video-abuses.ts)2
-rw-r--r--shared/utils/videos/video-blacklist.ts (renamed from server/tests/utils/videos/video-blacklist.ts)11
-rw-r--r--shared/utils/videos/video-captions.ts (renamed from server/tests/utils/videos/video-captions.ts)0
-rw-r--r--shared/utils/videos/video-change-ownership.ts (renamed from server/tests/utils/videos/video-change-ownership.ts)0
-rw-r--r--shared/utils/videos/video-channels.ts (renamed from server/tests/utils/videos/video-channels.ts)2
-rw-r--r--shared/utils/videos/video-comments.ts (renamed from server/tests/utils/videos/video-comments.ts)0
-rw-r--r--shared/utils/videos/video-history.ts39
-rw-r--r--shared/utils/videos/video-imports.ts (renamed from server/tests/utils/videos/video-imports.ts)8
-rw-r--r--shared/utils/videos/videos.ts (renamed from server/tests/utils/videos/videos.ts)9
-rw-r--r--support/doc/api/openapi.yaml139
-rw-r--r--support/doc/tools.md99
-rw-r--r--support/docker/production/.env1
-rw-r--r--support/docker/production/config/custom-environment-variables.yaml9
-rw-r--r--support/docker/production/config/production.yaml2
-rwxr-xr-xsupport/docker/production/docker-entrypoint.sh4
-rwxr-xr-xsupport/freebsd/peertube5
-rw-r--r--support/nginx/peertube33
-rw-r--r--support/systemd/peertube.service19
-rw-r--r--yarn.lock508
631 files changed, 25925 insertions, 12499 deletions
diff --git a/.travis.yml b/.travis.yml
index 3a73e4fc0..d252ae625 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -48,12 +48,12 @@ matrix:
48 - env: TEST_SUITE=jest 48 - env: TEST_SUITE=jest
49 49
50script: 50script:
51 - travis_retry npm run travis -- "$TEST_SUITE" 51 - NODE_PENDING_JOB_WAIT=1000 travis_retry npm run travis -- "$TEST_SUITE"
52 52
53after_failure: 53after_failure:
54 - cat test1/logs/all-logs.log 54 - cat test1/logs/peertube.log
55 - cat test2/logs/all-logs.log 55 - cat test2/logs/peertube.log
56 - cat test3/logs/all-logs.log 56 - cat test3/logs/peertube.log
57 - cat test4/logs/all-logs.log 57 - cat test4/logs/peertube.log
58 - cat test5/logs/all-logs.log 58 - cat test5/logs/peertube.log
59 - cat test6/logs/all-logs.log 59 - cat test6/logs/peertube.log
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cce6e7402..13bec7535 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,101 @@
1# Changelog 1# Changelog
2 2
3## v1.2.0
4
5### BREAKING CHANGES
6
7 * **Docker:** `PEERTUBE_TRUST_PROXY` env variable is now an array ([LecygneNoir](https://github.com/LecygneNoir))
8 * **Docker:** Check you have all the storage fields in your `/config/production.yaml` file: https://github.com/Chocobozzz/PeerTube/blob/develop/support/docker/production/config/production.yaml#L34
9 * **nginx:** Add redundancy endpoint in static file. **You should add it in your nginx configuration: https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/production.md#nginx**
10 * **nginx:** Add socket io endpoint. **You should add it in your nginx configuration: https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/production.md#nginx**
11 * Moderators can manage users now (add/delete/update/block)
12 * Add `tmp` and `redundancy` directories in configuration file. **You should configure them in your production.yaml**
13
14### Maintenance
15
16 * Check free storage before upgrading in upgrade script ([@Nutomic](https://github.com/nutomic))
17 * Explain that PeerTube must be stopped in prune storage script
18 * Add some security directives in the systemd unit configuration file ([@rigelk](https://github.com/rigelk) & [@mkoppmann](https://github.com/mkoppmann))
19 * Update FreeBSD startup script ([@gegeweb](https://github.com/gegeweb))
20
21### Docker
22
23 * Patch docker entrypoint to speed up the chown at startup ([LecygneNoir](https://github.com/LecygneNoir))
24
25### Features
26
27 * Add Russian, Polish and Italian languages
28 * Add user notifications:
29 * Notification types:
30 * Comment on my video
31 * New video from my subscriptions
32 * New video abuses (for moderators)
33 * Blacklist/Unblacklist on my video
34 * Video import finished (error or success)
35 * Pending video published (after transcoding or a scheduled update)
36 * My account or one of my channel has a new follower
37 * Someone (except muted accounts) mentioned me in comments
38 * A user registered on the instance (for moderators)
39 * Notification actions:
40 * Add a web notification
41 * Send an english email
42 * Add contact form in about page (**enabled by default**)
43 * Add ability to unfederate a local video in blacklist modal (**checkbox checked by default**)
44 * Support additional video extensions if transcoding is enabled (**enabled by default**)
45 * Redirect to the last url on login
46 * Add ability to automatically set the video caption in URL. Example: https://peertube2.cpy.re/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d?subtitle=ru
47 * Automatically enable the last selected caption when watching a video
48 * Add ability to disable, clear and list user videos history
49 * Add a button to help to translate peertube
50 * Add text in the report modal to explain to whom the report will be sent
51 * Open my account menu entries on hover
52 * Explain what features are enabled on the instance in the about page
53 * Add an error message in the forgot password modal if the instance email system is not configured
54 * Add sitemap
55 * Add well known url to change password ([@rigelk](https://github.com/rigelk))
56 * Remove 8GB video upload limit on client side. There may still be such limit depending on the reverse proxy configuration ([@scanlime](https://github.com/scanlime))
57 * Add CSP ([@rigelk](https://github.com/rigelk) & [@Nutomic](https://github.com/nutomic))
58 * Update title and description HTML tags when rendering video HTML page
59 * Add webfinger support for remote follows ([@acid-chicken](https://github.com/acid-chicken))
60 * Add tooltip to explain how the trending algorithm works ([@auberanger](https://github.com/auberanger))
61 * Warn users when they want to delete a channel because they will not be able to create another channel with the same name
62 * Warn users when they leave the video upload/update (on page refresh/tab close)
63 * Set max user name, user display name, channel name and channel display name lengths to 50 characters ([@McFlat](https://github.com/mcflat))
64 * Increase video abuse length to 3000 characters
65 * Add totalLocalVideoFilesSize in the stats endpoint
66
67## Bug fixes
68
69 * Fix the addition of captions to a video
70 * Fix federation of some videos
71 * Fix NSFW blur on search
72 * Add error message when trying to upload .ass subtitles
73 * Fix default homepage in the progressive web application
74 * Don't crash on queue error
75 * Fix EXDEV errors if you have multiple mount points
76 * Fix broken audio in transcoding with some videos
77 * Fix crash on getVideoFileStream issue
78 * Fix followers search
79 * Remove trailing `/` in CLI import script ([@HesioZ](https://github.com/HesioZ/))
80 * Use origin video url in canonical tag
81 * Fix captions in HTTP fallback
82 * Automatically refresh remote actors to fix deleted remote actors that are still displayed on some instances
83 * Add missing translations in video embed page
84 * Fix some styling issues in dark mode
85 * Fix transcoding issues with some videos
86 * Fix Mac OS mkv/avi upload
87 * Fix menu overflow on mobile
88 * Fix ownership button icons ([@joshmorel](https://github.com/joshmorel))
89
90
3## v1.1.0 91## v1.1.0
4 92
5***Since v1.0.1*** 93***Since v1.0.1***
6 94
95### BREAKING CHANGES
96
97 * **Docker:** `PEERTUBE_TRUST_PROXY` env variable is now an array ([LecygneNoir](https://github.com/LecygneNoir))
98
7### Maintenance 99### Maintenance
8 100
9 * Improve REST API documentation: https://docs.joinpeertube.org/api.html ([@rigelk](https://github.com/rigelk)) 101 * Improve REST API documentation: https://docs.joinpeertube.org/api.html ([@rigelk](https://github.com/rigelk))
@@ -26,7 +118,6 @@
26 * Add postfix image 118 * Add postfix image
27 * Redirect HTTP -> HTTPS 119 * Redirect HTTP -> HTTPS
28 * Disable Træfik web UI 120 * Disable Træfik web UI
29 * Add ability to set an array in `PEERTUBE_TRUST_PROXY` ([LecygneNoir](https://github.com/LecygneNoir))
30 121
31### Features 122### Features
32 123
diff --git a/CREDITS.md b/CREDITS.md
index ad5125227..509f9800d 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -6,25 +6,27 @@
6 * [Nutomic](https://github.com/Nutomic) 6 * [Nutomic](https://github.com/Nutomic)
7 * [Jorropo](https://github.com/Jorropo) 7 * [Jorropo](https://github.com/Jorropo)
8 * [BO41](https://github.com/BO41) 8 * [BO41](https://github.com/BO41)
9 * [joshmorel](https://github.com/joshmorel)
10 * [buoyantair](https://github.com/buoyantair)
9 * [bnjbvr](https://github.com/bnjbvr) 11 * [bnjbvr](https://github.com/bnjbvr)
10 * [DavidLibeau](https://github.com/DavidLibeau) 12 * [DavidLibeau](https://github.com/DavidLibeau)
11 * [jankeromnes](https://github.com/jankeromnes) 13 * [jankeromnes](https://github.com/jankeromnes)
12 * [joshmorel](https://github.com/joshmorel)
13 * [JohnXLivingston](https://github.com/JohnXLivingston) 14 * [JohnXLivingston](https://github.com/JohnXLivingston)
14 * [kaiyou](https://github.com/kaiyou) 15 * [kaiyou](https://github.com/kaiyou)
16 * [McFlat](https://github.com/McFlat)
15 * [DimitriGilbert](https://github.com/DimitriGilbert) 17 * [DimitriGilbert](https://github.com/DimitriGilbert)
16 * [floSoX](https://github.com/floSoX) 18 * [floSoX](https://github.com/floSoX)
17 * [Green-Star](https://github.com/Green-Star) 19 * [Green-Star](https://github.com/Green-Star)
20 * [thomaskuntzz](https://github.com/thomaskuntzz)
18 * [rezonant](https://github.com/rezonant) 21 * [rezonant](https://github.com/rezonant)
19 * [ldidry](https://github.com/ldidry) 22 * [ldidry](https://github.com/ldidry)
20 * [McFlat](https://github.com/McFlat)
21 * [okhin](https://github.com/okhin) 23 * [okhin](https://github.com/okhin)
22 * [daftaupe](https://github.com/daftaupe) 24 * [daftaupe](https://github.com/daftaupe)
23 * [thomaskuntzz](https://github.com/thomaskuntzz)
24 * [LecygneNoir](https://github.com/LecygneNoir) 25 * [LecygneNoir](https://github.com/LecygneNoir)
25 * [fflorent](https://github.com/fflorent) 26 * [fflorent](https://github.com/fflorent)
26 * [dedesite](https://github.com/dedesite) 27 * [dedesite](https://github.com/dedesite)
27 * [Nautigsam](https://github.com/Nautigsam) 28 * [Nautigsam](https://github.com/Nautigsam)
29 * [scanlime](https://github.com/scanlime)
28 * [tcitworld](https://github.com/tcitworld) 30 * [tcitworld](https://github.com/tcitworld)
29 * [am97](https://github.com/am97) 31 * [am97](https://github.com/am97)
30 * [dadall](https://github.com/dadall) 32 * [dadall](https://github.com/dadall)
@@ -35,7 +37,6 @@
35 * [jocelynj](https://github.com/jocelynj) 37 * [jocelynj](https://github.com/jocelynj)
36 * [lucas-dclrcq](https://github.com/lucas-dclrcq) 38 * [lucas-dclrcq](https://github.com/lucas-dclrcq)
37 * [lucaspontoexe](https://github.com/lucaspontoexe) 39 * [lucaspontoexe](https://github.com/lucaspontoexe)
38 * [scanlime](https://github.com/scanlime)
39 * [flyingrub](https://github.com/flyingrub) 40 * [flyingrub](https://github.com/flyingrub)
40 * [SerCom-KC](https://github.com/SerCom-KC) 41 * [SerCom-KC](https://github.com/SerCom-KC)
41 * [valvin1](https://github.com/valvin1) 42 * [valvin1](https://github.com/valvin1)
@@ -43,6 +44,7 @@
43 * [sticmac](https://github.com/sticmac) 44 * [sticmac](https://github.com/sticmac)
44 * [barbeque](https://github.com/barbeque) 45 * [barbeque](https://github.com/barbeque)
45 * [luzpaz](https://github.com/luzpaz) 46 * [luzpaz](https://github.com/luzpaz)
47 * [acid-chicken](https://github.com/acid-chicken)
46 * [louistio](https://github.com/louistio) 48 * [louistio](https://github.com/louistio)
47 * [qsypoq](https://github.com/qsypoq) 49 * [qsypoq](https://github.com/qsypoq)
48 * [daker](https://github.com/daker) 50 * [daker](https://github.com/daker)
@@ -65,6 +67,7 @@
65 * [grizio](https://github.com/grizio) 67 * [grizio](https://github.com/grizio)
66 * [Glandos](https://github.com/Glandos) 68 * [Glandos](https://github.com/Glandos)
67 * [lanodan](https://github.com/lanodan) 69 * [lanodan](https://github.com/lanodan)
70 * [HesioZ](https://github.com/HesioZ)
68 * [jagannathBhat](https://github.com/jagannathBhat) 71 * [jagannathBhat](https://github.com/jagannathBhat)
69 * [jlebras](https://github.com/jlebras) 72 * [jlebras](https://github.com/jlebras)
70 * [alcalyn](https://github.com/alcalyn) 73 * [alcalyn](https://github.com/alcalyn)
@@ -73,7 +76,9 @@
73 * [zapashcanon](https://github.com/zapashcanon) 76 * [zapashcanon](https://github.com/zapashcanon)
74 * [mart-e](https://github.com/mart-e) 77 * [mart-e](https://github.com/mart-e)
75 * [0mp](https://github.com/0mp) 78 * [0mp](https://github.com/0mp)
79 * [mkoppmann](https://github.com/mkoppmann)
76 * [1000i100](https://github.com/1000i100) 80 * [1000i100](https://github.com/1000i100)
81 * [roipoussiere](https://github.com/roipoussiere)
77 * [zeograd](https://github.com/zeograd) 82 * [zeograd](https://github.com/zeograd)
78 * [PhieF](https://github.com/PhieF) 83 * [PhieF](https://github.com/PhieF)
79 * [Quenty31](https://github.com/Quenty31) 84 * [Quenty31](https://github.com/Quenty31)
@@ -125,11 +130,14 @@
125 * [h3zjp](https://trad.framasoft.org/zanata/profile/view/h3zjp) 130 * [h3zjp](https://trad.framasoft.org/zanata/profile/view/h3zjp)
126 * [jfblanc](https://trad.framasoft.org/zanata/profile/view/jfblanc) 131 * [jfblanc](https://trad.framasoft.org/zanata/profile/view/jfblanc)
127 * [jhertel](https://trad.framasoft.org/zanata/profile/view/jhertel) 132 * [jhertel](https://trad.framasoft.org/zanata/profile/view/jhertel)
133 * [jmf](https://trad.framasoft.org/zanata/profile/view/jmf)
128 * [jorropo](https://trad.framasoft.org/zanata/profile/view/jorropo) 134 * [jorropo](https://trad.framasoft.org/zanata/profile/view/jorropo)
135 * [kairozen](https://trad.framasoft.org/zanata/profile/view/kairozen)
129 * [kedemferre](https://trad.framasoft.org/zanata/profile/view/kedemferre) 136 * [kedemferre](https://trad.framasoft.org/zanata/profile/view/kedemferre)
130 * [kousha](https://trad.framasoft.org/zanata/profile/view/kousha) 137 * [kousha](https://trad.framasoft.org/zanata/profile/view/kousha)
131 * [krkk](https://trad.framasoft.org/zanata/profile/view/krkk) 138 * [krkk](https://trad.framasoft.org/zanata/profile/view/krkk)
132 * [landrok](https://trad.framasoft.org/zanata/profile/view/landrok) 139 * [landrok](https://trad.framasoft.org/zanata/profile/view/landrok)
140 * [leeroyepold48](https://trad.framasoft.org/zanata/profile/view/leeroyepold48)
133 * [m4sk1n](https://trad.framasoft.org/zanata/profile/view/m4sk1n) 141 * [m4sk1n](https://trad.framasoft.org/zanata/profile/view/m4sk1n)
134 * [matograine](https://trad.framasoft.org/zanata/profile/view/matograine) 142 * [matograine](https://trad.framasoft.org/zanata/profile/view/matograine)
135 * [medow](https://trad.framasoft.org/zanata/profile/view/medow) 143 * [medow](https://trad.framasoft.org/zanata/profile/view/medow)
@@ -167,6 +175,10 @@
167 * [xinayder](https://trad.framasoft.org/zanata/profile/view/xinayder) 175 * [xinayder](https://trad.framasoft.org/zanata/profile/view/xinayder)
168 * [xosem](https://trad.framasoft.org/zanata/profile/view/xosem) 176 * [xosem](https://trad.framasoft.org/zanata/profile/view/xosem)
169 * [zveryok](https://trad.framasoft.org/zanata/profile/view/zveryok) 177 * [zveryok](https://trad.framasoft.org/zanata/profile/view/zveryok)
178 * [aditoo](https://trad.framasoft.org/zanata/profile/view/aditoo)
179 * [autom](https://trad.framasoft.org/zanata/profile/view/autom)
180 * [curupira](https://trad.framasoft.org/zanata/profile/view/curupira)
181 * [leeroyepold48](https://trad.framasoft.org/zanata/profile/view/leeroyepold48)
170 182
171 183
172# Design 184# Design
diff --git a/FAQ.md b/FAQ.md
index 1e586161c..e335868f8 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -13,6 +13,8 @@
13- [Will an index of all the videos of servers you follow be too large for small servers?](#will-an-index-of-all-the-videos-of-servers-you-follow-be-too-large-for-small-servers) 13- [Will an index of all the videos of servers you follow be too large for small servers?](#will-an-index-of-all-the-videos-of-servers-you-follow-be-too-large-for-small-servers)
14- [Which container formats can I use for the videos I want to upload?](#which-container-formats-can-i-use-for-the-videos-i-want-to-upload) 14- [Which container formats can I use for the videos I want to upload?](#which-container-formats-can-i-use-for-the-videos-i-want-to-upload)
15- [I want to change my domain name, how can I do that?](#i-want-to-change-my-domain-name-how-can-i-do-that) 15- [I want to change my domain name, how can I do that?](#i-want-to-change-my-domain-name-how-can-i-do-that)
16- [Why do we have to put our Twitter username in PeerTube configuration?](#why-do-we-have-to-put-our-twitter-username-in-peertube-configuration)
17- [How video views are calculated?](#how-video-views-are-calculated)
16- [Should I have a big server to run PeerTube?](#should-i-have-a-big-server-to-run-peertube) 18- [Should I have a big server to run PeerTube?](#should-i-have-a-big-server-to-run-peertube)
17- [Can I seed videos with my classic BitTorrent client (Transmission, rTorrent...)?](#can-i-seed-videos-with-my-classic-bittorrent-client-transmission-rtorrent) 19- [Can I seed videos with my classic BitTorrent client (Transmission, rTorrent...)?](#can-i-seed-videos-with-my-classic-bittorrent-client-transmission-rtorrent)
18- [Why host on GitHub and Framagit?](#why-host-on-github-and-framagit) 20- [Why host on GitHub and Framagit?](#why-host-on-github-and-framagit)
@@ -89,6 +91,18 @@ WEBM, MP4 or OGV videos.
89You can't. You'll need to reinstall an instance and reupload your videos. 91You can't. You'll need to reinstall an instance and reupload your videos.
90 92
91 93
94## Why do we have to put our Twitter username in PeerTube configuration?
95
96You don't have to: we set a default value if you don't have a Twitter account.
97We need this information because Twitter requires an account for links share/videos embed on their platform.
98
99
100## How video views are calculated?
101
102Your web browser sends a view to the server after 30 seconds of playback. Then, the IP cannot send another view in the next hour.
103Views are buffered, so don't panic if the view counter stays the same after you watched a video.
104
105
92## Should I have a big server to run PeerTube? 106## Should I have a big server to run PeerTube?
93 107
94Not really. For instance, the demonstration server [https://peertube.cpy.re](https://peertube.cpy.re) has 2 vCore and 2GB of RAM and consumes on average: 108Not really. For instance, the demonstration server [https://peertube.cpy.re](https://peertube.cpy.re) has 2 vCore and 2GB of RAM and consumes on average:
diff --git a/README.md b/README.md
index a3669353b..a9b4eb54a 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,16 @@ Be part of a network of multiple small federated, interoperable video hosting pr
17</p> 17</p>
18 18
19<p align="center"> 19<p align="center">
20 <strong>Developed with &#10084; by <a href="https://framasoft.org">Framasoft</a></strong>
21</p>
22
23<p align="center">
24 <a href="https://framasoft.org">
25 <img width="150px" src="http://lutim.cpy.re/Prd3ci7G.png" alt="Framasoft logo"/>
26 </a>
27</p>
28
29<p align="center">
20 <strong>Client</strong> 30 <strong>Client</strong>
21 31
22 <br /> 32 <br />
@@ -123,7 +133,7 @@ You can also join the cheerful bunch that makes our community:
123 133
124* Chat<a name="contact"></a>: 134* Chat<a name="contact"></a>:
125 * IRC : **[#peertube on chat.freenode.net:6697](https://kiwiirc.com/client/irc.freenode.net/#peertube)** 135 * IRC : **[#peertube on chat.freenode.net:6697](https://kiwiirc.com/client/irc.freenode.net/#peertube)**
126 * Matrix (bridged on the IRC channel) : **[#peertube:matrix.org](https://matrix.to/#/#peertube:matrix.org)** 136 * Matrix (bridged on IRC and [Discord](https://discord.gg/wj8DDUT)) : **[#peertube:matrix.org](https://matrix.to/#/#peertube:matrix.org)**
127* Forum: 137* Forum:
128 * Framacolibri: [https://framacolibri.org/c/peertube](https://framacolibri.org/c/peertube) 138 * Framacolibri: [https://framacolibri.org/c/peertube](https://framacolibri.org/c/peertube)
129 139
diff --git a/client/package.json b/client/package.json
index 3761a641a..31fc77887 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
1{ 1{
2 "name": "peertube-client", 2 "name": "peertube-client",
3 "version": "1.1.0", 3 "version": "1.2.0",
4 "private": true, 4 "private": true,
5 "licence": "GPLv3", 5 "licence": "GPLv3",
6 "author": { 6 "author": {
@@ -63,26 +63,26 @@
63 "setupTestFrameworkScriptFile": "<rootDir>/src/setupJest.ts" 63 "setupTestFrameworkScriptFile": "<rootDir>/src/setupJest.ts"
64 }, 64 },
65 "devDependencies": { 65 "devDependencies": {
66 "@angular-devkit/build-angular": "~0.10.0", 66 "@angular-devkit/build-angular": "~0.11.1",
67 "@angular/animations": "~7.0.2", 67 "@angular/animations": "~7.1.1",
68 "@angular/cli": "~7.0.4", 68 "@angular/cli": "~7.1.1",
69 "@angular/common": "~7.0.2", 69 "@angular/common": "~7.1.1",
70 "@angular/compiler": "~7.0.2", 70 "@angular/compiler": "~7.1.1",
71 "@angular/compiler-cli": "~7.0.2", 71 "@angular/compiler-cli": "~7.1.1",
72 "@angular/core": "~7.0.2", 72 "@angular/core": "~7.1.1",
73 "@angular/forms": "~7.0.2", 73 "@angular/forms": "~7.1.1",
74 "@angular/http": "~7.0.2", 74 "@angular/http": "~7.1.1",
75 "@angular/language-service": "~7.0.2", 75 "@angular/language-service": "~7.1.1",
76 "@angular/platform-browser": "~7.0.2", 76 "@angular/platform-browser": "~7.1.1",
77 "@angular/platform-browser-dynamic": "~7.0.2", 77 "@angular/platform-browser-dynamic": "~7.1.1",
78 "@angular/router": "~7.0.2", 78 "@angular/router": "~7.1.1",
79 "@angular/service-worker": "~7.0.2", 79 "@angular/service-worker": "~7.1.1",
80 "@angularclass/hmr": "^2.1.3", 80 "@angularclass/hmr": "^2.1.3",
81 "@neos21/bootstrap3-glyphicons": "^1.0.1", 81 "@neos21/bootstrap3-glyphicons": "^1.0.1",
82 "@ng-bootstrap/ng-bootstrap": "^4.0.0", 82 "@ng-bootstrap/ng-bootstrap": "^4.0.0",
83 "@ngx-loading-bar/core": "^2.2.0", 83 "@ngx-loading-bar/core": "^3.0.0",
84 "@ngx-loading-bar/http-client": "^2.2.0", 84 "@ngx-loading-bar/http-client": "^3.0.0",
85 "@ngx-loading-bar/router": "^2.2.0", 85 "@ngx-loading-bar/router": "^3.0.0",
86 "@ngx-meta/core": "^6.0.0-rc.1", 86 "@ngx-meta/core": "^6.0.0-rc.1",
87 "@ngx-translate/i18n-polyfill": "^1.0.0", 87 "@ngx-translate/i18n-polyfill": "^1.0.0",
88 "@types/core-js": "^2.5.0", 88 "@types/core-js": "^2.5.0",
@@ -94,10 +94,10 @@
94 "@types/markdown-it": "^0.0.5", 94 "@types/markdown-it": "^0.0.5",
95 "@types/node": "^10.9.2", 95 "@types/node": "^10.9.2",
96 "@types/sanitize-html": "1.18.0", 96 "@types/sanitize-html": "1.18.0",
97 "@types/socket.io-client": "^1.4.32",
97 "@types/video.js": "^7.2.5", 98 "@types/video.js": "^7.2.5",
98 "@types/webtorrent": "^0.98.4", 99 "@types/webtorrent": "^0.98.4",
99 "angular2-hotkeys": "^2.1.2", 100 "angular2-hotkeys": "^2.1.2",
100 "angular2-notifications": "^1.0.2",
101 "awesome-typescript-loader": "5.2.1", 101 "awesome-typescript-loader": "5.2.1",
102 "bootstrap": "^4.1.3", 102 "bootstrap": "^4.1.3",
103 "buffer": "^5.1.0", 103 "buffer": "^5.1.0",
@@ -132,7 +132,7 @@
132 "node-sass": "^4.9.3", 132 "node-sass": "^4.9.3",
133 "npm-font-source-sans-pro": "^1.0.2", 133 "npm-font-source-sans-pro": "^1.0.2",
134 "path-browserify": "^1.0.0", 134 "path-browserify": "^1.0.0",
135 "primeng": "^6.1.2", 135 "primeng": "^7.0.0",
136 "process": "^0.11.10", 136 "process": "^0.11.10",
137 "protractor": "^5.3.2", 137 "protractor": "^5.3.2",
138 "purify-css": "^1.2.5", 138 "purify-css": "^1.2.5",
@@ -142,6 +142,7 @@
142 "sanitize-html": "^1.18.4", 142 "sanitize-html": "^1.18.4",
143 "sass-loader": "^7.1.0", 143 "sass-loader": "^7.1.0",
144 "sass-resources-loader": "^2.0.0", 144 "sass-resources-loader": "^2.0.0",
145 "socket.io-client": "^2.2.0",
145 "stream-browserify": "^2.0.1", 146 "stream-browserify": "^2.0.1",
146 "stream-http": "^3.0.0", 147 "stream-http": "^3.0.0",
147 "terser-webpack-plugin": "^1.1.0", 148 "terser-webpack-plugin": "^1.1.0",
@@ -153,7 +154,6 @@
153 "videojs-contextmenu-ui": "^5.0.0", 154 "videojs-contextmenu-ui": "^5.0.0",
154 "videojs-dock": "^2.0.2", 155 "videojs-dock": "^2.0.2",
155 "videojs-hotkeys": "^0.2.21", 156 "videojs-hotkeys": "^0.2.21",
156 "webpack": "^4.17.1",
157 "webpack-bundle-analyzer": "^3.0.2", 157 "webpack-bundle-analyzer": "^3.0.2",
158 "webpack-cli": "^3.0.8", 158 "webpack-cli": "^3.0.8",
159 "webtorrent": "https://github.com/webtorrent/webtorrent#e9b209c7970816fc29e0cc871157a4918d66001d", 159 "webtorrent": "https://github.com/webtorrent/webtorrent#e9b209c7970816fc29e0cc871157a4918d66001d",
diff --git a/client/src/app/+about/about-instance/about-instance.component.html b/client/src/app/+about/about-instance/about-instance.component.html
index 5970cac01..8c700752e 100644
--- a/client/src/app/+about/about-instance/about-instance.component.html
+++ b/client/src/app/+about/about-instance/about-instance.component.html
@@ -1,39 +1,52 @@
1<div i18n class="about-instance-title"> 1<div class="row">
2 About {{ instanceName }} instance 2 <div class="col-md-12 col-xl-6">
3</div> 3 <div class="about-instance-title">
4 <div i18n>About {{ instanceName }} instance</div>
4 5
5<div class="short-description"> 6 <div *ngIf="isContactFormEnabled" (click)="openContactModal()" i18n role="button" class="contact-admin">Contact administrator</div>
6 <div>{{ shortDescription }}</div> 7 </div>
7</div>
8 8
9<div class="description"> 9 <div class="short-description">
10 <div i18n class="section-title">Description</div> 10 <div>{{ shortDescription }}</div>
11 </div>
11 12
12 <div [innerHTML]="descriptionHTML"></div> 13 <div class="description">
13</div> 14 <div i18n class="section-title">Description</div>
14 15
15<div class="terms" id="terms-section"> 16 <div [innerHTML]="descriptionHTML"></div>
16 <div i18n class="section-title">Terms</div> 17 </div>
17 18
18 <div [innerHTML]="termsHTML"></div> 19 <div class="terms" id="terms-section">
19</div> 20 <div i18n class="section-title">Terms</div>
20 21
21<div class="signup"> 22 <div [innerHTML]="termsHTML"></div>
22 <div i18n class="section-title">Signup</div> 23 </div>
23 24
24 <div *ngIf="isSignupAllowed"> 25 <div class="signup">
25 <ng-container i18n>User registration is allowed and</ng-container> 26 <div i18n class="section-title">Signup</div>
26 27
27 <ng-container i18n *ngIf="userVideoQuota !== -1"> 28 <div *ngIf="isSignupAllowed">
28 this instance provides a baseline quota of {{ userVideoQuota | bytes: 0 }} space for the videos of its users. 29 <ng-container i18n>User registration is allowed and</ng-container>
29 </ng-container>
30 30
31 <ng-container i18n *ngIf="userVideoQuota === -1"> 31 <ng-container i18n *ngIf="userVideoQuota !== -1">
32 this instance provides unlimited space for the videos of its users. 32 this instance provides a baseline quota of {{ userVideoQuota | bytes: 0 }} space for the videos of its users.
33 </ng-container> 33 </ng-container>
34
35 <ng-container i18n *ngIf="userVideoQuota === -1">
36 this instance provides unlimited space for the videos of its users.
37 </ng-container>
38 </div>
39
40 <div i18n *ngIf="isSignupAllowed === false">
41 User registration is currently not allowed.
42 </div>
43 </div>
34 </div> 44 </div>
35 45
36 <div i18n *ngIf="isSignupAllowed === false"> 46 <div class="col-md-12 col-xl-6">
37 User registration is currently not allowed. 47 <label>Features found on this instance</label>
48 <my-instance-features-table></my-instance-features-table>
38 </div> 49 </div>
39</div> \ No newline at end of file 50</div>
51
52<my-contact-admin-modal #contactAdminModal></my-contact-admin-modal>
diff --git a/client/src/app/+about/about-instance/about-instance.component.scss b/client/src/app/+about/about-instance/about-instance.component.scss
index b451e85aa..75cf57322 100644
--- a/client/src/app/+about/about-instance/about-instance.component.scss
+++ b/client/src/app/+about/about-instance/about-instance.component.scss
@@ -2,9 +2,19 @@
2@import '_mixins'; 2@import '_mixins';
3 3
4.about-instance-title { 4.about-instance-title {
5 font-size: 20px; 5 display: flex;
6 font-weight: bold; 6 justify-content: space-between;
7 margin-bottom: 15px; 7
8 & > div {
9 font-size: 20px;
10 font-weight: bold;
11 margin-bottom: 15px;
12 }
13
14 & > .contact-admin {
15 @include peertube-button;
16 @include orange-button;
17 }
8} 18}
9 19
10.section-title { 20.section-title {
diff --git a/client/src/app/+about/about-instance/about-instance.component.ts b/client/src/app/+about/about-instance/about-instance.component.ts
index 354f52ce7..a1b30fa8c 100644
--- a/client/src/app/+about/about-instance/about-instance.component.ts
+++ b/client/src/app/+about/about-instance/about-instance.component.ts
@@ -1,23 +1,26 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit, ViewChild } from '@angular/core'
2import { ServerService } from '@app/core' 2import { Notifier, ServerService } from '@app/core'
3import { MarkdownService } from '@app/videos/shared'
4import { NotificationsService } from 'angular2-notifications'
5import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component'
5import { InstanceService } from '@app/shared/instance/instance.service'
6import { MarkdownService } from '@app/shared/renderer'
6 7
7@Component({ 8@Component({
8 selector: 'my-about-instance', 9 selector: 'my-about-instance',
9 templateUrl: './about-instance.component.html', 10 templateUrl: './about-instance.component.html',
10 styleUrls: [ './about-instance.component.scss' ] 11 styleUrls: [ './about-instance.component.scss' ]
11}) 12})
12
13export class AboutInstanceComponent implements OnInit { 13export class AboutInstanceComponent implements OnInit {
14 @ViewChild('contactAdminModal') contactAdminModal: ContactAdminModalComponent
15
14 shortDescription = '' 16 shortDescription = ''
15 descriptionHTML = '' 17 descriptionHTML = ''
16 termsHTML = '' 18 termsHTML = ''
17 19
18 constructor ( 20 constructor (
19 private notificationsService: NotificationsService, 21 private notifier: Notifier,
20 private serverService: ServerService, 22 private serverService: ServerService,
23 private instanceService: InstanceService,
21 private markdownService: MarkdownService, 24 private markdownService: MarkdownService,
22 private i18n: I18n 25 private i18n: I18n
23 ) {} 26 ) {}
@@ -34,8 +37,12 @@ export class AboutInstanceComponent implements OnInit {
34 return this.serverService.getConfig().signup.allowed 37 return this.serverService.getConfig().signup.allowed
35 } 38 }
36 39
40 get isContactFormEnabled () {
41 return this.serverService.getConfig().email.enabled && this.serverService.getConfig().contactForm.enabled
42 }
43
37 ngOnInit () { 44 ngOnInit () {
38 this.serverService.getAbout() 45 this.instanceService.getAbout()
39 .subscribe( 46 .subscribe(
40 res => { 47 res => {
41 this.shortDescription = res.instance.shortDescription 48 this.shortDescription = res.instance.shortDescription
@@ -43,8 +50,12 @@ export class AboutInstanceComponent implements OnInit {
43 this.termsHTML = this.markdownService.textMarkdownToHTML(res.instance.terms) 50 this.termsHTML = this.markdownService.textMarkdownToHTML(res.instance.terms)
44 }, 51 },
45 52
46 err => this.notificationsService.error(this.i18n('Error getting about from server'), err) 53 () => this.notifier.error(this.i18n('Cannot get about information from server'))
47 ) 54 )
48 } 55 }
49 56
57 openContactModal () {
58 return this.contactAdminModal.show()
59 }
60
50} 61}
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.html b/client/src/app/+about/about-instance/contact-admin-modal.component.html
new file mode 100644
index 000000000..b2cbd0873
--- /dev/null
+++ b/client/src/app/+about/about-instance/contact-admin-modal.component.html
@@ -0,0 +1,50 @@
1<ng-template #modal>
2 <div class="modal-header">
3 <h4 i18n class="modal-title">Contact {{ instanceName }} administrator</h4>
4 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
5 </div>
6
7 <div class="modal-body">
8
9 <form novalidate [formGroup]="form" (ngSubmit)="sendForm()">
10 <div class="form-group">
11 <label i18n for="fromName">Your name</label>
12 <input
13 type="text" id="fromName"
14 formControlName="fromName" [ngClass]="{ 'input-error': formErrors.fromName }"
15 >
16 <div *ngIf="formErrors.fromName" class="form-error">{{ formErrors.fromName }}</div>
17 </div>
18
19 <div class="form-group">
20 <label i18n for="fromEmail">Your email</label>
21 <input
22 type="text" id="fromEmail"
23 formControlName="fromEmail" [ngClass]="{ 'input-error': formErrors['fromEmail'] }"
24 >
25 <div *ngIf="formErrors.fromEmail" class="form-error">{{ formErrors.fromEmail }}</div>
26 </div>
27
28 <div class="form-group">
29 <label i18n for="body">Your message</label>
30 <textarea id="body" formControlName="body" [ngClass]="{ 'input-error': formErrors['body'] }">
31 </textarea>
32 <div *ngIf="formErrors.body" class="form-error">{{ formErrors.body }}</div>
33 </div>
34
35 <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
36
37 <div class="form-group inputs">
38 <span i18n class="action-button action-button-cancel" (click)="hide()">
39 Cancel
40 </span>
41
42 <input
43 type="submit" i18n-value value="Submit" class="action-button-submit"
44 [disabled]="!form.valid"
45 >
46 </div>
47 </form>
48
49 </div>
50</ng-template>
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.scss b/client/src/app/+about/about-instance/contact-admin-modal.component.scss
new file mode 100644
index 000000000..260d77888
--- /dev/null
+++ b/client/src/app/+about/about-instance/contact-admin-modal.component.scss
@@ -0,0 +1,11 @@
1@import 'variables';
2@import 'mixins';
3
4input[type=text] {
5 @include peertube-input-text(340px);
6 display: block;
7}
8
9textarea {
10 @include peertube-textarea(100%, 200px);
11}
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.ts b/client/src/app/+about/about-instance/contact-admin-modal.component.ts
new file mode 100644
index 000000000..7d79c2215
--- /dev/null
+++ b/client/src/app/+about/about-instance/contact-admin-modal.component.ts
@@ -0,0 +1,77 @@
1import { Component, OnInit, ViewChild } from '@angular/core'
2import { Notifier, ServerService } from '@app/core'
3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
5import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
6import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
7import { FormReactive, InstanceValidatorsService } from '@app/shared'
8import { InstanceService } from '@app/shared/instance/instance.service'
9
10@Component({
11 selector: 'my-contact-admin-modal',
12 templateUrl: './contact-admin-modal.component.html',
13 styleUrls: [ './contact-admin-modal.component.scss' ]
14})
15export class ContactAdminModalComponent extends FormReactive implements OnInit {
16 @ViewChild('modal') modal: NgbModal
17
18 error: string
19
20 private openedModal: NgbModalRef
21
22 constructor (
23 protected formValidatorService: FormValidatorService,
24 private modalService: NgbModal,
25 private instanceValidatorsService: InstanceValidatorsService,
26 private instanceService: InstanceService,
27 private serverService: ServerService,
28 private notifier: Notifier,
29 private i18n: I18n
30 ) {
31 super()
32 }
33
34 get instanceName () {
35 return this.serverService.getConfig().instance.name
36 }
37
38 ngOnInit () {
39 this.buildForm({
40 fromName: this.instanceValidatorsService.FROM_NAME,
41 fromEmail: this.instanceValidatorsService.FROM_EMAIL,
42 body: this.instanceValidatorsService.BODY
43 })
44 }
45
46 show () {
47 this.openedModal = this.modalService.open(this.modal, { keyboard: false })
48 }
49
50 hide () {
51 this.form.reset()
52 this.error = undefined
53
54 this.openedModal.close()
55 this.openedModal = null
56 }
57
58 sendForm () {
59 const fromName = this.form.value['fromName']
60 const fromEmail = this.form.value[ 'fromEmail' ]
61 const body = this.form.value[ 'body' ]
62
63 this.instanceService.contactAdministrator(fromEmail, fromName, body)
64 .subscribe(
65 () => {
66 this.notifier.success(this.i18n('Your message has been sent.'))
67 this.hide()
68 },
69
70 err => {
71 this.error = err.status === 403
72 ? this.i18n('You already sent this form recently')
73 : err.message
74 }
75 )
76 }
77}
diff --git a/client/src/app/+about/about.module.ts b/client/src/app/+about/about.module.ts
index ff6e8ef41..9c6b29740 100644
--- a/client/src/app/+about/about.module.ts
+++ b/client/src/app/+about/about.module.ts
@@ -5,6 +5,7 @@ import { AboutComponent } from './about.component'
5import { SharedModule } from '../shared' 5import { SharedModule } from '../shared'
6import { AboutInstanceComponent } from '@app/+about/about-instance/about-instance.component' 6import { AboutInstanceComponent } from '@app/+about/about-instance/about-instance.component'
7import { AboutPeertubeComponent } from '@app/+about/about-peertube/about-peertube.component' 7import { AboutPeertubeComponent } from '@app/+about/about-peertube/about-peertube.component'
8import { ContactAdminModalComponent } from '@app/+about/about-instance/contact-admin-modal.component'
8 9
9@NgModule({ 10@NgModule({
10 imports: [ 11 imports: [
@@ -15,7 +16,8 @@ import { AboutPeertubeComponent } from '@app/+about/about-peertube/about-peertub
15 declarations: [ 16 declarations: [
16 AboutComponent, 17 AboutComponent,
17 AboutInstanceComponent, 18 AboutInstanceComponent,
18 AboutPeertubeComponent 19 AboutPeertubeComponent,
20 ContactAdminModalComponent
19 ], 21 ],
20 22
21 exports: [ 23 exports: [
diff --git a/client/src/app/+accounts/account-about/account-about.component.ts b/client/src/app/+accounts/account-about/account-about.component.ts
index 6f3e6caa0..13890a0ee 100644
--- a/client/src/app/+accounts/account-about/account-about.component.ts
+++ b/client/src/app/+accounts/account-about/account-about.component.ts
@@ -1,9 +1,9 @@
1import { Component, OnInit, OnDestroy } from '@angular/core' 1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { Account } from '@app/shared/account/account.model' 2import { Account } from '@app/shared/account/account.model'
3import { AccountService } from '@app/shared/account/account.service' 3import { AccountService } from '@app/shared/account/account.service'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { Subscription } from 'rxjs' 5import { Subscription } from 'rxjs'
6import { MarkdownService } from '@app/videos/shared' 6import { MarkdownService } from '@app/shared/renderer'
7 7
8@Component({ 8@Component({
9 selector: 'my-account-about', 9 selector: 'my-account-about',
diff --git a/client/src/app/+accounts/account-videos/account-videos.component.ts b/client/src/app/+accounts/account-videos/account-videos.component.ts
index e5c1f58b0..13b634a01 100644
--- a/client/src/app/+accounts/account-videos/account-videos.component.ts
+++ b/client/src/app/+accounts/account-videos/account-videos.component.ts
@@ -2,7 +2,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { Location } from '@angular/common' 3import { Location } from '@angular/common'
4import { immutableAssign } from '@app/shared/misc/utils' 4import { immutableAssign } from '@app/shared/misc/utils'
5import { NotificationsService } from 'angular2-notifications'
6import { AuthService } from '../../core/auth' 5import { AuthService } from '../../core/auth'
7import { ConfirmService } from '../../core/confirm' 6import { ConfirmService } from '../../core/confirm'
8import { AbstractVideoList } from '../../shared/video/abstract-video-list' 7import { AbstractVideoList } from '../../shared/video/abstract-video-list'
@@ -13,6 +12,7 @@ import { tap } from 'rxjs/operators'
13import { I18n } from '@ngx-translate/i18n-polyfill' 12import { I18n } from '@ngx-translate/i18n-polyfill'
14import { Subscription } from 'rxjs' 13import { Subscription } from 'rxjs'
15import { ScreenService } from '@app/shared/misc/screen.service' 14import { ScreenService } from '@app/shared/misc/screen.service'
15import { Notifier } from '@app/core'
16 16
17@Component({ 17@Component({
18 selector: 'my-account-videos', 18 selector: 'my-account-videos',
@@ -35,7 +35,7 @@ export class AccountVideosComponent extends AbstractVideoList implements OnInit,
35 protected router: Router, 35 protected router: Router,
36 protected route: ActivatedRoute, 36 protected route: ActivatedRoute,
37 protected authService: AuthService, 37 protected authService: AuthService,
38 protected notificationsService: NotificationsService, 38 protected notifier: Notifier,
39 protected confirmService: ConfirmService, 39 protected confirmService: ConfirmService,
40 protected location: Location, 40 protected location: Location,
41 protected screenService: ScreenService, 41 protected screenService: ScreenService,
diff --git a/client/src/app/+accounts/accounts.component.ts b/client/src/app/+accounts/accounts.component.ts
index e19927d6b..e8339b78b 100644
--- a/client/src/app/+accounts/accounts.component.ts
+++ b/client/src/app/+accounts/accounts.component.ts
@@ -5,10 +5,9 @@ import { Account } from '@app/shared/account/account.model'
5import { RestExtractor, UserService } from '@app/shared' 5import { RestExtractor, UserService } from '@app/shared'
6import { catchError, distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators' 6import { catchError, distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators'
7import { Subscription } from 'rxjs' 7import { Subscription } from 'rxjs'
8import { NotificationsService } from 'angular2-notifications' 8import { AuthService, Notifier, RedirectService } from '@app/core'
9import { User, UserRight } from '../../../../shared' 9import { User, UserRight } from '../../../../shared'
10import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
11import { AuthService, RedirectService } from '@app/core'
12 11
13@Component({ 12@Component({
14 templateUrl: './accounts.component.html', 13 templateUrl: './accounts.component.html',
@@ -24,11 +23,10 @@ export class AccountsComponent implements OnInit, OnDestroy {
24 private route: ActivatedRoute, 23 private route: ActivatedRoute,
25 private userService: UserService, 24 private userService: UserService,
26 private accountService: AccountService, 25 private accountService: AccountService,
27 private notificationsService: NotificationsService, 26 private notifier: Notifier,
28 private restExtractor: RestExtractor, 27 private restExtractor: RestExtractor,
29 private redirectService: RedirectService, 28 private redirectService: RedirectService,
30 private authService: AuthService, 29 private authService: AuthService
31 private i18n: I18n
32 ) {} 30 ) {}
33 31
34 ngOnInit () { 32 ngOnInit () {
@@ -43,7 +41,7 @@ export class AccountsComponent implements OnInit, OnDestroy {
43 .subscribe( 41 .subscribe(
44 account => this.account = account, 42 account => this.account = account,
45 43
46 err => this.notificationsService.error(this.i18n('Error'), err.message) 44 err => this.notifier.error(err.message)
47 ) 45 )
48 } 46 }
49 47
@@ -69,7 +67,7 @@ export class AccountsComponent implements OnInit, OnDestroy {
69 .subscribe( 67 .subscribe(
70 user => this.user = user, 68 user => this.user = user,
71 69
72 err => this.notificationsService.error(this.i18n('Error'), err.message) 70 err => this.notifier.error(err.message)
73 ) 71 )
74 } 72 }
75 } 73 }
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
index fd4d3d9c9..52eb00d93 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
@@ -7,169 +7,169 @@
7 7
8 <div i18n class="inner-form-title">Instance</div> 8 <div i18n class="inner-form-title">Instance</div>
9 9
10 <div class="form-group"> 10 <ng-container formGroupName="instance">
11 <label i18n for="instanceName">Name</label> 11 <div class="form-group">
12 <input 12 <label i18n for="instanceName">Name</label>
13 type="text" id="instanceName" 13 <input
14 formControlName="instanceName" [ngClass]="{ 'input-error': formErrors['instanceName'] }" 14 type="text" id="instanceName"
15 > 15 formControlName="name" [ngClass]="{ 'input-error': formErrors.instance.name }"
16 <div *ngIf="formErrors.instanceName" class="form-error"> 16 >
17 {{ formErrors.instanceName }} 17 <div *ngIf="formErrors.instance.name" class="form-error">{{ formErrors.instance.name }}</div>
18 </div> 18 </div>
19 </div>
20 19
21 <div class="form-group"> 20 <div class="form-group">
22 <label i18n for="instanceShortDescription">Short description</label> 21 <label i18n for="instanceShortDescription">Short description</label>
23 <textarea 22 <textarea
24 id="instanceShortDescription" formControlName="instanceShortDescription" 23 id="instanceShortDescription" formControlName="shortDescription"
25 [ngClass]="{ 'input-error': formErrors['instanceShortDescription'] }" 24 [ngClass]="{ 'input-error': formErrors['instance.shortDescription'] }"
26 ></textarea> 25 ></textarea>
27 <div *ngIf="formErrors.instanceShortDescription" class="form-error"> 26 <div *ngIf="formErrors.instance.shortDescription" class="form-error">{{ formErrors.instance.shortDescription }}</div>
28 {{ formErrors.instanceShortDescription }}
29 </div> 27 </div>
30 </div>
31 28
32 <div class="form-group"> 29 <div class="form-group">
33 <label i18n for="instanceDescription">Description</label><my-help helpType="markdownText"></my-help> 30 <label i18n for="instanceDescription">Description</label><my-help helpType="markdownText"></my-help>
34 <my-markdown-textarea 31 <my-markdown-textarea
35 id="instanceDescription" formControlName="instanceDescription" textareaWidth="500px" [previewColumn]="true" 32 id="instanceDescription" formControlName="description" textareaWidth="500px" [previewColumn]="true"
36 [classes]="{ 'input-error': formErrors['instanceDescription'] }" 33 [classes]="{ 'input-error': formErrors['instance.description'] }"
37 ></my-markdown-textarea> 34 ></my-markdown-textarea>
38 <div *ngIf="formErrors.instanceDescription" class="form-error"> 35 <div *ngIf="formErrors.instance.description" class="form-error">{{ formErrors.instance.description }}</div>
39 {{ formErrors.instanceDescription }}
40 </div> 36 </div>
41 </div>
42 37
43 <div class="form-group"> 38 <div class="form-group">
44 <label i18n for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help> 39 <label i18n for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help>
45 <my-markdown-textarea 40 <my-markdown-textarea
46 id="instanceTerms" formControlName="instanceTerms" textareaWidth="500px" [previewColumn]="true" 41 id="instanceTerms" formControlName="terms" textareaWidth="500px" [previewColumn]="true"
47 [ngClass]="{ 'input-error': formErrors['instanceTerms'] }" 42 [ngClass]="{ 'input-error': formErrors['instance.terms'] }"
48 ></my-markdown-textarea> 43 ></my-markdown-textarea>
49 <div *ngIf="formErrors.instanceTerms" class="form-error"> 44 <div *ngIf="formErrors.instance.terms" class="form-error">{{ formErrors.instance.terms }}</div>
50 {{ formErrors.instanceTerms }}
51 </div> 45 </div>
52 </div>
53 46
54 <div class="form-group"> 47 <div class="form-group">
55 <label i18n for="instanceDefaultClientRoute">Default client route</label> 48 <label i18n for="instanceDefaultClientRoute">Default client route</label>
56 <div class="peertube-select-container"> 49 <div class="peertube-select-container">
57 <select id="instanceDefaultClientRoute" formControlName="instanceDefaultClientRoute"> 50 <select id="instanceDefaultClientRoute" formControlName="defaultClientRoute">
58 <option i18n value="/videos/overview">Videos Overview</option> 51 <option i18n value="/videos/overview">Videos Overview</option>
59 <option i18n value="/videos/trending">Videos Trending</option> 52 <option i18n value="/videos/trending">Videos Trending</option>
60 <option i18n value="/videos/recently-added">Videos Recently Added</option> 53 <option i18n value="/videos/recently-added">Videos Recently Added</option>
61 <option i18n value="/videos/local">Local videos</option> 54 <option i18n value="/videos/local">Local videos</option>
62 </select> 55 </select>
56 </div>
57 <div *ngIf="formErrors.instance.defaultClientRoute" class="form-error">{{ formErrors.instance.defaultClientRoute }}</div>
63 </div> 58 </div>
64 <div *ngIf="formErrors.instanceDefaultClientRoute" class="form-error"> 59
65 {{ formErrors.instanceDefaultClientRoute }} 60 <div class="form-group">
61 <label i18n for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label>
62 <my-help
63 helpType="custom" i18n-customHtml
64 customHtml="With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video."
65 ></my-help>
66
67 <div class="peertube-select-container">
68 <select id="instanceDefaultNSFWPolicy" formControlName="defaultNSFWPolicy">
69 <option i18n value="do_not_list">Do not list</option>
70 <option i18n value="blur">Blur thumbnails</option>
71 <option i18n value="display">Display</option>
72 </select>
73 </div>
74 <div *ngIf="formErrors.instance.defaultNSFWPolicy" class="form-error">{{ formErrors.instance.defaultNSFWPolicy }}</div>
66 </div> 75 </div>
67 </div> 76 </ng-container>
68 77
69 <div class="form-group"> 78 <div i18n class="inner-form-title">Signup</div>
70 <label i18n for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label>
71 <my-help
72 helpType="custom" i18n-customHtml
73 customHtml="With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video."
74 ></my-help>
75 79
76 <div class="peertube-select-container"> 80 <ng-container formGroupName="signup">
77 <select id="instanceDefaultNSFWPolicy" formControlName="instanceDefaultNSFWPolicy"> 81 <div class="form-group">
78 <option i18n value="do_not_list">Do not list</option> 82 <my-peertube-checkbox
79 <option i18n value="blur">Blur thumbnails</option> 83 inputName="signupEnabled" formControlName="enabled"
80 <option i18n value="display">Display</option> 84 i18n-labelText labelText="Signup enabled"
81 </select> 85 ></my-peertube-checkbox>
82 </div> 86 </div>
83 <div *ngIf="formErrors.instanceDefaultNSFWPolicy" class="form-error"> 87
84 {{ formErrors.instanceDefaultNSFWPolicy }} 88 <div class="form-group">
89 <my-peertube-checkbox *ngIf="isSignupEnabled()"
90 inputName="signupRequiresEmailVerification" formControlName="requiresEmailVerification"
91 i18n-labelText labelText="Signup requires email verification"
92 ></my-peertube-checkbox>
85 </div> 93 </div>
86 </div>
87 94
88 <div i18n class="inner-form-title">Signup</div> 95 <div *ngIf="isSignupEnabled()" class="form-group">
96 <label i18n for="signupLimit">Signup limit</label>
97 <input
98 type="text" id="signupLimit"
99 formControlName="limit" [ngClass]="{ 'input-error': formErrors['signup.limit'] }"
100 >
101 <div *ngIf="formErrors.signup.limit" class="form-error">{{ formErrors.signup.limit }}</div>
102 </div>
103 </ng-container>
89 104
90 <div class="form-group"> 105 <div i18n class="inner-form-title">Users</div>
91 <my-peertube-checkbox
92 inputName="signupEnabled" formControlName="signupEnabled"
93 i18n-labelText labelText="Signup enabled"
94 ></my-peertube-checkbox>
95 </div>
96 106
97 <div class="form-group"> 107 <ng-container formGroupName="user">
98 <my-peertube-checkbox *ngIf="isSignupEnabled()" 108 <div class="form-group">
99 inputName="signupRequiresEmailVerification" formControlName="signupRequiresEmailVerification" 109 <label i18n for="userVideoQuota">User default video quota</label>
100 i18n-labelText labelText="Signup requires email verification" 110 <div class="peertube-select-container">
101 ></my-peertube-checkbox> 111 <select id="userVideoQuota" formControlName="videoQuota">
102 </div> 112 <option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value">
113 {{ videoQuotaOption.label }}
114 </option>
115 </select>
116 </div>
117 <div *ngIf="formErrors.user.videoQuota" class="form-error">{{ formErrors.user.videoQuota }}</div>
118 </div>
103 119
104 <div *ngIf="isSignupEnabled()" class="form-group"> 120 <div class="form-group">
105 <label i18n for="signupLimit">Signup limit</label> 121 <label i18n for="userVideoQuotaDaily">User default daily upload limit</label>
106 <input 122 <div class="peertube-select-container">
107 type="text" id="signupLimit" 123 <select id="userVideoQuotaDaily" formControlName="videoQuotaDaily">
108 formControlName="signupLimit" [ngClass]="{ 'input-error': formErrors['signupLimit'] }" 124 <option *ngFor="let videoQuotaDailyOption of videoQuotaDailyOptions" [value]="videoQuotaDailyOption.value">
109 > 125 {{ videoQuotaDailyOption.label }}
110 <div *ngIf="formErrors.signupLimit" class="form-error"> 126 </option>
111 {{ formErrors.signupLimit }} 127 </select>
128 </div>
129 <div *ngIf="formErrors.user.videoQuotaDaily" class="form-error">{{ formErrors.user.videoQuotaDaily }}</div>
112 </div> 130 </div>
113 </div> 131 </ng-container>
114 132
115 <div i18n class="inner-form-title">Import</div> 133 <div i18n class="inner-form-title">Import</div>
116 134
117 <div class="form-group"> 135 <ng-container formGroupName="import">
118 <my-peertube-checkbox 136 <ng-container formGroupName="videos">
119 inputName="importVideosHttpEnabled" formControlName="importVideosHttpEnabled"
120 i18n-labelText labelText="Video import with HTTP URL (i.e. YouTube) enabled"
121 ></my-peertube-checkbox>
122 </div>
123 137
124 <div class="form-group"> 138 <div class="form-group" formGroupName="http">
125 <my-peertube-checkbox 139 <my-peertube-checkbox
126 inputName="importVideosTorrentEnabled" formControlName="importVideosTorrentEnabled" 140 inputName="importVideosHttpEnabled" formControlName="enabled"
127 i18n-labelText labelText="Video import with a torrent file or a magnet URI enabled" 141 i18n-labelText labelText="Video import with HTTP URL (i.e. YouTube) enabled"
128 ></my-peertube-checkbox> 142 ></my-peertube-checkbox>
129 </div> 143 </div>
144
145 <div class="form-group" formGroupName="torrent">
146 <my-peertube-checkbox
147 inputName="importVideosTorrentEnabled" formControlName="enabled"
148 i18n-labelText labelText="Video import with a torrent file or a magnet URI enabled"
149 ></my-peertube-checkbox>
150 </div>
151
152 </ng-container>
153 </ng-container>
130 154
131 <div i18n class="inner-form-title">Administrator</div> 155 <div i18n class="inner-form-title">Administrator</div>
132 156
133 <div class="form-group"> 157 <div class="form-group" formGroupName="admin">
134 <label i18n for="adminEmail">Admin email</label> 158 <label i18n for="adminEmail">Admin email</label>
135 <input 159 <input
136 type="text" id="adminEmail" 160 type="text" id="adminEmail"
137 formControlName="adminEmail" [ngClass]="{ 'input-error': formErrors['adminEmail'] }" 161 formControlName="email" [ngClass]="{ 'input-error': formErrors['admin.email'] }"
138 > 162 >
139 <div *ngIf="formErrors.adminEmail" class="form-error"> 163 <div *ngIf="formErrors.admin.email" class="form-error">{{ formErrors.admin.email }}</div>
140 {{ formErrors.adminEmail }}
141 </div>
142 </div> 164 </div>
143 165
144 <div i18n class="inner-form-title">Users</div> 166 <div class="form-group" formGroupName="contactForm">
145 167 <my-peertube-checkbox
146 <div class="form-group"> 168 inputName="enableContactForm" formControlName="enabled"
147 <label i18n for="userVideoQuota">User default video quota</label> 169 i18n-labelText labelText="Enable contact form"
148 <div class="peertube-select-container"> 170 ></my-peertube-checkbox>
149 <select id="userVideoQuota" formControlName="userVideoQuota">
150 <option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value">
151 {{ videoQuotaOption.label }}
152 </option>
153 </select>
154 </div>
155 <div *ngIf="formErrors.userVideoQuota" class="form-error">
156 {{ formErrors.userVideoQuota }}
157 </div>
158 </div> 171 </div>
159 172
160 <div class="form-group">
161 <label i18n for="userVideoQuotaDaily">User default daily upload limit</label>
162 <div class="peertube-select-container">
163 <select id="userVideoQuotaDaily" formControlName="userVideoQuotaDaily">
164 <option *ngFor="let videoQuotaDailyOption of videoQuotaDailyOptions" [value]="videoQuotaDailyOption.value">
165 {{ videoQuotaDailyOption.label }}
166 </option>
167 </select>
168 </div>
169 <div *ngIf="formErrors.userVideoQuotaDaily" class="form-error">
170 {{ formErrors.userVideoQuotaDaily }}
171 </div>
172 </div>
173 </ng-template> 173 </ng-template>
174 </ngb-tab> 174 </ngb-tab>
175 175
@@ -177,30 +177,35 @@
177 <ng-template ngbTabContent> 177 <ng-template ngbTabContent>
178 <div i18n class="inner-form-title">Twitter</div> 178 <div i18n class="inner-form-title">Twitter</div>
179 179
180 <div class="form-group"> 180 <ng-container formGroupName="services">
181 <label i18n for="signupLimit">Your Twitter username</label> 181 <ng-container formGroupName="twitter">
182 <my-help 182
183 helpType="custom" i18n-customHtml 183 <div class="form-group">
184 customHtml="Indicates the Twitter account for the website or platform on which the content was published." 184 <label i18n for="signupLimit">Your Twitter username</label>
185 ></my-help> 185 <my-help
186 <input 186 helpType="custom" i18n-customHtml
187 type="text" id="servicesTwitterUsername" 187 customHtml="Indicates the Twitter account for the website or platform on which the content was published."
188 formControlName="servicesTwitterUsername" [ngClass]="{ 'input-error': formErrors['servicesTwitterUsername'] }" 188 ></my-help>
189 > 189 <input
190 <div *ngIf="formErrors.servicesTwitterUsername" class="form-error"> 190 type="text" id="servicesTwitterUsername"
191 {{ formErrors.servicesTwitterUsername }} 191 formControlName="username" [ngClass]="{ 'input-error': formErrors['services.twitter.username'] }"
192 </div> 192 >
193 </div> 193 <div *ngIf="formErrors.services.twitter.username" class="form-error">{{ formErrors.services.twitter.username }}</div>
194 </div>
195
196 <div class="form-group">
197 <my-peertube-checkbox
198 inputName="servicesTwitterWhitelisted" formControlName="whitelisted"
199 i18n-labelText labelText="Instance whitelisted by Twitter"
200 i18n-helpHtml helpHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br />
201 If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br />
202 Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted."
203 ></my-peertube-checkbox>
204 </div>
205
206 </ng-container>
207 </ng-container>
194 208
195 <div class="form-group">
196 <my-peertube-checkbox
197 inputName="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted"
198 i18n-labelText labelText="Instance whitelisted by Twitter"
199 i18n-helpHtml helpHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br />
200 If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br />
201 Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted."
202 ></my-peertube-checkbox>
203 </div>
204 </ng-template> 209 </ng-template>
205 </ngb-tab> 210 </ngb-tab>
206 211
@@ -209,37 +214,48 @@
209 214
210 <div i18n class="inner-form-title">Transcoding</div> 215 <div i18n class="inner-form-title">Transcoding</div>
211 216
212 <div class="form-group"> 217 <ng-container formGroupName="transcoding">
213 <my-peertube-checkbox 218 <div class="form-group">
214 inputName="transcodingEnabled" formControlName="transcodingEnabled" 219 <my-peertube-checkbox
215 i18n-labelText labelText="Transcoding enabled" 220 inputName="transcodingEnabled" formControlName="enabled"
216 i18n-helpHtml helpHtml="If you disable transcoding, many videos from your users will not work!" 221 i18n-labelText labelText="Transcoding enabled"
217 ></my-peertube-checkbox> 222 i18n-helpHtml helpHtml="If you disable transcoding, many videos from your users will not work!"
218 </div> 223 ></my-peertube-checkbox>
224 </div>
219 225
220 <ng-template [ngIf]="isTranscodingEnabled()"> 226 <ng-container *ngIf="isTranscodingEnabled()">
221 227
222 <div class="form-group"> 228 <div class="form-group">
223 <label i18n for="transcodingThreads">Transcoding threads</label> 229 <my-peertube-checkbox
224 <div class="peertube-select-container"> 230 inputName="transcodingAllowAdditionalExtensions" formControlName="allowAdditionalExtensions"
225 <select id="transcodingThreads" formControlName="transcodingThreads"> 231 i18n-labelText labelText="Allow additional extensions"
226 <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value"> 232 i18n-helpHtml helpHtml="Allow your users to upload .mkv, .mov, .avi, .flv videos"
227 {{ transcodingThreadOption.label }} 233 ></my-peertube-checkbox>
228 </option>
229 </select>
230 </div> 234 </div>
231 <div *ngIf="formErrors.transcodingThreads" class="form-error"> 235
232 {{ formErrors.transcodingThreads }} 236 <div class="form-group">
237 <label i18n for="transcodingThreads">Transcoding threads</label>
238 <div class="peertube-select-container">
239 <select id="transcodingThreads" formControlName="threads">
240 <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value">
241 {{ transcodingThreadOption.label }}
242 </option>
243 </select>
244 </div>
245 <div *ngIf="formErrors.transcoding.threads" class="form-error">{{ formErrors.transcoding.threads }}</div>
233 </div> 246 </div>
234 </div>
235 247
236 <div class="form-group" *ngFor="let resolution of resolutions"> 248 <ng-container formGroupName="resolutions">
237 <my-peertube-checkbox 249 <div class="form-group" *ngFor="let resolution of resolutions">
238 [inputName]="getResolutionKey(resolution)" [formControlName]="getResolutionKey(resolution)" 250 <my-peertube-checkbox
239 i18n-labelText labelText="Resolution {{resolution}} enabled" 251 [inputName]="getResolutionKey(resolution)" [formControlName]="resolution"
240 ></my-peertube-checkbox> 252 i18n-labelText labelText="Resolution {{resolution}} enabled"
241 </div> 253 ></my-peertube-checkbox>
242 </ng-template> 254 </div>
255 </ng-container>
256
257 </ng-container>
258 </ng-container>
243 259
244 <div i18n class="inner-form-title"> 260 <div i18n class="inner-form-title">
245 Cache 261 Cache
@@ -250,74 +266,73 @@
250 ></my-help> 266 ></my-help>
251 </div> 267 </div>
252 268
253 <div class="form-group"> 269 <ng-container formGroupName="cache">
254 <label i18n for="cachePreviewsSize">Previews cache size</label> 270 <div class="form-group" formGroupName="previews">
255 <input 271 <label i18n for="cachePreviewsSize">Previews cache size</label>
256 type="text" id="cachePreviewsSize" 272 <input
257 formControlName="cachePreviewsSize" [ngClass]="{ 'input-error': formErrors['cachePreviewsSize'] }" 273 type="text" id="cachePreviewsSize"
258 > 274 formControlName="size" [ngClass]="{ 'input-error': formErrors['cache.previews.size'] }"
259 <div *ngIf="formErrors.cachePreviewsSize" class="form-error"> 275 >
260 {{ formErrors.cachePreviewsSize }} 276 <div *ngIf="formErrors.cache.previews.size" class="form-error">{{ formErrors.cache.previews.size }}</div>
261 </div> 277 </div>
262 </div>
263 278
264 <div class="form-group"> 279 <div class="form-group" formGroupName="captions">
265 <label i18n for="cachePreviewsSize">Video captions cache size</label> 280 <label i18n for="cacheCaptionsSize">Video captions cache size</label>
266 <input 281 <input
267 type="text" id="cacheCaptionsSize" 282 type="text" id="cacheCaptionsSize"
268 formControlName="cacheCaptionsSize" [ngClass]="{ 'input-error': formErrors['cacheCaptionsSize'] }" 283 formControlName="size" [ngClass]="{ 'input-error': formErrors['cache.captions.size'] }"
269 > 284 >
270 <div *ngIf="formErrors.cacheCaptionsSize" class="form-error"> 285 <div *ngIf="formErrors.cache.captions.size" class="form-error">{{ formErrors.cache.captions.size }}</div>
271 {{ formErrors.cacheCaptionsSize }}
272 </div> 286 </div>
273 </div> 287 </ng-container>
274 288
275 <div i18n class="inner-form-title">Customizations</div> 289 <div i18n class="inner-form-title">Customizations</div>
276 290
277 <div class="form-group"> 291 <ng-container formGroupName="instance">
278 <label i18n for="customizationJavascript">JavaScript</label> 292 <ng-container formGroupName="customizations">
279 <my-help 293 <div class="form-group">
280 helpType="custom" i18n-customHtml 294 <label i18n for="customizationJavascript">JavaScript</label>
281 customHtml="Write directly JavaScript code.<br />Example: <pre>console.log('my instance is amazing');</pre>" 295 <my-help
282 ></my-help> 296 helpType="custom" i18n-customHtml
283 <textarea 297 customHtml="Write directly JavaScript code.<br />Example: <pre>console.log('my instance is amazing');</pre>"
284 id="customizationJavascript" formControlName="customizationJavascript" 298 ></my-help>
285 [ngClass]="{ 'input-error': formErrors['customizationJavascript'] }" 299 <textarea
286 ></textarea> 300 id="customizationJavascript" formControlName="javascript"
287 <div *ngIf="formErrors.customizationJavascript" class="form-error"> 301 [ngClass]="{ 'input-error': formErrors['instance.customizations.javascript'] }"
288 {{ formErrors.customizationJavascript }} 302 ></textarea>
289 </div> 303 <div *ngIf="formErrors.instance.customizations.javascript" class="form-error">{{ formErrors.instance.customizations.javascript }}</div>
290 </div> 304 </div>
305
306 <div class="form-group">
307 <label for="customizationCSS">CSS</label>
308 <my-help
309 helpType="custom"
310 i18n-customHtml
311 customHtml="
312 Write directly CSS code. Example:<br />
313 <pre>
314 body {{ '{' }}
315 background-color: red;
316 {{ '}' }}
317 </pre>
318
319 Prepend with <em>#custom-css</em> to override styles. Example:
320 <pre>
321 #custom-css .logged-in-email {{ '{' }}
322 color: red;
323 {{ '}' }}
324 </pre>
325 "
326 ></my-help>
327 <textarea
328 id="customizationCSS" formControlName="css"
329 [ngClass]="{ 'input-error': formErrors['instance.customizations.css'] }"
330 ></textarea>
331 <div *ngIf="formErrors.instance.customizations.css" class="form-error">{{ formErrors.instance.customizations.css }}</div>
332 </div>
333 </ng-container>
334 </ng-container>
291 335
292 <div class="form-group">
293 <label for="customizationCSS">CSS</label>
294 <my-help
295 helpType="custom"
296 i18n-customHtml
297 customHtml="
298 Write directly CSS code. Example:<br />
299 <pre>
300 body {{ '{' }}
301 background-color: red;
302 {{ '}' }}
303 </pre>
304
305 Prepend with <em>#custom-css</em> to override styles. Example:
306 <pre>
307 #custom-css .logged-in-email {{ '{' }}
308 color: red;
309 {{ '}' }}
310 </pre>
311 "
312 ></my-help>
313 <textarea
314 id="customizationCSS" formControlName="customizationCSS"
315 [ngClass]="{ 'input-error': formErrors['customizationCSS'] }"
316 ></textarea>
317 <div *ngIf="formErrors.customizationCSS" class="form-error">
318 {{ formErrors.customizationCSS }}
319 </div>
320 </div>
321 </ng-template> 336 </ng-template>
322 </ngb-tab> 337 </ngb-tab>
323 </ngb-tabset> 338 </ngb-tabset>
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
index f48b6fc1a..654a076b0 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
@@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core'
2import { ConfigService } from '@app/+admin/config/shared/config.service' 2import { ConfigService } from '@app/+admin/config/shared/config.service'
3import { ServerService } from '@app/core/server/server.service' 3import { ServerService } from '@app/core/server/server.service'
4import { CustomConfigValidatorsService, FormReactive, UserValidatorsService } from '@app/shared' 4import { CustomConfigValidatorsService, FormReactive, UserValidatorsService } from '@app/shared'
5import { NotificationsService } from 'angular2-notifications' 5import { Notifier } from '@app/core'
6import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model' 6import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model'
7import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { BuildFormDefaultValues, FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 8import { BuildFormDefaultValues, FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
@@ -18,14 +18,11 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
18 resolutions: string[] = [] 18 resolutions: string[] = []
19 transcodingThreadOptions: { label: string, value: number }[] = [] 19 transcodingThreadOptions: { label: string, value: number }[] = []
20 20
21 private oldCustomJavascript: string
22 private oldCustomCSS: string
23
24 constructor ( 21 constructor (
25 protected formValidatorService: FormValidatorService, 22 protected formValidatorService: FormValidatorService,
26 private customConfigValidatorsService: CustomConfigValidatorsService, 23 private customConfigValidatorsService: CustomConfigValidatorsService,
27 private userValidatorsService: UserValidatorsService, 24 private userValidatorsService: UserValidatorsService,
28 private notificationsService: NotificationsService, 25 private notifier: Notifier,
29 private configService: ConfigService, 26 private configService: ConfigService,
30 private serverService: ServerService, 27 private serverService: ServerService,
31 private i18n: I18n 28 private i18n: I18n
@@ -58,40 +55,78 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
58 } 55 }
59 56
60 getResolutionKey (resolution: string) { 57 getResolutionKey (resolution: string) {
61 return 'transcodingResolution' + resolution 58 return 'transcoding.resolutions.' + resolution
62 } 59 }
63 60
64 ngOnInit () { 61 ngOnInit () {
65 const formGroupData: { [key: string]: any } = { 62 const formGroupData: { [key in keyof CustomConfig ]: any } = {
66 instanceName: this.customConfigValidatorsService.INSTANCE_NAME, 63 instance: {
67 instanceShortDescription: this.customConfigValidatorsService.INSTANCE_SHORT_DESCRIPTION, 64 name: this.customConfigValidatorsService.INSTANCE_NAME,
68 instanceDescription: null, 65 shortDescription: this.customConfigValidatorsService.INSTANCE_SHORT_DESCRIPTION,
69 instanceTerms: null, 66 description: null,
70 instanceDefaultClientRoute: null, 67 terms: null,
71 instanceDefaultNSFWPolicy: null, 68 defaultClientRoute: null,
72 servicesTwitterUsername: this.customConfigValidatorsService.SERVICES_TWITTER_USERNAME, 69 defaultNSFWPolicy: null,
73 servicesTwitterWhitelisted: null, 70 customizations: {
74 cachePreviewsSize: this.customConfigValidatorsService.CACHE_PREVIEWS_SIZE, 71 javascript: null,
75 cacheCaptionsSize: this.customConfigValidatorsService.CACHE_CAPTIONS_SIZE, 72 css: null
76 signupEnabled: null, 73 }
77 signupLimit: this.customConfigValidatorsService.SIGNUP_LIMIT, 74 },
78 signupRequiresEmailVerification: null, 75 services: {
79 importVideosHttpEnabled: null, 76 twitter: {
80 importVideosTorrentEnabled: null, 77 username: this.customConfigValidatorsService.SERVICES_TWITTER_USERNAME,
81 adminEmail: this.customConfigValidatorsService.ADMIN_EMAIL, 78 whitelisted: null
82 userVideoQuota: this.userValidatorsService.USER_VIDEO_QUOTA, 79 }
83 userVideoQuotaDaily: this.userValidatorsService.USER_VIDEO_QUOTA_DAILY, 80 },
84 transcodingThreads: this.customConfigValidatorsService.TRANSCODING_THREADS, 81 cache: {
85 transcodingEnabled: null, 82 previews: {
86 customizationJavascript: null, 83 size: this.customConfigValidatorsService.CACHE_PREVIEWS_SIZE
87 customizationCSS: null 84 },
85 captions: {
86 size: this.customConfigValidatorsService.CACHE_CAPTIONS_SIZE
87 }
88 },
89 signup: {
90 enabled: null,
91 limit: this.customConfigValidatorsService.SIGNUP_LIMIT,
92 requiresEmailVerification: null
93 },
94 import: {
95 videos: {
96 http: {
97 enabled: null
98 },
99 torrent: {
100 enabled: null
101 }
102 }
103 },
104 admin: {
105 email: this.customConfigValidatorsService.ADMIN_EMAIL
106 },
107 contactForm: {
108 enabled: null
109 },
110 user: {
111 videoQuota: this.userValidatorsService.USER_VIDEO_QUOTA,
112 videoQuotaDaily: this.userValidatorsService.USER_VIDEO_QUOTA_DAILY
113 },
114 transcoding: {
115 enabled: null,
116 threads: this.customConfigValidatorsService.TRANSCODING_THREADS,
117 allowAdditionalExtensions: null,
118 resolutions: {}
119 }
88 } 120 }
89 121
90 const defaultValues: BuildFormDefaultValues = {} 122 const defaultValues = {
123 transcoding: {
124 resolutions: {}
125 }
126 }
91 for (const resolution of this.resolutions) { 127 for (const resolution of this.resolutions) {
92 const key = this.getResolutionKey(resolution) 128 defaultValues.transcoding.resolutions[resolution] = 'false'
93 defaultValues[key] = 'false' 129 formGroupData.transcoding.resolutions[resolution] = null
94 formGroupData[key] = null
95 } 130 }
96 131
97 this.buildForm(formGroupData) 132 this.buildForm(formGroupData)
@@ -101,90 +136,25 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
101 res => { 136 res => {
102 this.customConfig = res 137 this.customConfig = res
103 138
104 this.oldCustomCSS = this.customConfig.instance.customizations.css
105 this.oldCustomJavascript = this.customConfig.instance.customizations.javascript
106
107 this.updateForm() 139 this.updateForm()
108 // Force form validation 140 // Force form validation
109 this.forceCheck() 141 this.forceCheck()
110 }, 142 },
111 143
112 err => this.notificationsService.error(this.i18n('Error'), err.message) 144 err => this.notifier.error(err.message)
113 ) 145 )
114 } 146 }
115 147
116 isTranscodingEnabled () { 148 isTranscodingEnabled () {
117 return this.form.value['transcodingEnabled'] === true 149 return this.form.value['transcoding']['enabled'] === true
118 } 150 }
119 151
120 isSignupEnabled () { 152 isSignupEnabled () {
121 return this.form.value['signupEnabled'] === true 153 return this.form.value['signup']['enabled'] === true
122 } 154 }
123 155
124 async formValidated () { 156 async formValidated () {
125 const data: CustomConfig = { 157 this.configService.updateCustomConfig(this.form.value)
126 instance: {
127 name: this.form.value['instanceName'],
128 shortDescription: this.form.value['instanceShortDescription'],
129 description: this.form.value['instanceDescription'],
130 terms: this.form.value['instanceTerms'],
131 defaultClientRoute: this.form.value['instanceDefaultClientRoute'],
132 defaultNSFWPolicy: this.form.value['instanceDefaultNSFWPolicy'],
133 customizations: {
134 javascript: this.form.value['customizationJavascript'],
135 css: this.form.value['customizationCSS']
136 }
137 },
138 services: {
139 twitter: {
140 username: this.form.value['servicesTwitterUsername'],
141 whitelisted: this.form.value['servicesTwitterWhitelisted']
142 }
143 },
144 cache: {
145 previews: {
146 size: this.form.value['cachePreviewsSize']
147 },
148 captions: {
149 size: this.form.value['cacheCaptionsSize']
150 }
151 },
152 signup: {
153 enabled: this.form.value['signupEnabled'],
154 limit: this.form.value['signupLimit'],
155 requiresEmailVerification: this.form.value['signupRequiresEmailVerification']
156 },
157 admin: {
158 email: this.form.value['adminEmail']
159 },
160 user: {
161 videoQuota: this.form.value['userVideoQuota'],
162 videoQuotaDaily: this.form.value['userVideoQuotaDaily']
163 },
164 transcoding: {
165 enabled: this.form.value['transcodingEnabled'],
166 threads: this.form.value['transcodingThreads'],
167 resolutions: {
168 '240p': this.form.value[this.getResolutionKey('240p')],
169 '360p': this.form.value[this.getResolutionKey('360p')],
170 '480p': this.form.value[this.getResolutionKey('480p')],
171 '720p': this.form.value[this.getResolutionKey('720p')],
172 '1080p': this.form.value[this.getResolutionKey('1080p')]
173 }
174 },
175 import: {
176 videos: {
177 http: {
178 enabled: this.form.value['importVideosHttpEnabled']
179 },
180 torrent: {
181 enabled: this.form.value['importVideosTorrentEnabled']
182 }
183 }
184 }
185 }
186
187 this.configService.updateCustomConfig(data)
188 .subscribe( 158 .subscribe(
189 res => { 159 res => {
190 this.customConfig = res 160 this.customConfig = res
@@ -194,45 +164,15 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
194 164
195 this.updateForm() 165 this.updateForm()
196 166
197 this.notificationsService.success(this.i18n('Success'), this.i18n('Configuration updated.')) 167 this.notifier.success(this.i18n('Configuration updated.'))
198 }, 168 },
199 169
200 err => this.notificationsService.error(this.i18n('Error'), err.message) 170 err => this.notifier.error(err.message)
201 ) 171 )
202 } 172 }
203 173
204 private updateForm () { 174 private updateForm () {
205 const data: { [key: string]: any } = { 175 this.form.patchValue(this.customConfig)
206 instanceName: this.customConfig.instance.name,
207 instanceShortDescription: this.customConfig.instance.shortDescription,
208 instanceDescription: this.customConfig.instance.description,
209 instanceTerms: this.customConfig.instance.terms,
210 instanceDefaultClientRoute: this.customConfig.instance.defaultClientRoute,
211 instanceDefaultNSFWPolicy: this.customConfig.instance.defaultNSFWPolicy,
212 servicesTwitterUsername: this.customConfig.services.twitter.username,
213 servicesTwitterWhitelisted: this.customConfig.services.twitter.whitelisted,
214 cachePreviewsSize: this.customConfig.cache.previews.size,
215 cacheCaptionsSize: this.customConfig.cache.captions.size,
216 signupEnabled: this.customConfig.signup.enabled,
217 signupLimit: this.customConfig.signup.limit,
218 signupRequiresEmailVerification: this.customConfig.signup.requiresEmailVerification,
219 adminEmail: this.customConfig.admin.email,
220 userVideoQuota: this.customConfig.user.videoQuota,
221 userVideoQuotaDaily: this.customConfig.user.videoQuotaDaily,
222 transcodingThreads: this.customConfig.transcoding.threads,
223 transcodingEnabled: this.customConfig.transcoding.enabled,
224 customizationJavascript: this.customConfig.instance.customizations.javascript,
225 customizationCSS: this.customConfig.instance.customizations.css,
226 importVideosHttpEnabled: this.customConfig.import.videos.http.enabled,
227 importVideosTorrentEnabled: this.customConfig.import.videos.torrent.enabled
228 }
229
230 for (const resolution of this.resolutions) {
231 const key = this.getResolutionKey(resolution)
232 data[key] = this.customConfig.transcoding.resolutions[resolution]
233 }
234
235 this.form.patchValue(data)
236 } 176 }
237 177
238} 178}
diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.ts b/client/src/app/+admin/follows/followers-list/followers-list.component.ts
index 4a25b7ff3..9a8848bfb 100644
--- a/client/src/app/+admin/follows/followers-list/followers-list.component.ts
+++ b/client/src/app/+admin/follows/followers-list/followers-list.component.ts
@@ -1,6 +1,6 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2 2
3import { NotificationsService } from 'angular2-notifications' 3import { Notifier } from '@app/core'
4import { SortMeta } from 'primeng/primeng' 4import { SortMeta } from 'primeng/primeng'
5import { ActorFollow } from '../../../../../../shared/models/actors/follow.model' 5import { ActorFollow } from '../../../../../../shared/models/actors/follow.model'
6import { RestPagination, RestTable } from '../../../shared' 6import { RestPagination, RestTable } from '../../../shared'
@@ -20,7 +20,7 @@ export class FollowersListComponent extends RestTable implements OnInit {
20 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 20 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
21 21
22 constructor ( 22 constructor (
23 private notificationsService: NotificationsService, 23 private notifier: Notifier,
24 private followService: FollowService, 24 private followService: FollowService,
25 private i18n: I18n 25 private i18n: I18n
26 ) { 26 ) {
@@ -32,14 +32,14 @@ export class FollowersListComponent extends RestTable implements OnInit {
32 } 32 }
33 33
34 protected loadData () { 34 protected loadData () {
35 this.followService.getFollowers(this.pagination, this.sort) 35 this.followService.getFollowers(this.pagination, this.sort, this.search)
36 .subscribe( 36 .subscribe(
37 resultList => { 37 resultList => {
38 this.followers = resultList.data 38 this.followers = resultList.data
39 this.totalRecords = resultList.total 39 this.totalRecords = resultList.total
40 }, 40 },
41 41
42 err => this.notificationsService.error(this.i18n('Error'), err.message) 42 err => this.notifier.error(err.message)
43 ) 43 )
44 } 44 }
45} 45}
diff --git a/client/src/app/+admin/follows/following-add/following-add.component.ts b/client/src/app/+admin/follows/following-add/following-add.component.ts
index bd9cc022b..2bb249746 100644
--- a/client/src/app/+admin/follows/following-add/following-add.component.ts
+++ b/client/src/app/+admin/follows/following-add/following-add.component.ts
@@ -1,6 +1,6 @@
1import { Component } from '@angular/core' 1import { Component } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { Notifier } from '@app/core'
4import { ConfirmService } from '../../../core' 4import { ConfirmService } from '../../../core'
5import { validateHost } from '../../../shared' 5import { validateHost } from '../../../shared'
6import { FollowService } from '../shared' 6import { FollowService } from '../shared'
@@ -18,7 +18,7 @@ export class FollowingAddComponent {
18 18
19 constructor ( 19 constructor (
20 private router: Router, 20 private router: Router,
21 private notificationsService: NotificationsService, 21 private notifier: Notifier,
22 private confirmService: ConfirmService, 22 private confirmService: ConfirmService,
23 private followService: FollowService, 23 private followService: FollowService,
24 private i18n: I18n 24 private i18n: I18n
@@ -64,12 +64,12 @@ export class FollowingAddComponent {
64 64
65 this.followService.follow(hosts).subscribe( 65 this.followService.follow(hosts).subscribe(
66 () => { 66 () => {
67 this.notificationsService.success(this.i18n('Success'), this.i18n('Follow request(s) sent!')) 67 this.notifier.success(this.i18n('Follow request(s) sent!'))
68 68
69 setTimeout(() => this.router.navigate([ '/admin/follows/following-list' ]), 500) 69 setTimeout(() => this.router.navigate([ '/admin/follows/following-list' ]), 500)
70 }, 70 },
71 71
72 err => this.notificationsService.error(this.i18n('Error'), err.message) 72 err => this.notifier.error(err.message)
73 ) 73 )
74 } 74 }
75 75
diff --git a/client/src/app/+admin/follows/following-list/following-list.component.ts b/client/src/app/+admin/follows/following-list/following-list.component.ts
index 9b7029f75..4517a721e 100644
--- a/client/src/app/+admin/follows/following-list/following-list.component.ts
+++ b/client/src/app/+admin/follows/following-list/following-list.component.ts
@@ -1,5 +1,5 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { SortMeta } from 'primeng/primeng' 3import { SortMeta } from 'primeng/primeng'
4import { ActorFollow } from '../../../../../../shared/models/actors/follow.model' 4import { ActorFollow } from '../../../../../../shared/models/actors/follow.model'
5import { ConfirmService } from '../../../core/confirm/confirm.service' 5import { ConfirmService } from '../../../core/confirm/confirm.service'
@@ -20,7 +20,7 @@ export class FollowingListComponent extends RestTable implements OnInit {
20 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 20 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
21 21
22 constructor ( 22 constructor (
23 private notificationsService: NotificationsService, 23 private notifier: Notifier,
24 private confirmService: ConfirmService, 24 private confirmService: ConfirmService,
25 private followService: FollowService, 25 private followService: FollowService,
26 private i18n: I18n 26 private i18n: I18n
@@ -41,14 +41,11 @@ export class FollowingListComponent extends RestTable implements OnInit {
41 41
42 this.followService.unfollow(follow).subscribe( 42 this.followService.unfollow(follow).subscribe(
43 () => { 43 () => {
44 this.notificationsService.success( 44 this.notifier.success(this.i18n('You are not following {{host}} anymore.', { host: follow.following.host }))
45 this.i18n('Success'),
46 this.i18n('You are not following {{host}} anymore.', { host: follow.following.host })
47 )
48 this.loadData() 45 this.loadData()
49 }, 46 },
50 47
51 err => this.notificationsService.error(this.i18n('Error'), err.message) 48 err => this.notifier.error(err.message)
52 ) 49 )
53 } 50 }
54 51
@@ -60,7 +57,7 @@ export class FollowingListComponent extends RestTable implements OnInit {
60 this.totalRecords = resultList.total 57 this.totalRecords = resultList.total
61 }, 58 },
62 59
63 err => this.notificationsService.error(this.i18n('Error'), err.message) 60 err => this.notifier.error(err.message)
64 ) 61 )
65 } 62 }
66} 63}
diff --git a/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts b/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts
index 6d77a0eb4..fa1da26bf 100644
--- a/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts
+++ b/client/src/app/+admin/follows/shared/redundancy-checkbox.component.ts
@@ -1,5 +1,5 @@
1import { Component, Input } from '@angular/core' 1import { Component, Input } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { RedundancyService } from '@app/+admin/follows/shared/redundancy.service' 4import { RedundancyService } from '@app/+admin/follows/shared/redundancy.service'
5 5
@@ -13,24 +13,21 @@ export class RedundancyCheckboxComponent {
13 @Input() host: string 13 @Input() host: string
14 14
15 constructor ( 15 constructor (
16 private notificationsService: NotificationsService, 16 private notifier: Notifier,
17 private redundancyService: RedundancyService, 17 private redundancyService: RedundancyService,
18 private i18n: I18n 18 private i18n: I18n
19 ) { } 19 ) { }
20 20
21 updateRedundancyState () { 21 updateRedundancyState () {
22 this.redundancyService.updateRedundancy(this.host, this.redundancyAllowed) 22 this.redundancyService.updateRedundancy(this.host, this.redundancyAllowed)
23 .subscribe( 23 .subscribe(
24 () => { 24 () => {
25 const stateLabel = this.redundancyAllowed ? this.i18n('enabled') : this.i18n('disabled') 25 const stateLabel = this.redundancyAllowed ? this.i18n('enabled') : this.i18n('disabled')
26 26
27 this.notificationsService.success( 27 this.notifier.success(this.i18n('Redundancy for {{host}} is {{stateLabel}}', { host: this.host, stateLabel }))
28 this.i18n('Success'), 28 },
29 this.i18n('Redundancy for {{host}} is {{stateLabel}}', { host: this.host, stateLabel })
30 )
31 },
32 29
33 err => this.notificationsService.error(this.i18n('Error'), err.message) 30 err => this.notifier.error(err.message)
34 ) 31 )
35 } 32 }
36} 33}
diff --git a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts
index 44778ab56..b265e1dd6 100644
--- a/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts
+++ b/client/src/app/+admin/jobs/jobs-list/jobs-list.component.ts
@@ -1,6 +1,6 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' 2import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
3import { NotificationsService } from 'angular2-notifications' 3import { Notifier } from '@app/core'
4import { SortMeta } from 'primeng/primeng' 4import { SortMeta } from 'primeng/primeng'
5import { Job } from '../../../../../../shared/index' 5import { Job } from '../../../../../../shared/index'
6import { JobState } from '../../../../../../shared/models' 6import { JobState } from '../../../../../../shared/models'
@@ -25,7 +25,7 @@ export class JobsListComponent extends RestTable implements OnInit {
25 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 25 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
26 26
27 constructor ( 27 constructor (
28 private notificationsService: NotificationsService, 28 private notifier: Notifier,
29 private jobsService: JobService, 29 private jobsService: JobService,
30 private i18n: I18n 30 private i18n: I18n
31 ) { 31 ) {
@@ -53,7 +53,7 @@ export class JobsListComponent extends RestTable implements OnInit {
53 this.totalRecords = resultList.total 53 this.totalRecords = resultList.total
54 }, 54 },
55 55
56 err => this.notificationsService.error(this.i18n('Error'), err.message) 56 err => this.notifier.error(err.message)
57 ) 57 )
58 } 58 }
59 59
diff --git a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts
index 3f243aee4..032bf745a 100644
--- a/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts
+++ b/client/src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts
@@ -1,9 +1,9 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { RestPagination, RestTable } from '@app/shared' 4import { RestPagination, RestTable } from '@app/shared'
5import { SortMeta } from 'primeng/components/common/sortmeta' 5import { SortMeta } from 'primeng/components/common/sortmeta'
6import { BlocklistService, AccountBlock } from '@app/shared/blocklist' 6import { AccountBlock, BlocklistService } from '@app/shared/blocklist'
7 7
8@Component({ 8@Component({
9 selector: 'my-instance-account-blocklist', 9 selector: 'my-instance-account-blocklist',
@@ -18,7 +18,7 @@ export class InstanceAccountBlocklistComponent extends RestTable implements OnIn
18 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 18 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
19 19
20 constructor ( 20 constructor (
21 private notificationsService: NotificationsService, 21 private notifier: Notifier,
22 private blocklistService: BlocklistService, 22 private blocklistService: BlocklistService,
23 private i18n: I18n 23 private i18n: I18n
24 ) { 24 ) {
@@ -35,8 +35,7 @@ export class InstanceAccountBlocklistComponent extends RestTable implements OnIn
35 this.blocklistService.unblockAccountByInstance(blockedAccount) 35 this.blocklistService.unblockAccountByInstance(blockedAccount)
36 .subscribe( 36 .subscribe(
37 () => { 37 () => {
38 this.notificationsService.success( 38 this.notifier.success(
39 this.i18n('Success'),
40 this.i18n('Account {{nameWithHost}} unmuted by your instance.', { nameWithHost: blockedAccount.nameWithHost }) 39 this.i18n('Account {{nameWithHost}} unmuted by your instance.', { nameWithHost: blockedAccount.nameWithHost })
41 ) 40 )
42 41
@@ -53,7 +52,7 @@ export class InstanceAccountBlocklistComponent extends RestTable implements OnIn
53 this.totalRecords = resultList.total 52 this.totalRecords = resultList.total
54 }, 53 },
55 54
56 err => this.notificationsService.error(this.i18n('Error'), err.message) 55 err => this.notifier.error(err.message)
57 ) 56 )
58 } 57 }
59} 58}
diff --git a/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts b/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts
index 130009dc7..db3dfcd1c 100644
--- a/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts
+++ b/client/src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts
@@ -1,5 +1,5 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { RestPagination, RestTable } from '@app/shared' 4import { RestPagination, RestTable } from '@app/shared'
5import { SortMeta } from 'primeng/components/common/sortmeta' 5import { SortMeta } from 'primeng/components/common/sortmeta'
@@ -19,7 +19,7 @@ export class InstanceServerBlocklistComponent extends RestTable implements OnIni
19 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 19 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
20 20
21 constructor ( 21 constructor (
22 private notificationsService: NotificationsService, 22 private notifier: Notifier,
23 private blocklistService: BlocklistService, 23 private blocklistService: BlocklistService,
24 private i18n: I18n 24 private i18n: I18n
25 ) { 25 ) {
@@ -36,10 +36,7 @@ export class InstanceServerBlocklistComponent extends RestTable implements OnIni
36 this.blocklistService.unblockServerByInstance(host) 36 this.blocklistService.unblockServerByInstance(host)
37 .subscribe( 37 .subscribe(
38 () => { 38 () => {
39 this.notificationsService.success( 39 this.notifier.success(this.i18n('Instance {{host}} unmuted by your instance.', { host }))
40 this.i18n('Success'),
41 this.i18n('Instance {{host}} unmuted by your instance.', { host })
42 )
43 40
44 this.loadData() 41 this.loadData()
45 } 42 }
@@ -54,7 +51,7 @@ export class InstanceServerBlocklistComponent extends RestTable implements OnIni
54 this.totalRecords = resultList.total 51 this.totalRecords = resultList.total
55 }, 52 },
56 53
57 err => this.notificationsService.error(this.i18n('Error'), err.message) 54 err => this.notifier.error(err.message)
58 ) 55 )
59 } 56 }
60} 57}
diff --git a/client/src/app/+admin/moderation/moderation.component.scss b/client/src/app/+admin/moderation/moderation.component.scss
index 02ccfc8ca..13b019c5b 100644
--- a/client/src/app/+admin/moderation/moderation.component.scss
+++ b/client/src/app/+admin/moderation/moderation.component.scss
@@ -10,6 +10,7 @@
10 font-weight: $font-semibold; 10 font-weight: $font-semibold;
11 min-width: 200px; 11 min-width: 200px;
12 display: inline-block; 12 display: inline-block;
13 vertical-align: top;
13} 14}
14 15
15.moderation-expanded-text { 16.moderation-expanded-text {
diff --git a/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.html b/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.html
index 3a8424f68..303a788d2 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.html
+++ b/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.html
@@ -1,7 +1,8 @@
1<ng-template #modal> 1<ng-template #modal>
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Moderation comment</h4> 3 <h4 i18n class="modal-title">Moderation comment</h4>
4 <span class="close" aria-hidden="true" (click)="hideModerationCommentModal()"></span> 4
5 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
5 </div> 6 </div>
6 7
7 <div class="modal-body"> 8 <div class="modal-body">
@@ -14,12 +15,12 @@
14 </div> 15 </div>
15 </div> 16 </div>
16 17
17 <div i18n> 18 <div class="form-group" i18n>
18 This comment can only be seen by you or the other moderators. 19 This comment can only be seen by you or the other moderators.
19 </div> 20 </div>
20 21
21 <div class="form-group inputs"> 22 <div class="form-group inputs">
22 <span i18n class="action-button action-button-cancel" (click)="hideModerationCommentModal()">Cancel</span> 23 <span i18n class="action-button action-button-cancel" (click)="hide()">Cancel</span>
23 24
24 <input 25 <input
25 type="submit" i18n-value value="Update this comment" class="action-button-submit" 26 type="submit" i18n-value value="Update this comment" class="action-button-submit"
@@ -29,4 +30,4 @@
29 </form> 30 </form>
30 </div> 31 </div>
31 32
32</ng-template> \ No newline at end of file 33</ng-template>
diff --git a/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts b/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts
index 34ab384d1..f915978ee 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts
+++ b/client/src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts
@@ -1,5 +1,5 @@
1import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' 1import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { FormReactive, VideoAbuseService, VideoAbuseValidatorsService } from '../../../shared' 3import { FormReactive, VideoAbuseService, VideoAbuseValidatorsService } from '../../../shared'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 5import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
@@ -22,7 +22,7 @@ export class ModerationCommentModalComponent extends FormReactive implements OnI
22 constructor ( 22 constructor (
23 protected formValidatorService: FormValidatorService, 23 protected formValidatorService: FormValidatorService,
24 private modalService: NgbModal, 24 private modalService: NgbModal,
25 private notificationsService: NotificationsService, 25 private notifier: Notifier,
26 private videoAbuseService: VideoAbuseService, 26 private videoAbuseService: VideoAbuseService,
27 private videoAbuseValidatorsService: VideoAbuseValidatorsService, 27 private videoAbuseValidatorsService: VideoAbuseValidatorsService,
28 private i18n: I18n 28 private i18n: I18n
@@ -45,29 +45,26 @@ export class ModerationCommentModalComponent extends FormReactive implements OnI
45 }) 45 })
46 } 46 }
47 47
48 hideModerationCommentModal () { 48 hide () {
49 this.abuseToComment = undefined 49 this.abuseToComment = undefined
50 this.openedModal.close() 50 this.openedModal.close()
51 this.form.reset() 51 this.form.reset()
52 } 52 }
53 53
54 async banUser () { 54 async banUser () {
55 const moderationComment: string = this.form.value['moderationComment'] 55 const moderationComment: string = this.form.value[ 'moderationComment' ]
56 56
57 this.videoAbuseService.updateVideoAbuse(this.abuseToComment, { moderationComment }) 57 this.videoAbuseService.updateVideoAbuse(this.abuseToComment, { moderationComment })
58 .subscribe( 58 .subscribe(
59 () => { 59 () => {
60 this.notificationsService.success( 60 this.notifier.success(this.i18n('Comment updated.'))
61 this.i18n('Success'),
62 this.i18n('Comment updated.')
63 )
64 61
65 this.commentUpdated.emit(moderationComment) 62 this.commentUpdated.emit(moderationComment)
66 this.hideModerationCommentModal() 63 this.hide()
67 }, 64 },
68 65
69 err => this.notificationsService.error(this.i18n('Error'), err.message) 66 err => this.notifier.error(err.message)
70 ) 67 )
71 } 68 }
72 69
73} 70}
diff --git a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html
index 0374b70ef..05b549de6 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html
+++ b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html
@@ -41,7 +41,7 @@
41 </td> 41 </td>
42 42
43 <td class="action-cell"> 43 <td class="action-cell">
44 <my-action-dropdown i18n-label label="Actions" [actions]="videoAbuseActions" [entry]="videoAbuse"></my-action-dropdown> 44 <my-action-dropdown placement="bottom-right" i18n-label label="Actions" [actions]="videoAbuseActions" [entry]="videoAbuse"></my-action-dropdown>
45 </td> 45 </td>
46 </tr> 46 </tr>
47 </ng-template> 47 </ng-template>
@@ -51,15 +51,15 @@
51 <td class="moderation-expanded" colspan="6"> 51 <td class="moderation-expanded" colspan="6">
52 <div> 52 <div>
53 <span i18n class="moderation-expanded-label">Reason:</span> 53 <span i18n class="moderation-expanded-label">Reason:</span>
54 <span class="moderation-expanded-text">{{ videoAbuse.reason }}</span> 54 <span class="moderation-expanded-text" [innerHTML]="toHtml(videoAbuse.reason)"></span>
55 </div> 55 </div>
56 <div *ngIf="videoAbuse.moderationComment"> 56 <div *ngIf="videoAbuse.moderationComment">
57 <span i18n class="moderation-expanded-label">Moderation comment:</span> 57 <span i18n class="moderation-expanded-label">Moderation comment:</span>
58 <span class="moderation-expanded-text">{{ videoAbuse.moderationComment }}</span> 58 <span class="moderation-expanded-text" [innerHTML]="toHtml(videoAbuse.moderationComment)"></span>
59 </div> 59 </div>
60 </td> 60 </td>
61 </tr> 61 </tr>
62 </ng-template> 62 </ng-template>
63</p-table> 63</p-table>
64 64
65<my-moderation-comment-modal #moderationCommentModal (commentUpdated)="onModerationCommentUpdated()"></my-moderation-comment-modal> \ No newline at end of file 65<my-moderation-comment-modal #moderationCommentModal (commentUpdated)="onModerationCommentUpdated()"></my-moderation-comment-modal>
diff --git a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts
index 7a219c846..00c871659 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts
+++ b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts
@@ -1,6 +1,6 @@
1import { Component, OnInit, ViewChild } from '@angular/core' 1import { Component, OnInit, ViewChild } from '@angular/core'
2import { Account } from '../../../shared/account/account.model' 2import { Account } from '../../../shared/account/account.model'
3import { NotificationsService } from 'angular2-notifications' 3import { Notifier } from '@app/core'
4import { SortMeta } from 'primeng/components/common/sortmeta' 4import { SortMeta } from 'primeng/components/common/sortmeta'
5import { VideoAbuse, VideoAbuseState } from '../../../../../../shared' 5import { VideoAbuse, VideoAbuseState } from '../../../../../../shared'
6import { RestPagination, RestTable, VideoAbuseService } from '../../../shared' 6import { RestPagination, RestTable, VideoAbuseService } from '../../../shared'
@@ -9,6 +9,7 @@ import { DropdownAction } from '../../../shared/buttons/action-dropdown.componen
9import { ConfirmService } from '../../../core/index' 9import { ConfirmService } from '../../../core/index'
10import { ModerationCommentModalComponent } from './moderation-comment-modal.component' 10import { ModerationCommentModalComponent } from './moderation-comment-modal.component'
11import { Video } from '../../../shared/video/video.model' 11import { Video } from '../../../shared/video/video.model'
12import { MarkdownService } from '@app/shared/renderer'
12 13
13@Component({ 14@Component({
14 selector: 'my-video-abuse-list', 15 selector: 'my-video-abuse-list',
@@ -27,10 +28,11 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
27 videoAbuseActions: DropdownAction<VideoAbuse>[] = [] 28 videoAbuseActions: DropdownAction<VideoAbuse>[] = []
28 29
29 constructor ( 30 constructor (
30 private notificationsService: NotificationsService, 31 private notifier: Notifier,
31 private videoAbuseService: VideoAbuseService, 32 private videoAbuseService: VideoAbuseService,
32 private confirmService: ConfirmService, 33 private confirmService: ConfirmService,
33 private i18n: I18n 34 private i18n: I18n,
35 private markdownRenderer: MarkdownService
34 ) { 36 ) {
35 super() 37 super()
36 38
@@ -90,14 +92,11 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
90 92
91 this.videoAbuseService.removeVideoAbuse(videoAbuse).subscribe( 93 this.videoAbuseService.removeVideoAbuse(videoAbuse).subscribe(
92 () => { 94 () => {
93 this.notificationsService.success( 95 this.notifier.success(this.i18n('Abuse deleted.'))
94 this.i18n('Success'),
95 this.i18n('Abuse deleted.')
96 )
97 this.loadData() 96 this.loadData()
98 }, 97 },
99 98
100 err => this.notificationsService.error(this.i18n('Error'), err.message) 99 err => this.notifier.error(err.message)
101 ) 100 )
102 } 101 }
103 102
@@ -106,11 +105,15 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
106 .subscribe( 105 .subscribe(
107 () => this.loadData(), 106 () => this.loadData(),
108 107
109 err => this.notificationsService.error(this.i18n('Error'), err.message) 108 err => this.notifier.error(err.message)
110 ) 109 )
111 110
112 } 111 }
113 112
113 toHtml (text: string) {
114 return this.markdownRenderer.textMarkdownToHTML(text)
115 }
116
114 protected loadData () { 117 protected loadData () {
115 return this.videoAbuseService.getVideoAbuses(this.pagination, this.sort) 118 return this.videoAbuseService.getVideoAbuses(this.pagination, this.sort)
116 .subscribe( 119 .subscribe(
@@ -119,7 +122,7 @@ export class VideoAbuseListComponent extends RestTable implements OnInit {
119 this.totalRecords = resultList.total 122 this.totalRecords = resultList.total
120 }, 123 },
121 124
122 err => this.notificationsService.error(this.i18n('Error'), err.message) 125 err => this.notifier.error(err.message)
123 ) 126 )
124 } 127 }
125} 128}
diff --git a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html
index ff4543b97..247f441c1 100644
--- a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html
+++ b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html
@@ -7,6 +7,7 @@
7 <th style="width: 40px"></th> 7 <th style="width: 40px"></th>
8 <th i18n pSortableColumn="name">Video name <p-sortIcon field="name"></p-sortIcon></th> 8 <th i18n pSortableColumn="name">Video name <p-sortIcon field="name"></p-sortIcon></th>
9 <th i18n>Sensitive</th> 9 <th i18n>Sensitive</th>
10 <th i18n>Unfederated</th>
10 <th i18n pSortableColumn="createdAt">Date <p-sortIcon field="createdAt"></p-sortIcon></th> 11 <th i18n pSortableColumn="createdAt">Date <p-sortIcon field="createdAt"></p-sortIcon></th>
11 <th style="width: 120px;"></th> 12 <th style="width: 120px;"></th>
12 </tr> 13 </tr>
@@ -26,20 +27,21 @@
26 </a> 27 </a>
27 </td> 28 </td>
28 29
29 <td>{{ videoBlacklist.video.nsfw }}</td> 30 <td>{{ booleanToText(videoBlacklist.video.nsfw) }}</td>
31 <td>{{ booleanToText(videoBlacklist.unfederated) }}</td>
30 <td>{{ videoBlacklist.createdAt }}</td> 32 <td>{{ videoBlacklist.createdAt }}</td>
31 33
32 <td class="action-cell"> 34 <td class="action-cell">
33 <my-action-dropdown i18n-label label="Actions" [actions]="videoBlacklistActions" [entry]="videoBlacklist"></my-action-dropdown> 35 <my-action-dropdown i18n-label placement="bottom-right" label="Actions" [actions]="videoBlacklistActions" [entry]="videoBlacklist"></my-action-dropdown>
34 </td> 36 </td>
35 </tr> 37 </tr>
36 </ng-template> 38 </ng-template>
37 39
38 <ng-template pTemplate="rowexpansion" let-videoBlacklist> 40 <ng-template pTemplate="rowexpansion" let-videoBlacklist>
39 <tr> 41 <tr>
40 <td class="moderation-expanded" colspan="5"> 42 <td class="moderation-expanded" colspan="6">
41 <span i18n class="moderation-expanded-label">Blacklist reason:</span> 43 <span i18n class="moderation-expanded-label">Blacklist reason:</span>
42 <span class="moderation-expanded-text">{{ videoBlacklist.reason }}</span> 44 <span class="moderation-expanded-text" [innerHTML]="toHtml(videoBlacklist.reason)"></span>
43 </td> 45 </td>
44 </tr> 46 </tr>
45 </ng-template> 47 </ng-template>
diff --git a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts
index e491edaca..b27bbbfef 100644
--- a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts
+++ b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts
@@ -1,12 +1,13 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { SortMeta } from 'primeng/components/common/sortmeta' 2import { SortMeta } from 'primeng/components/common/sortmeta'
3import { NotificationsService } from 'angular2-notifications' 3import { Notifier } from '@app/core'
4import { ConfirmService } from '../../../core' 4import { ConfirmService } from '../../../core'
5import { RestPagination, RestTable, VideoBlacklistService } from '../../../shared' 5import { RestPagination, RestTable, VideoBlacklistService } from '../../../shared'
6import { VideoBlacklist } from '../../../../../../shared' 6import { VideoBlacklist } from '../../../../../../shared'
7import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { DropdownAction } from '../../../shared/buttons/action-dropdown.component' 8import { DropdownAction } from '../../../shared/buttons/action-dropdown.component'
9import { Video } from '../../../shared/video/video.model' 9import { Video } from '../../../shared/video/video.model'
10import { MarkdownService } from '@app/shared/renderer'
10 11
11@Component({ 12@Component({
12 selector: 'my-video-blacklist-list', 13 selector: 'my-video-blacklist-list',
@@ -23,9 +24,10 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
23 videoBlacklistActions: DropdownAction<VideoBlacklist>[] = [] 24 videoBlacklistActions: DropdownAction<VideoBlacklist>[] = []
24 25
25 constructor ( 26 constructor (
26 private notificationsService: NotificationsService, 27 private notifier: Notifier,
27 private confirmService: ConfirmService, 28 private confirmService: ConfirmService,
28 private videoBlacklistService: VideoBlacklistService, 29 private videoBlacklistService: VideoBlacklistService,
30 private markdownRenderer: MarkdownService,
29 private i18n: I18n 31 private i18n: I18n
30 ) { 32 ) {
31 super() 33 super()
@@ -46,6 +48,16 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
46 return Video.buildClientUrl(videoBlacklist.video.uuid) 48 return Video.buildClientUrl(videoBlacklist.video.uuid)
47 } 49 }
48 50
51 booleanToText (value: boolean) {
52 if (value === true) return this.i18n('yes')
53
54 return this.i18n('no')
55 }
56
57 toHtml (text: string) {
58 return this.markdownRenderer.textMarkdownToHTML(text)
59 }
60
49 async removeVideoFromBlacklist (entry: VideoBlacklist) { 61 async removeVideoFromBlacklist (entry: VideoBlacklist) {
50 const confirmMessage = this.i18n( 62 const confirmMessage = this.i18n(
51 'Do you really want to remove this video from the blacklist? It will be available again in the videos list.' 63 'Do you really want to remove this video from the blacklist? It will be available again in the videos list.'
@@ -56,14 +68,11 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
56 68
57 this.videoBlacklistService.removeVideoFromBlacklist(entry.video.id).subscribe( 69 this.videoBlacklistService.removeVideoFromBlacklist(entry.video.id).subscribe(
58 () => { 70 () => {
59 this.notificationsService.success( 71 this.notifier.success(this.i18n('Video {{name}} removed from the blacklist.', { name: entry.video.name }))
60 this.i18n('Success'),
61 this.i18n('Video {{name}} removed from the blacklist.', { name: entry.video.name })
62 )
63 this.loadData() 72 this.loadData()
64 }, 73 },
65 74
66 err => this.notificationsService.error(this.i18n('Error'), err.message) 75 err => this.notifier.error(err.message)
67 ) 76 )
68 } 77 }
69 78
@@ -75,7 +84,7 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
75 this.totalRecords = resultList.total 84 this.totalRecords = resultList.total
76 }, 85 },
77 86
78 err => this.notificationsService.error(this.i18n('Error'), err.message) 87 err => this.notifier.error(err.message)
79 ) 88 )
80 } 89 }
81} 90}
diff --git a/client/src/app/+admin/users/user-edit/user-create.component.ts b/client/src/app/+admin/users/user-edit/user-create.component.ts
index dd8e4efd5..137ecfcbd 100644
--- a/client/src/app/+admin/users/user-edit/user-create.component.ts
+++ b/client/src/app/+admin/users/user-edit/user-create.component.ts
@@ -1,7 +1,6 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { Notifier, ServerService } from '@app/core'
4import { ServerService } from '../../../core'
5import { UserCreate, UserRole } from '../../../../../../shared' 4import { UserCreate, UserRole } from '../../../../../../shared'
6import { UserEdit } from './user-edit' 5import { UserEdit } from './user-edit'
7import { I18n } from '@ngx-translate/i18n-polyfill' 6import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -24,7 +23,7 @@ export class UserCreateComponent extends UserEdit implements OnInit {
24 protected configService: ConfigService, 23 protected configService: ConfigService,
25 private userValidatorsService: UserValidatorsService, 24 private userValidatorsService: UserValidatorsService,
26 private router: Router, 25 private router: Router,
27 private notificationsService: NotificationsService, 26 private notifier: Notifier,
28 private userService: UserService, 27 private userService: UserService,
29 private i18n: I18n 28 private i18n: I18n
30 ) { 29 ) {
@@ -60,10 +59,7 @@ export class UserCreateComponent extends UserEdit implements OnInit {
60 59
61 this.userService.addUser(userCreate).subscribe( 60 this.userService.addUser(userCreate).subscribe(
62 () => { 61 () => {
63 this.notificationsService.success( 62 this.notifier.success(this.i18n('User {{username}} created.', { username: userCreate.username }))
64 this.i18n('Success'),
65 this.i18n('User {{username}} created.', { username: userCreate.username })
66 )
67 this.router.navigate([ '/admin/users/list' ]) 63 this.router.navigate([ '/admin/users/list' ])
68 }, 64 },
69 65
diff --git a/client/src/app/+admin/users/user-edit/user-update.component.ts b/client/src/app/+admin/users/user-edit/user-update.component.ts
index cd3885a99..61e641823 100644
--- a/client/src/app/+admin/users/user-edit/user-update.component.ts
+++ b/client/src/app/+admin/users/user-edit/user-update.component.ts
@@ -1,7 +1,7 @@
1import { Component, OnDestroy, OnInit } from '@angular/core' 1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { Subscription } from 'rxjs' 3import { Subscription } from 'rxjs'
4import { NotificationsService } from 'angular2-notifications' 4import { Notifier } from '@app/core'
5import { ServerService } from '../../../core' 5import { ServerService } from '../../../core'
6import { UserEdit } from './user-edit' 6import { UserEdit } from './user-edit'
7import { User, UserUpdate } from '../../../../../../shared' 7import { User, UserUpdate } from '../../../../../../shared'
@@ -30,7 +30,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
30 private userValidatorsService: UserValidatorsService, 30 private userValidatorsService: UserValidatorsService,
31 private route: ActivatedRoute, 31 private route: ActivatedRoute,
32 private router: Router, 32 private router: Router,
33 private notificationsService: NotificationsService, 33 private notifier: Notifier,
34 private userService: UserService, 34 private userService: UserService,
35 private i18n: I18n 35 private i18n: I18n
36 ) { 36 ) {
@@ -73,10 +73,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
73 73
74 this.userService.updateUser(this.userId, userUpdate).subscribe( 74 this.userService.updateUser(this.userId, userUpdate).subscribe(
75 () => { 75 () => {
76 this.notificationsService.success( 76 this.notifier.success(this.i18n('User {{username}} updated.', { username: this.username }))
77 this.i18n('Success'),
78 this.i18n('User {{username}} updated.', { username: this.username })
79 )
80 this.router.navigate([ '/admin/users/list' ]) 77 this.router.navigate([ '/admin/users/list' ])
81 }, 78 },
82 79
diff --git a/client/src/app/+admin/users/user-list/user-list.component.html b/client/src/app/+admin/users/user-list/user-list.component.html
index 556ab3c5d..69a4616a3 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.html
+++ b/client/src/app/+admin/users/user-list/user-list.component.html
@@ -2,7 +2,7 @@
2 <div i18n class="form-sub-title">Users list</div> 2 <div i18n class="form-sub-title">Users list</div>
3 3
4 <a class="add-button" routerLink="/admin/users/create"> 4 <a class="add-button" routerLink="/admin/users/create">
5 <span class="icon icon-add"></span> 5 <my-global-icon iconName="add"></my-global-icon>
6 <ng-container i18n>Create user</ng-container> 6 <ng-container i18n>Create user</ng-container>
7 </a> 7 </a>
8</div> 8</div>
@@ -65,7 +65,9 @@
65 <span i18n *ngIf="user.blocked" class="banned-info">(banned)</span> 65 <span i18n *ngIf="user.blocked" class="banned-info">(banned)</span>
66 </a> 66 </a>
67 </td> 67 </td>
68
68 <td *ngIf="!requiresEmailVerification || user.blocked; else emailWithVerificationStatus">{{ user.email }}</td> 69 <td *ngIf="!requiresEmailVerification || user.blocked; else emailWithVerificationStatus">{{ user.email }}</td>
70
69 <ng-template #emailWithVerificationStatus> 71 <ng-template #emailWithVerificationStatus>
70 <td *ngIf="user.emailVerified === false; else emailVerifiedNotFalse" i18n-title title="User's email must be verified to login"> 72 <td *ngIf="user.emailVerified === false; else emailVerifiedNotFalse" i18n-title title="User's email must be verified to login">
71 <em>? {{ user.email }}</em> 73 <em>? {{ user.email }}</em>
@@ -76,6 +78,7 @@
76 </td> 78 </td>
77 </ng-template> 79 </ng-template>
78 </ng-template> 80 </ng-template>
81
79 <td>{{ user.videoQuotaUsed }} / {{ user.videoQuota }}</td> 82 <td>{{ user.videoQuotaUsed }} / {{ user.videoQuota }}</td>
80 <td>{{ user.roleLabel }}</td> 83 <td>{{ user.roleLabel }}</td>
81 <td>{{ user.createdAt }}</td> 84 <td>{{ user.createdAt }}</td>
diff --git a/client/src/app/+admin/users/user-list/user-list.component.scss b/client/src/app/+admin/users/user-list/user-list.component.scss
index f235769f0..5274be01c 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.scss
+++ b/client/src/app/+admin/users/user-list/user-list.component.scss
@@ -2,7 +2,7 @@
2@import '_mixins'; 2@import '_mixins';
3 3
4.add-button { 4.add-button {
5 @include create-button('../../../../assets/images/global/add.svg'); 5 @include create-button;
6} 6}
7 7
8tr.banned { 8tr.banned {
@@ -23,4 +23,4 @@ tr.banned {
23 input { 23 input {
24 @include peertube-input-text(250px); 24 @include peertube-input-text(250px);
25 } 25 }
26} \ No newline at end of file 26}
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts
index fb085c133..66ab796f9 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.ts
+++ b/client/src/app/+admin/users/user-list/user-list.component.ts
@@ -1,5 +1,5 @@
1import { Component, OnInit, ViewChild } from '@angular/core' 1import { Component, OnInit, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { SortMeta } from 'primeng/components/common/sortmeta' 3import { SortMeta } from 'primeng/components/common/sortmeta'
4import { ConfirmService, ServerService } from '../../../core' 4import { ConfirmService, ServerService } from '../../../core'
5import { RestPagination, RestTable, UserService } from '../../../shared' 5import { RestPagination, RestTable, UserService } from '../../../shared'
@@ -26,7 +26,7 @@ export class UserListComponent extends RestTable implements OnInit {
26 bulkUserActions: DropdownAction<User[]>[] = [] 26 bulkUserActions: DropdownAction<User[]>[] = []
27 27
28 constructor ( 28 constructor (
29 private notificationsService: NotificationsService, 29 private notifier: Notifier,
30 private confirmService: ConfirmService, 30 private confirmService: ConfirmService,
31 private serverService: ServerService, 31 private serverService: ServerService,
32 private userService: UserService, 32 private userService: UserService,
@@ -68,7 +68,7 @@ export class UserListComponent extends RestTable implements OnInit {
68 openBanUserModal (users: User[]) { 68 openBanUserModal (users: User[]) {
69 for (const user of users) { 69 for (const user of users) {
70 if (user.username === 'root') { 70 if (user.username === 'root') {
71 this.notificationsService.error(this.i18n('Error'), this.i18n('You cannot ban root.')) 71 this.notifier.error(this.i18n('You cannot ban root.'))
72 return 72 return
73 } 73 }
74 } 74 }
@@ -91,18 +91,18 @@ export class UserListComponent extends RestTable implements OnInit {
91 () => { 91 () => {
92 const message = this.i18n('{{num}} users unbanned.', { num: users.length }) 92 const message = this.i18n('{{num}} users unbanned.', { num: users.length })
93 93
94 this.notificationsService.success(this.i18n('Success'), message) 94 this.notifier.success(message)
95 this.loadData() 95 this.loadData()
96 }, 96 },
97 97
98 err => this.notificationsService.error(this.i18n('Error'), err.message) 98 err => this.notifier.error(err.message)
99 ) 99 )
100 } 100 }
101 101
102 async removeUsers (users: User[]) { 102 async removeUsers (users: User[]) {
103 for (const user of users) { 103 for (const user of users) {
104 if (user.username === 'root') { 104 if (user.username === 'root') {
105 this.notificationsService.error(this.i18n('Error'), this.i18n('You cannot delete root.')) 105 this.notifier.error(this.i18n('You cannot delete root.'))
106 return 106 return
107 } 107 }
108 } 108 }
@@ -113,28 +113,22 @@ export class UserListComponent extends RestTable implements OnInit {
113 113
114 this.userService.removeUser(users).subscribe( 114 this.userService.removeUser(users).subscribe(
115 () => { 115 () => {
116 this.notificationsService.success( 116 this.notifier.success(this.i18n('{{num}} users deleted.', { num: users.length }))
117 this.i18n('Success'),
118 this.i18n('{{num}} users deleted.', { num: users.length })
119 )
120 this.loadData() 117 this.loadData()
121 }, 118 },
122 119
123 err => this.notificationsService.error(this.i18n('Error'), err.message) 120 err => this.notifier.error(err.message)
124 ) 121 )
125 } 122 }
126 123
127 async setEmailsAsVerified (users: User[]) { 124 async setEmailsAsVerified (users: User[]) {
128 this.userService.updateUsers(users, { emailVerified: true }).subscribe( 125 this.userService.updateUsers(users, { emailVerified: true }).subscribe(
129 () => { 126 () => {
130 this.notificationsService.success( 127 this.notifier.success(this.i18n('{{num}} users email set as verified.', { num: users.length }))
131 this.i18n('Success'),
132 this.i18n('{{num}} users email set as verified.', { num: users.length })
133 )
134 this.loadData() 128 this.loadData()
135 }, 129 },
136 130
137 err => this.notificationsService.error(this.i18n('Error'), err.message) 131 err => this.notifier.error(err.message)
138 ) 132 )
139 } 133 }
140 134
@@ -146,13 +140,13 @@ export class UserListComponent extends RestTable implements OnInit {
146 this.selectedUsers = [] 140 this.selectedUsers = []
147 141
148 this.userService.getUsers(this.pagination, this.sort, this.search) 142 this.userService.getUsers(this.pagination, this.sort, this.search)
149 .subscribe( 143 .subscribe(
150 resultList => { 144 resultList => {
151 this.users = resultList.data 145 this.users = resultList.data
152 this.totalRecords = resultList.total 146 this.totalRecords = resultList.total
153 }, 147 },
154 148
155 err => this.notificationsService.error(this.i18n('Error'), err.message) 149 err => this.notifier.error(err.message)
156 ) 150 )
157 } 151 }
158} 152}
diff --git a/client/src/app/+my-account/my-account-blocklist/my-account-blocklist.component.ts b/client/src/app/+my-account/my-account-blocklist/my-account-blocklist.component.ts
index fbad28410..e3025dec4 100644
--- a/client/src/app/+my-account/my-account-blocklist/my-account-blocklist.component.ts
+++ b/client/src/app/+my-account/my-account-blocklist/my-account-blocklist.component.ts
@@ -1,9 +1,9 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { RestPagination, RestTable } from '@app/shared' 4import { RestPagination, RestTable } from '@app/shared'
5import { SortMeta } from 'primeng/components/common/sortmeta' 5import { SortMeta } from 'primeng/components/common/sortmeta'
6import { BlocklistService, AccountBlock } from '@app/shared/blocklist' 6import { AccountBlock, BlocklistService } from '@app/shared/blocklist'
7 7
8@Component({ 8@Component({
9 selector: 'my-account-blocklist', 9 selector: 'my-account-blocklist',
@@ -18,7 +18,7 @@ export class MyAccountBlocklistComponent extends RestTable implements OnInit {
18 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 18 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
19 19
20 constructor ( 20 constructor (
21 private notificationsService: NotificationsService, 21 private notifier: Notifier,
22 private blocklistService: BlocklistService, 22 private blocklistService: BlocklistService,
23 private i18n: I18n 23 private i18n: I18n
24 ) { 24 ) {
@@ -35,10 +35,7 @@ export class MyAccountBlocklistComponent extends RestTable implements OnInit {
35 this.blocklistService.unblockAccountByUser(blockedAccount) 35 this.blocklistService.unblockAccountByUser(blockedAccount)
36 .subscribe( 36 .subscribe(
37 () => { 37 () => {
38 this.notificationsService.success( 38 this.notifier.success(this.i18n('Account {{nameWithHost}} unmuted.', { nameWithHost: blockedAccount.nameWithHost }))
39 this.i18n('Success'),
40 this.i18n('Account {{nameWithHost}} unmuted.', { nameWithHost: blockedAccount.nameWithHost })
41 )
42 39
43 this.loadData() 40 this.loadData()
44 } 41 }
@@ -53,7 +50,7 @@ export class MyAccountBlocklistComponent extends RestTable implements OnInit {
53 this.totalRecords = resultList.total 50 this.totalRecords = resultList.total
54 }, 51 },
55 52
56 err => this.notificationsService.error(this.i18n('Error'), err.message) 53 err => this.notifier.error(err.message)
57 ) 54 )
58 } 55 }
59} 56}
diff --git a/client/src/app/+my-account/my-account-blocklist/my-account-server-blocklist.component.ts b/client/src/app/+my-account/my-account-blocklist/my-account-server-blocklist.component.ts
index b411d6926..4c5cc28b8 100644
--- a/client/src/app/+my-account/my-account-blocklist/my-account-server-blocklist.component.ts
+++ b/client/src/app/+my-account/my-account-blocklist/my-account-server-blocklist.component.ts
@@ -1,5 +1,5 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { RestPagination, RestTable } from '@app/shared' 4import { RestPagination, RestTable } from '@app/shared'
5import { SortMeta } from 'primeng/components/common/sortmeta' 5import { SortMeta } from 'primeng/components/common/sortmeta'
@@ -19,7 +19,7 @@ export class MyAccountServerBlocklistComponent extends RestTable implements OnIn
19 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 19 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
20 20
21 constructor ( 21 constructor (
22 private notificationsService: NotificationsService, 22 private notifier: Notifier,
23 private blocklistService: BlocklistService, 23 private blocklistService: BlocklistService,
24 private i18n: I18n 24 private i18n: I18n
25 ) { 25 ) {
@@ -36,10 +36,7 @@ export class MyAccountServerBlocklistComponent extends RestTable implements OnIn
36 this.blocklistService.unblockServerByUser(host) 36 this.blocklistService.unblockServerByUser(host)
37 .subscribe( 37 .subscribe(
38 () => { 38 () => {
39 this.notificationsService.success( 39 this.notifier.success(this.i18n('Instance {{host}} unmuted.', { host }))
40 this.i18n('Success'),
41 this.i18n('Instance {{host}} unmuted.', { host })
42 )
43 40
44 this.loadData() 41 this.loadData()
45 } 42 }
@@ -54,7 +51,7 @@ export class MyAccountServerBlocklistComponent extends RestTable implements OnIn
54 this.totalRecords = resultList.total 51 this.totalRecords = resultList.total
55 }, 52 },
56 53
57 err => this.notificationsService.error(this.i18n('Error'), err.message) 54 err => this.notifier.error(err.message)
58 ) 55 )
59 } 56 }
60} 57}
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.html b/client/src/app/+my-account/my-account-history/my-account-history.component.html
new file mode 100644
index 000000000..d42af37d4
--- /dev/null
+++ b/client/src/app/+my-account/my-account-history/my-account-history.component.html
@@ -0,0 +1,27 @@
1<div class="top-buttons">
2 <div class="history-switch">
3 <p-inputSwitch [(ngModel)]="videosHistoryEnabled" (ngModelChange)="onVideosHistoryChange()"></p-inputSwitch>
4 <label i18n>History enabled</label>
5 </div>
6
7 <div class="delete-history">
8 <button (click)="deleteHistory()" i18n>Delete history</button>
9 </div>
10</div>
11
12
13<div class="no-history" i18n *ngIf="pagination.totalItems === 0">You don't have videos history yet.</div>
14
15<div myInfiniteScroller (nearOfBottom)="onNearOfBottom()" class="videos" #videosElement>
16 <div *ngFor="let videos of videoPages;" class="videos-page">
17 <div class="video" *ngFor="let video of videos">
18 <my-video-thumbnail [video]="video"></my-video-thumbnail>
19
20 <div class="video-info">
21 <a tabindex="-1" class="video-info-name" [routerLink]="['/videos/watch', video.uuid]" [attr.title]="video.name">{{ video.name }}</a>
22 <span i18n class="video-info-date-views">{{ video.views | myNumberFormatter }} views</span>
23 <a tabindex="-1" class="video-info-account" [routerLink]="[ '/accounts', video.byAccount ]">{{ video.byAccount }}</a>
24 </div>
25 </div>
26 </div>
27</div>
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.scss b/client/src/app/+my-account/my-account-history/my-account-history.component.scss
new file mode 100644
index 000000000..e7c6863f1
--- /dev/null
+++ b/client/src/app/+my-account/my-account-history/my-account-history.component.scss
@@ -0,0 +1,99 @@
1@import '_variables';
2@import '_mixins';
3
4.no-history {
5 display: flex;
6 justify-content: center;
7 margin-top: 50px;
8 font-weight: $font-semibold;
9 font-size: 16px;
10}
11
12.top-buttons {
13 margin-bottom: 20px;
14 display: flex;
15
16 .history-switch {
17 display: flex;
18 flex-grow: 1;
19
20 label {
21 margin: 0 0 0 5px;
22 }
23 }
24
25 .delete-history {
26 font-size: 15px;
27
28 button {
29 @include peertube-button;
30 @include grey-button;
31 }
32 }
33}
34
35.video {
36 @include row-blocks;
37
38 my-video-thumbnail {
39 margin-right: 10px;
40 }
41
42 .video-info {
43 flex-grow: 1;
44
45 .video-info-name {
46 @include disable-default-a-behaviour;
47
48 color: var(--mainForegroundColor);
49 display: block;
50 width: fit-content;
51 font-size: 18px;
52 font-weight: $font-semibold;
53 }
54
55 .video-info-date-views {
56 font-size: 14px;
57 }
58
59 .video-info-account {
60 @include disable-default-a-behaviour;
61
62 display: block;
63 width: fit-content;
64 overflow: hidden;
65 text-overflow: ellipsis;
66 white-space: nowrap;
67 font-size: 14px;
68 color: $grey-foreground-color;
69
70 &:hover {
71 color: $grey-foreground-hover-color;
72 }
73 }
74 }
75}
76
77@media screen and (max-width: $small-view) {
78 .video {
79 flex-direction: column;
80 height: auto;
81 text-align: center;
82
83 .video-info-name {
84 margin: auto;
85 }
86
87 input[type=checkbox] {
88 display: none;
89 }
90
91 my-video-thumbnail {
92 margin-right: 0;
93 }
94
95 .video-buttons {
96 margin-top: 10px;
97 }
98 }
99}
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.ts b/client/src/app/+my-account/my-account-history/my-account-history.component.ts
new file mode 100644
index 000000000..394091bad
--- /dev/null
+++ b/client/src/app/+my-account/my-account-history/my-account-history.component.ts
@@ -0,0 +1,107 @@
1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'
3import { Location } from '@angular/common'
4import { immutableAssign } from '@app/shared/misc/utils'
5import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
6import { AuthService } from '../../core/auth'
7import { ConfirmService } from '../../core/confirm'
8import { AbstractVideoList } from '../../shared/video/abstract-video-list'
9import { VideoService } from '../../shared/video/video.service'
10import { I18n } from '@ngx-translate/i18n-polyfill'
11import { ScreenService } from '@app/shared/misc/screen.service'
12import { UserHistoryService } from '@app/shared/users/user-history.service'
13import { UserService } from '@app/shared'
14import { Notifier } from '@app/core'
15
16@Component({
17 selector: 'my-account-history',
18 templateUrl: './my-account-history.component.html',
19 styleUrls: [ './my-account-history.component.scss' ]
20})
21export class MyAccountHistoryComponent extends AbstractVideoList implements OnInit, OnDestroy {
22 titlePage: string
23 currentRoute = '/my-account/history/videos'
24 pagination: ComponentPagination = {
25 currentPage: 1,
26 itemsPerPage: 5,
27 totalItems: null
28 }
29 videosHistoryEnabled: boolean
30
31 protected baseVideoWidth = -1
32 protected baseVideoHeight = 155
33
34 constructor (
35 protected router: Router,
36 protected route: ActivatedRoute,
37 protected authService: AuthService,
38 protected userService: UserService,
39 protected notifier: Notifier,
40 protected location: Location,
41 protected screenService: ScreenService,
42 protected i18n: I18n,
43 private confirmService: ConfirmService,
44 private videoService: VideoService,
45 private userHistoryService: UserHistoryService
46 ) {
47 super()
48
49 this.titlePage = this.i18n('My videos history')
50 }
51
52 ngOnInit () {
53 super.ngOnInit()
54
55 this.videosHistoryEnabled = this.authService.getUser().videosHistoryEnabled
56 }
57
58 ngOnDestroy () {
59 super.ngOnDestroy()
60 }
61
62 getVideosObservable (page: number) {
63 const newPagination = immutableAssign(this.pagination, { currentPage: page })
64
65 return this.userHistoryService.getUserVideosHistory(newPagination)
66 }
67
68 generateSyndicationList () {
69 throw new Error('Method not implemented.')
70 }
71
72 onVideosHistoryChange () {
73 this.userService.updateMyProfile({ videosHistoryEnabled: this.videosHistoryEnabled })
74 .subscribe(
75 () => {
76 const message = this.videosHistoryEnabled === true ?
77 this.i18n('Videos history is enabled') :
78 this.i18n('Videos history is disabled')
79
80 this.notifier.success(message)
81
82 this.authService.refreshUserInformation()
83 },
84
85 err => this.notifier.error(err.message)
86 )
87 }
88
89 async deleteHistory () {
90 const title = this.i18n('Delete videos history')
91 const message = this.i18n('Are you sure you want to delete all your videos history?')
92
93 const res = await this.confirmService.confirm(message, title)
94 if (res !== true) return
95
96 this.userHistoryService.deleteUserVideosHistory()
97 .subscribe(
98 () => {
99 this.notifier.success(this.i18n('Videos history deleted'))
100
101 this.reloadVideos()
102 },
103
104 err => this.notifier.error(err.message)
105 )
106 }
107}
diff --git a/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.html b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.html
new file mode 100644
index 000000000..d518b22ec
--- /dev/null
+++ b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.html
@@ -0,0 +1,13 @@
1<div class="header">
2 <a routerLink="/my-account/settings" fragment="notifications" i18n>
3 <my-global-icon iconName="cog"></my-global-icon>
4 Notification preferences
5 </a>
6
7 <button (click)="markAllAsRead()" i18n>
8 <my-global-icon iconName="circle-tick"></my-global-icon>
9 Mark all as read
10 </button>
11</div>
12
13<my-user-notifications #userNotification></my-user-notifications>
diff --git a/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.scss b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.scss
new file mode 100644
index 000000000..43d1f82ab
--- /dev/null
+++ b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.scss
@@ -0,0 +1,25 @@
1@import '_variables';
2@import '_mixins';
3
4.header {
5 display: flex;
6 justify-content: space-between;
7 font-size: 15px;
8 margin-bottom: 20px;
9
10 a {
11 @include peertube-button-link;
12 @include grey-button;
13 @include button-with-icon(18px, 3px, -1px);
14 }
15
16 button {
17 @include peertube-button;
18 @include grey-button;
19 @include button-with-icon(20px, 3px, -1px);
20 }
21}
22
23my-user-notifications {
24 font-size: 15px;
25}
diff --git a/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.ts b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.ts
new file mode 100644
index 000000000..3e197088d
--- /dev/null
+++ b/client/src/app/+my-account/my-account-notifications/my-account-notifications.component.ts
@@ -0,0 +1,14 @@
1import { Component, ViewChild } from '@angular/core'
2import { UserNotificationsComponent } from '@app/shared'
3
4@Component({
5 templateUrl: './my-account-notifications.component.html',
6 styleUrls: [ './my-account-notifications.component.scss' ]
7})
8export class MyAccountNotificationsComponent {
9 @ViewChild('userNotification') userNotification: UserNotificationsComponent
10
11 markAllAsRead () {
12 this.userNotification.markAllAsRead()
13 }
14}
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.html b/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.html
index fd7d7d23b..674a4e8a2 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.html
+++ b/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.html
@@ -1,7 +1,8 @@
1<ng-template #modal let-close="close" let-dismiss="dismiss"> 1<ng-template #modal let-close="close" let-dismiss="dismiss">
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Accept ownership</h4> 3 <h4 i18n class="modal-title">Accept ownership</h4>
4 <span class="close" aria-label="Close" role="button" (click)="dismiss()"></span> 4
5 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="dismiss()"></my-global-icon>
5 </div> 6 </div>
6 7
7 <div class="modal-body" [formGroup]="form"> 8 <div class="modal-body" [formGroup]="form">
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts b/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts
index a68b452ec..79d29b139 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts
+++ b/client/src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts
@@ -1,5 +1,5 @@
1import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' 1import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { AuthService, Notifier } from '@app/core'
3import { FormReactive } from '@app/shared' 3import { FormReactive } from '@app/shared'
4import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 4import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
5import { VideoOwnershipService } from '@app/shared/video-ownership' 5import { VideoOwnershipService } from '@app/shared/video-ownership'
@@ -8,7 +8,6 @@ import { VideoAcceptOwnershipValidatorsService } from '@app/shared/forms/form-va
8import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 8import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
9import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 9import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
10import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
11import { AuthService } from '@app/core'
12import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 11import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
13 12
14@Component({ 13@Component({
@@ -31,7 +30,7 @@ export class MyAccountAcceptOwnershipComponent extends FormReactive implements O
31 protected formValidatorService: FormValidatorService, 30 protected formValidatorService: FormValidatorService,
32 private videoChangeOwnershipValidatorsService: VideoAcceptOwnershipValidatorsService, 31 private videoChangeOwnershipValidatorsService: VideoAcceptOwnershipValidatorsService,
33 private videoOwnershipService: VideoOwnershipService, 32 private videoOwnershipService: VideoOwnershipService,
34 private notificationsService: NotificationsService, 33 private notifier: Notifier,
35 private authService: AuthService, 34 private authService: AuthService,
36 private videoChannelService: VideoChannelService, 35 private videoChannelService: VideoChannelService,
37 private modalService: NgbModal, 36 private modalService: NgbModal,
@@ -68,12 +67,12 @@ export class MyAccountAcceptOwnershipComponent extends FormReactive implements O
68 .acceptOwnership(videoChangeOwnership.id, { channelId: channel }) 67 .acceptOwnership(videoChangeOwnership.id, { channelId: channel })
69 .subscribe( 68 .subscribe(
70 () => { 69 () => {
71 this.notificationsService.success(this.i18n('Success'), this.i18n('Ownership accepted')) 70 this.notifier.success(this.i18n('Ownership accepted'))
72 if (this.accepted) this.accepted.emit() 71 if (this.accepted) this.accepted.emit()
73 this.videoChangeOwnership = undefined 72 this.videoChangeOwnership = undefined
74 }, 73 },
75 74
76 err => this.notificationsService.error(this.i18n('Error'), err.message) 75 err => this.notifier.error(err.message)
77 ) 76 )
78 } 77 }
79} 78}
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.html b/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.html
index 379fd8bb1..5709e9f54 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.html
+++ b/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.html
@@ -40,10 +40,10 @@
40 <td class="action-cell"> 40 <td class="action-cell">
41 <ng-container *ngIf="videoChangeOwnership.status === 'WAITING'"> 41 <ng-container *ngIf="videoChangeOwnership.status === 'WAITING'">
42 <my-button i18n label="Accept" 42 <my-button i18n label="Accept"
43 icon="icon-tick" 43 icon="tick"
44 (click)="openAcceptModal(videoChangeOwnership)"></my-button> 44 (click)="openAcceptModal(videoChangeOwnership)"></my-button>
45 <my-button i18n label="Refuse" 45 <my-button i18n label="Refuse"
46 icon="icon-cross" 46 icon="cross"
47 (click)="refuse(videoChangeOwnership)">Refuse</my-button> 47 (click)="refuse(videoChangeOwnership)">Refuse</my-button>
48 </ng-container> 48 </ng-container>
49 </td> 49 </td>
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts b/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts
index 0b51ac13c..77857c4fd 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts
+++ b/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts
@@ -1,13 +1,11 @@
1import { Component, OnInit, ViewChild } from '@angular/core' 1import { Component, OnInit, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { RestPagination, RestTable } from '@app/shared' 3import { RestPagination, RestTable } from '@app/shared'
5import { SortMeta } from 'primeng/components/common/sortmeta' 4import { SortMeta } from 'primeng/components/common/sortmeta'
6import { VideoChangeOwnership } from '../../../../../shared' 5import { VideoChangeOwnership } from '../../../../../shared'
7import { VideoOwnershipService } from '@app/shared/video-ownership' 6import { VideoOwnershipService } from '@app/shared/video-ownership'
8import { Account } from '@app/shared/account/account.model' 7import { Account } from '@app/shared/account/account.model'
9import { MyAccountAcceptOwnershipComponent } 8import { MyAccountAcceptOwnershipComponent } from './my-account-accept-ownership/my-account-accept-ownership.component'
10from '@app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component'
11 9
12@Component({ 10@Component({
13 selector: 'my-account-ownership', 11 selector: 'my-account-ownership',
@@ -23,9 +21,8 @@ export class MyAccountOwnershipComponent extends RestTable implements OnInit {
23 @ViewChild('myAccountAcceptOwnershipComponent') myAccountAcceptOwnershipComponent: MyAccountAcceptOwnershipComponent 21 @ViewChild('myAccountAcceptOwnershipComponent') myAccountAcceptOwnershipComponent: MyAccountAcceptOwnershipComponent
24 22
25 constructor ( 23 constructor (
26 private notificationsService: NotificationsService, 24 private notifier: Notifier,
27 private videoOwnershipService: VideoOwnershipService, 25 private videoOwnershipService: VideoOwnershipService
28 private i18n: I18n
29 ) { 26 ) {
30 super() 27 super()
31 } 28 }
@@ -50,7 +47,7 @@ export class MyAccountOwnershipComponent extends RestTable implements OnInit {
50 this.videoOwnershipService.refuseOwnership(videoChangeOwnership.id) 47 this.videoOwnershipService.refuseOwnership(videoChangeOwnership.id)
51 .subscribe( 48 .subscribe(
52 () => this.loadData(), 49 () => this.loadData(),
53 err => this.notificationsService.error(this.i18n('Error'), err.message) 50 err => this.notifier.error(err.message)
54 ) 51 )
55 } 52 }
56 53
@@ -62,7 +59,7 @@ export class MyAccountOwnershipComponent extends RestTable implements OnInit {
62 this.totalRecords = resultList.total 59 this.totalRecords = resultList.total
63 }, 60 },
64 61
65 err => this.notificationsService.error(this.i18n('Error'), err.message) 62 err => this.notifier.error(err.message)
66 ) 63 )
67 } 64 }
68} 65}
diff --git a/client/src/app/+my-account/my-account-routing.module.ts b/client/src/app/+my-account/my-account-routing.module.ts
index 601e517b4..9996218ca 100644
--- a/client/src/app/+my-account/my-account-routing.module.ts
+++ b/client/src/app/+my-account/my-account-routing.module.ts
@@ -13,6 +13,8 @@ import { MyAccountSubscriptionsComponent } from '@app/+my-account/my-account-sub
13import { MyAccountOwnershipComponent } from '@app/+my-account/my-account-ownership/my-account-ownership.component' 13import { MyAccountOwnershipComponent } from '@app/+my-account/my-account-ownership/my-account-ownership.component'
14import { MyAccountBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-blocklist.component' 14import { MyAccountBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-blocklist.component'
15import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-server-blocklist.component' 15import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-server-blocklist.component'
16import { MyAccountHistoryComponent } from '@app/+my-account/my-account-history/my-account-history.component'
17import { MyAccountNotificationsComponent } from '@app/+my-account/my-account-notifications/my-account-notifications.component'
16 18
17const myAccountRoutes: Routes = [ 19const myAccountRoutes: Routes = [
18 { 20 {
@@ -114,6 +116,24 @@ const myAccountRoutes: Routes = [
114 title: 'Muted instances' 116 title: 'Muted instances'
115 } 117 }
116 } 118 }
119 },
120 {
121 path: 'history/videos',
122 component: MyAccountHistoryComponent,
123 data: {
124 meta: {
125 title: 'Videos history'
126 }
127 }
128 },
129 {
130 path: 'notifications',
131 component: MyAccountNotificationsComponent,
132 data: {
133 meta: {
134 title: 'Notifications'
135 }
136 }
117 } 137 }
118 ] 138 ]
119 } 139 }
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
index e5343b33d..cbb068c7c 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
@@ -1,11 +1,10 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { AuthService, Notifier } from '@app/core'
3import { FormReactive, UserService } from '../../../shared' 3import { FormReactive, UserService } from '../../../shared'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 5import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
6import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service' 6import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service'
7import { filter } from 'rxjs/operators' 7import { filter } from 'rxjs/operators'
8import { AuthService } from '@app/core'
9import { User } from '../../../../../../shared' 8import { User } from '../../../../../../shared'
10 9
11@Component({ 10@Component({
@@ -20,7 +19,7 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On
20 constructor ( 19 constructor (
21 protected formValidatorService: FormValidatorService, 20 protected formValidatorService: FormValidatorService,
22 private userValidatorsService: UserValidatorsService, 21 private userValidatorsService: UserValidatorsService,
23 private notificationsService: NotificationsService, 22 private notifier: Notifier,
24 private authService: AuthService, 23 private authService: AuthService,
25 private userService: UserService, 24 private userService: UserService,
26 private i18n: I18n 25 private i18n: I18n
@@ -50,7 +49,7 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On
50 49
51 this.userService.changePassword(currentPassword, newPassword).subscribe( 50 this.userService.changePassword(currentPassword, newPassword).subscribe(
52 () => { 51 () => {
53 this.notificationsService.success(this.i18n('Success'), this.i18n('Password updated.')) 52 this.notifier.success(this.i18n('Password updated.'))
54 53
55 this.form.reset() 54 this.form.reset()
56 this.error = null 55 this.error = null
diff --git a/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts b/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts
index 63a121f64..3f79efe20 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts
@@ -1,5 +1,5 @@
1import { Component, Input } from '@angular/core' 1import { Component, Input } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { AuthService, ConfirmService, RedirectService } from '../../../core' 3import { AuthService, ConfirmService, RedirectService } from '../../../core'
4import { UserService } from '../../../shared' 4import { UserService } from '../../../shared'
5import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -15,7 +15,7 @@ export class MyAccountDangerZoneComponent {
15 15
16 constructor ( 16 constructor (
17 private authService: AuthService, 17 private authService: AuthService,
18 private notificationsService: NotificationsService, 18 private notifier: Notifier,
19 private userService: UserService, 19 private userService: UserService,
20 private confirmService: ConfirmService, 20 private confirmService: ConfirmService,
21 private redirectService: RedirectService, 21 private redirectService: RedirectService,
@@ -34,13 +34,13 @@ export class MyAccountDangerZoneComponent {
34 34
35 this.userService.deleteMe().subscribe( 35 this.userService.deleteMe().subscribe(
36 () => { 36 () => {
37 this.notificationsService.success(this.i18n('Success'), this.i18n('Your account is deleted.')) 37 this.notifier.success(this.i18n('Your account is deleted.'))
38 38
39 this.authService.logout() 39 this.authService.logout()
40 this.redirectService.redirectToHomepage() 40 this.redirectService.redirectToHomepage()
41 }, 41 },
42 42
43 err => this.notificationsService.error(this.i18n('Error'), err.message) 43 err => this.notifier.error(err.message)
44 ) 44 )
45 } 45 }
46} 46}
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/index.ts b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/index.ts
new file mode 100644
index 000000000..5e1d51339
--- /dev/null
+++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/index.ts
@@ -0,0 +1 @@
export * from './my-account-notification-preferences.component'
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html
new file mode 100644
index 000000000..59422d682
--- /dev/null
+++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html
@@ -0,0 +1,19 @@
1<div class="custom-row">
2 <div i18n>Activities</div>
3 <div i18n>Web</div>
4 <div i18n *ngIf="emailEnabled">Email</div>
5</div>
6
7<div class="custom-row" *ngFor="let notificationType of notificationSettingKeys">
8 <ng-container *ngIf="hasUserRight(notificationType)">
9 <div>{{ labelNotifications[notificationType] }}</div>
10
11 <div>
12 <p-inputSwitch [(ngModel)]="webNotifications[notificationType]" (onChange)="updateWebSetting(notificationType, $event.checked)"></p-inputSwitch>
13 </div>
14
15 <div *ngIf="emailEnabled">
16 <p-inputSwitch [(ngModel)]="emailNotifications[notificationType]" (onChange)="updateEmailSetting(notificationType, $event.checked)"></p-inputSwitch>
17 </div>
18 </ng-container>
19</div>
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.scss b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.scss
new file mode 100644
index 000000000..6feb16ab1
--- /dev/null
+++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.scss
@@ -0,0 +1,25 @@
1@import '_variables';
2@import '_mixins';
3
4.custom-row {
5 display: flex;
6 align-items: center;
7 border-bottom: 1px solid rgba(0, 0, 0, 0.10);
8
9 &:first-child {
10 font-size: 16px;
11
12 & > div {
13 font-weight: $font-semibold;
14 }
15 }
16
17 & > div {
18 width: 350px;
19 }
20
21 & > div {
22 padding: 10px
23 }
24}
25
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts
new file mode 100644
index 000000000..519bdfab4
--- /dev/null
+++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts
@@ -0,0 +1,99 @@
1import { Component, Input, OnInit } from '@angular/core'
2import { User } from '@app/shared'
3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { Subject } from 'rxjs'
5import { UserNotificationSetting, UserNotificationSettingValue, UserRight } from '../../../../../../shared'
6import { Notifier, ServerService } from '@app/core'
7import { debounce } from 'lodash-es'
8import { UserNotificationService } from '@app/shared/users/user-notification.service'
9
10@Component({
11 selector: 'my-account-notification-preferences',
12 templateUrl: './my-account-notification-preferences.component.html',
13 styleUrls: [ './my-account-notification-preferences.component.scss' ]
14})
15export class MyAccountNotificationPreferencesComponent implements OnInit {
16 @Input() user: User = null
17 @Input() userInformationLoaded: Subject<any>
18
19 notificationSettingKeys: (keyof UserNotificationSetting)[] = []
20 emailNotifications: { [ id in keyof UserNotificationSetting ]: boolean } = {} as any
21 webNotifications: { [ id in keyof UserNotificationSetting ]: boolean } = {} as any
22 labelNotifications: { [ id in keyof UserNotificationSetting ]: string } = {} as any
23 rightNotifications: { [ id in keyof Partial<UserNotificationSetting> ]: UserRight } = {} as any
24 emailEnabled: boolean
25
26 private savePreferences = debounce(this.savePreferencesImpl.bind(this), 500)
27
28 constructor (
29 private i18n: I18n,
30 private userNotificationService: UserNotificationService,
31 private serverService: ServerService,
32 private notifier: Notifier
33 ) {
34 this.labelNotifications = {
35 newVideoFromSubscription: this.i18n('New video from your subscriptions'),
36 newCommentOnMyVideo: this.i18n('New comment on your video'),
37 videoAbuseAsModerator: this.i18n('New video abuse on local video'),
38 blacklistOnMyVideo: this.i18n('One of your video is blacklisted/unblacklisted'),
39 myVideoPublished: this.i18n('Video published (after transcoding/scheduled update)'),
40 myVideoImportFinished: this.i18n('Video import finished'),
41 newUserRegistration: this.i18n('A new user registered on your instance'),
42 newFollow: this.i18n('You or your channel(s) has a new follower'),
43 commentMention: this.i18n('Someone mentioned you in video comments')
44 }
45 this.notificationSettingKeys = Object.keys(this.labelNotifications) as (keyof UserNotificationSetting)[]
46
47 this.rightNotifications = {
48 videoAbuseAsModerator: UserRight.MANAGE_VIDEO_ABUSES,
49 newUserRegistration: UserRight.MANAGE_USERS
50 }
51
52 this.emailEnabled = this.serverService.getConfig().email.enabled
53 }
54
55 ngOnInit () {
56 this.userInformationLoaded.subscribe(() => this.loadNotificationSettings())
57 }
58
59 hasUserRight (field: keyof UserNotificationSetting) {
60 const rightToHave = this.rightNotifications[field]
61 if (!rightToHave) return true // No rights needed
62
63 return this.user.hasRight(rightToHave)
64 }
65
66 updateEmailSetting (field: keyof UserNotificationSetting, value: boolean) {
67 if (value === true) this.user.notificationSettings[field] |= UserNotificationSettingValue.EMAIL
68 else this.user.notificationSettings[field] &= ~UserNotificationSettingValue.EMAIL
69
70 this.savePreferences()
71 }
72
73 updateWebSetting (field: keyof UserNotificationSetting, value: boolean) {
74 if (value === true) this.user.notificationSettings[field] |= UserNotificationSettingValue.WEB
75 else this.user.notificationSettings[field] &= ~UserNotificationSettingValue.WEB
76
77 this.savePreferences()
78 }
79
80 private savePreferencesImpl () {
81 this.userNotificationService.updateNotificationSettings(this.user, this.user.notificationSettings)
82 .subscribe(
83 () => {
84 this.notifier.success(this.i18n('Preferences saved'), undefined, 2000)
85 },
86
87 err => this.notifier.error(err.message)
88 )
89 }
90
91 private loadNotificationSettings () {
92 for (const key of Object.keys(this.user.notificationSettings)) {
93 const value = this.user.notificationSettings[key]
94 this.emailNotifications[key] = value & UserNotificationSettingValue.EMAIL
95
96 this.webNotifications[key] = value & UserNotificationSettingValue.WEB
97 }
98 }
99}
diff --git a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
index 967e21f0b..a9503ed1b 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts
@@ -1,5 +1,5 @@
1import { Component, Input, OnInit } from '@angular/core' 1import { Component, Input, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { FormReactive, UserService } from '../../../shared' 3import { FormReactive, UserService } from '../../../shared'
4import { User } from '@app/shared' 4import { User } from '@app/shared'
5import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -21,7 +21,7 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit {
21 constructor ( 21 constructor (
22 protected formValidatorService: FormValidatorService, 22 protected formValidatorService: FormValidatorService,
23 private userValidatorsService: UserValidatorsService, 23 private userValidatorsService: UserValidatorsService,
24 private notificationsService: NotificationsService, 24 private notifier: Notifier,
25 private userService: UserService, 25 private userService: UserService,
26 private i18n: I18n 26 private i18n: I18n
27 ) { 27 ) {
@@ -53,7 +53,7 @@ export class MyAccountProfileComponent extends FormReactive implements OnInit {
53 this.user.account.displayName = displayName 53 this.user.account.displayName = displayName
54 this.user.account.description = description 54 this.user.account.description = description
55 55
56 this.notificationsService.success(this.i18n('Success'), this.i18n('Profile updated.')) 56 this.notifier.success(this.i18n('Profile updated.'))
57 }, 57 },
58 58
59 err => this.error = err.message 59 err => this.error = err.message
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
index c7e23cd1f..ad64f28fe 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
+++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
@@ -4,10 +4,11 @@
4 <span i18n class="user-quota-label">Video quota:</span> {{ userVideoQuotaUsed | bytes: 0 }} / {{ userVideoQuota }} 4 <span i18n class="user-quota-label">Video quota:</span> {{ userVideoQuotaUsed | bytes: 0 }} / {{ userVideoQuota }}
5</div> 5</div>
6 6
7<ng-template [ngIf]="user && user.account"> 7<div i18n class="account-title">Profile</div>
8 <div i18n class="account-title">Profile</div> 8<my-account-profile [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-profile>
9 <my-account-profile [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-profile> 9
10</ng-template> 10<div i18n class="account-title" id="notifications">Notifications</div>
11<my-account-notification-preferences [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-notification-preferences>
11 12
12<div i18n class="account-title">Password</div> 13<div i18n class="account-title">Password</div>
13<my-account-change-password></my-account-change-password> 14<my-account-change-password></my-account-change-password>
@@ -16,4 +17,4 @@
16<my-account-video-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-video-settings> 17<my-account-video-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-video-settings>
17 18
18<div i18n class="account-title">Danger zone</div> 19<div i18n class="account-title">Danger zone</div>
19<my-account-danger-zone [user]="user"></my-account-danger-zone> \ No newline at end of file 20<my-account-danger-zone [user]="user"></my-account-danger-zone>
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
index 62053d97b..f4b954e54 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
@@ -1,5 +1,5 @@
1import { Component, OnInit, ViewChild } from '@angular/core' 1import { Component, OnInit, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { BytesPipe } from 'ngx-pipes' 3import { BytesPipe } from 'ngx-pipes'
4import { AuthService } from '../../core' 4import { AuthService } from '../../core'
5import { User } from '../../shared' 5import { User } from '../../shared'
@@ -19,7 +19,7 @@ export class MyAccountSettingsComponent implements OnInit {
19 constructor ( 19 constructor (
20 private userService: UserService, 20 private userService: UserService,
21 private authService: AuthService, 21 private authService: AuthService,
22 private notificationsService: NotificationsService, 22 private notifier: Notifier,
23 private i18n: I18n 23 private i18n: I18n
24 ) {} 24 ) {}
25 25
@@ -48,12 +48,12 @@ export class MyAccountSettingsComponent implements OnInit {
48 this.userService.changeAvatar(formData) 48 this.userService.changeAvatar(formData)
49 .subscribe( 49 .subscribe(
50 data => { 50 data => {
51 this.notificationsService.success(this.i18n('Success'), this.i18n('Avatar changed.')) 51 this.notifier.success(this.i18n('Avatar changed.'))
52 52
53 this.user.updateAccountAvatar(data.avatar) 53 this.user.updateAccountAvatar(data.avatar)
54 }, 54 },
55 55
56 err => this.notificationsService.error(this.i18n('Error'), err.message) 56 err => this.notifier.error(err.message)
57 ) 57 )
58 } 58 }
59} 59}
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
index 6c9a7ce75..b8f80bc1a 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
@@ -1,5 +1,5 @@
1import { Component, Input, OnInit } from '@angular/core' 1import { Component, Input, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { UserUpdateMe } from '../../../../../../shared' 3import { UserUpdateMe } from '../../../../../../shared'
4import { AuthService } from '../../../core' 4import { AuthService } from '../../../core'
5import { FormReactive, User, UserService } from '../../../shared' 5import { FormReactive, User, UserService } from '../../../shared'
@@ -19,7 +19,7 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
19 constructor ( 19 constructor (
20 protected formValidatorService: FormValidatorService, 20 protected formValidatorService: FormValidatorService,
21 private authService: AuthService, 21 private authService: AuthService,
22 private notificationsService: NotificationsService, 22 private notifier: Notifier,
23 private userService: UserService, 23 private userService: UserService,
24 private i18n: I18n 24 private i18n: I18n
25 ) { 25 ) {
@@ -54,12 +54,12 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
54 54
55 this.userService.updateMyProfile(details).subscribe( 55 this.userService.updateMyProfile(details).subscribe(
56 () => { 56 () => {
57 this.notificationsService.success(this.i18n('Success'), this.i18n('Information updated.')) 57 this.notifier.success(this.i18n('Information updated.'))
58 58
59 this.authService.refreshUserInformation() 59 this.authService.refreshUserInformation()
60 }, 60 },
61 61
62 err => this.notificationsService.error(this.i18n('Error'), err.message) 62 err => this.notifier.error(err.message)
63 ) 63 )
64 } 64 }
65} 65}
diff --git a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts b/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts
index 9517a3705..9d2dccdf0 100644
--- a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts
+++ b/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts
@@ -1,5 +1,5 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 3import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { UserSubscriptionService } from '@app/shared/user-subscription' 5import { UserSubscriptionService } from '@app/shared/user-subscription'
@@ -21,7 +21,7 @@ export class MyAccountSubscriptionsComponent implements OnInit {
21 21
22 constructor ( 22 constructor (
23 private userSubscriptionService: UserSubscriptionService, 23 private userSubscriptionService: UserSubscriptionService,
24 private notificationsService: NotificationsService, 24 private notifier: Notifier,
25 private i18n: I18n 25 private i18n: I18n
26 ) {} 26 ) {}
27 27
@@ -37,7 +37,7 @@ export class MyAccountSubscriptionsComponent implements OnInit {
37 this.pagination.totalItems = res.total 37 this.pagination.totalItems = res.total
38 }, 38 },
39 39
40 error => this.notificationsService.error(this.i18n('Error'), error.message) 40 error => this.notifier.error(error.message)
41 ) 41 )
42 } 42 }
43 43
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
index 81608d837..a68f79b47 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts
@@ -1,10 +1,9 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { AuthService, Notifier } from '@app/core'
4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' 4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit'
5import { VideoChannelCreate } from '../../../../../shared/models/videos' 5import { VideoChannelCreate } from '../../../../../shared/models/videos'
6import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 6import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
7import { AuthService } from '@app/core'
8import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
9import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 8import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
10import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators/video-channel-validators.service' 9import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators/video-channel-validators.service'
@@ -21,7 +20,7 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE
21 protected formValidatorService: FormValidatorService, 20 protected formValidatorService: FormValidatorService,
22 private authService: AuthService, 21 private authService: AuthService,
23 private videoChannelValidatorsService: VideoChannelValidatorsService, 22 private videoChannelValidatorsService: VideoChannelValidatorsService,
24 private notificationsService: NotificationsService, 23 private notifier: Notifier,
25 private router: Router, 24 private router: Router,
26 private videoChannelService: VideoChannelService, 25 private videoChannelService: VideoChannelService,
27 private i18n: I18n 26 private i18n: I18n
@@ -56,8 +55,8 @@ export class MyAccountVideoChannelCreateComponent extends MyAccountVideoChannelE
56 this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe( 55 this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe(
57 () => { 56 () => {
58 this.authService.refreshUserInformation() 57 this.authService.refreshUserInformation()
59 this.notificationsService.success( 58
60 this.i18n('Success'), 59 this.notifier.success(
61 this.i18n('Video channel {{videoChannelName}} created.', { videoChannelName: videoChannelCreate.displayName }) 60 this.i18n('Video channel {{videoChannelName}} created.', { videoChannelName: videoChannelCreate.displayName })
62 ) 61 )
63 this.router.navigate([ '/my-account', 'video-channels' ]) 62 this.router.navigate([ '/my-account', 'video-channels' ])
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
index 5d43956f2..da4fb645a 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
@@ -1,12 +1,11 @@
1import { Component, OnDestroy, OnInit } from '@angular/core' 1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { AuthService, Notifier, ServerService } from '@app/core'
4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' 4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit'
5import { VideoChannelUpdate } from '../../../../../shared/models/videos' 5import { VideoChannelUpdate } from '../../../../../shared/models/videos'
6import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 6import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
7import { Subscription } from 'rxjs' 7import { Subscription } from 'rxjs'
8import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 8import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
9import { AuthService, ServerService } from '@app/core'
10import { I18n } from '@ngx-translate/i18n-polyfill' 9import { I18n } from '@ngx-translate/i18n-polyfill'
11import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 10import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
12import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators/video-channel-validators.service' 11import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators/video-channel-validators.service'
@@ -26,7 +25,7 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
26 protected formValidatorService: FormValidatorService, 25 protected formValidatorService: FormValidatorService,
27 private authService: AuthService, 26 private authService: AuthService,
28 private videoChannelValidatorsService: VideoChannelValidatorsService, 27 private videoChannelValidatorsService: VideoChannelValidatorsService,
29 private notificationsService: NotificationsService, 28 private notifier: Notifier,
30 private router: Router, 29 private router: Router,
31 private route: ActivatedRoute, 30 private route: ActivatedRoute,
32 private videoChannelService: VideoChannelService, 31 private videoChannelService: VideoChannelService,
@@ -79,10 +78,11 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
79 this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.name, videoChannelUpdate).subscribe( 78 this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.name, videoChannelUpdate).subscribe(
80 () => { 79 () => {
81 this.authService.refreshUserInformation() 80 this.authService.refreshUserInformation()
82 this.notificationsService.success( 81
83 this.i18n('Success'), 82 this.notifier.success(
84 this.i18n('Video channel {{videoChannelName}} updated.', { videoChannelName: videoChannelUpdate.displayName }) 83 this.i18n('Video channel {{videoChannelName}} updated.', { videoChannelName: videoChannelUpdate.displayName })
85 ) 84 )
85
86 this.router.navigate([ '/my-account', 'video-channels' ]) 86 this.router.navigate([ '/my-account', 'video-channels' ])
87 }, 87 },
88 88
@@ -94,12 +94,12 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
94 this.videoChannelService.changeVideoChannelAvatar(this.videoChannelToUpdate.name, formData) 94 this.videoChannelService.changeVideoChannelAvatar(this.videoChannelToUpdate.name, formData)
95 .subscribe( 95 .subscribe(
96 data => { 96 data => {
97 this.notificationsService.success(this.i18n('Success'), this.i18n('Avatar changed.')) 97 this.notifier.success(this.i18n('Avatar changed.'))
98 98
99 this.videoChannelToUpdate.updateAvatar(data.avatar) 99 this.videoChannelToUpdate.updateAvatar(data.avatar)
100 }, 100 },
101 101
102 err => this.notificationsService.error(this.i18n('Error'), err.message) 102 err => this.notifier.error(err.message)
103 ) 103 )
104 } 104 }
105 105
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html
index df74b19b6..51db2e75d 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html
@@ -1,6 +1,6 @@
1<div class="video-channels-header"> 1<div class="video-channels-header">
2 <a class="create-button" routerLink="create"> 2 <a class="create-button" routerLink="create">
3 <span class="icon icon-add"></span> 3 <my-global-icon iconName="add"></my-global-icon>
4 <ng-container i18n>Create another video channel</ng-container> 4 <ng-container i18n>Create another video channel</ng-container>
5 </a> 5 </a>
6</div> 6</div>
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.scss b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.scss
index 472cbb723..77fce138b 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.scss
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.scss
@@ -2,7 +2,7 @@
2@import '_mixins'; 2@import '_mixins';
3 3
4.create-button { 4.create-button {
5 @include create-button('../../../assets/images/global/add.svg'); 5 @include create-button;
6} 6}
7 7
8/deep/ .action-button { 8/deep/ .action-button {
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts
index 6d1098865..da2c5bcd3 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts
@@ -1,5 +1,5 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { AuthService } from '../../core/auth' 3import { AuthService } from '../../core/auth'
4import { ConfirmService } from '../../core/confirm' 4import { ConfirmService } from '../../core/confirm'
5import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 5import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
@@ -20,7 +20,7 @@ export class MyAccountVideoChannelsComponent implements OnInit {
20 20
21 constructor ( 21 constructor (
22 private authService: AuthService, 22 private authService: AuthService,
23 private notificationsService: NotificationsService, 23 private notifier: Notifier,
24 private confirmService: ConfirmService, 24 private confirmService: ConfirmService,
25 private videoChannelService: VideoChannelService, 25 private videoChannelService: VideoChannelService,
26 private i18n: I18n 26 private i18n: I18n
@@ -35,10 +35,14 @@ export class MyAccountVideoChannelsComponent implements OnInit {
35 async deleteVideoChannel (videoChannel: VideoChannel) { 35 async deleteVideoChannel (videoChannel: VideoChannel) {
36 const res = await this.confirmService.confirmWithInput( 36 const res = await this.confirmService.confirmWithInput(
37 this.i18n( 37 this.i18n(
38 'Do you really want to delete {{videoChannelName}}? It will delete all videos uploaded in this channel too.', 38 'Do you really want to delete {{channelDisplayName}}? It will delete all videos uploaded in this channel, ' +
39 { videoChannelName: videoChannel.displayName } 39 'and you will not be able to create another channel with the same name ({{channelName}})!',
40 { channelDisplayName: videoChannel.displayName, channelName: videoChannel.name }
41 ),
42 this.i18n(
43 'Please type the display name of the video channel ({{displayName}}) to confirm',
44 { displayName: videoChannel.displayName }
40 ), 45 ),
41 this.i18n('Please type the name of the video channel to confirm'),
42 videoChannel.displayName, 46 videoChannel.displayName,
43 this.i18n('Delete') 47 this.i18n('Delete')
44 ) 48 )
@@ -46,15 +50,14 @@ export class MyAccountVideoChannelsComponent implements OnInit {
46 50
47 this.videoChannelService.removeVideoChannel(videoChannel) 51 this.videoChannelService.removeVideoChannel(videoChannel)
48 .subscribe( 52 .subscribe(
49 status => { 53 () => {
50 this.loadVideoChannels() 54 this.loadVideoChannels()
51 this.notificationsService.success( 55 this.notifier.success(
52 this.i18n('Success'),
53 this.i18n('Video channel {{videoChannelName}} deleted.', { videoChannelName: videoChannel.displayName }) 56 this.i18n('Video channel {{videoChannelName}} deleted.', { videoChannelName: videoChannel.displayName })
54 ) 57 )
55 }, 58 },
56 59
57 error => this.notificationsService.error(this.i18n('Error'), error.message) 60 error => this.notifier.error(error.message)
58 ) 61 )
59 } 62 }
60 63
diff --git a/client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.ts b/client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.ts
index 5b920c98d..21a10c8ff 100644
--- a/client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.ts
+++ b/client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.ts
@@ -1,7 +1,7 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { RestPagination, RestTable } from '@app/shared' 2import { RestPagination, RestTable } from '@app/shared'
3import { SortMeta } from 'primeng/components/common/sortmeta' 3import { SortMeta } from 'primeng/components/common/sortmeta'
4import { NotificationsService } from 'angular2-notifications' 4import { Notifier } from '@app/core'
5import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
6import { VideoImport, VideoImportState } from '../../../../../shared/models/videos' 6import { VideoImport, VideoImportState } from '../../../../../shared/models/videos'
7import { VideoImportService } from '@app/shared/video-import' 7import { VideoImportService } from '@app/shared/video-import'
@@ -19,7 +19,7 @@ export class MyAccountVideoImportsComponent extends RestTable implements OnInit
19 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 19 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
20 20
21 constructor ( 21 constructor (
22 private notificationsService: NotificationsService, 22 private notifier: Notifier,
23 private videoImportService: VideoImportService, 23 private videoImportService: VideoImportService,
24 private i18n: I18n 24 private i18n: I18n
25 ) { 25 ) {
@@ -58,7 +58,7 @@ export class MyAccountVideoImportsComponent extends RestTable implements OnInit
58 this.totalRecords = resultList.total 58 this.totalRecords = resultList.total
59 }, 59 },
60 60
61 err => this.notificationsService.error(this.i18n('Error'), err.message) 61 err => this.notifier.error(err.message)
62 ) 62 )
63 } 63 }
64} 64}
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
index a6911e4bf..69748ef37 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
+++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html
@@ -32,7 +32,7 @@
32 </span> 32 </span>
33 33
34 <span class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()"> 34 <span class="action-button action-button-delete-selection" (click)="deleteSelectedVideos()">
35 <span class="icon icon-delete-white"></span> 35 <my-global-icon iconName="delete"></my-global-icon>
36 <ng-container i18n>Delete</ng-container> 36 <ng-container i18n>Delete</ng-container>
37 </span> 37 </span>
38 </div> 38 </div>
@@ -45,7 +45,7 @@
45 45
46 <my-button i18n-label label="Change ownership" 46 <my-button i18n-label label="Change ownership"
47 className="action-button-change-ownership" 47 className="action-button-change-ownership"
48 icon="icon-im-with-her" 48 icon="im-with-her"
49 (click)="changeOwnership($event, video)" 49 (click)="changeOwnership($event, video)"
50 ></my-button> 50 ></my-button>
51 </div> 51 </div>
@@ -53,4 +53,4 @@
53 </div> 53 </div>
54</div> 54</div>
55 55
56<my-video-change-ownership #videoChangeOwnershipModal></my-video-change-ownership> \ No newline at end of file 56<my-video-change-ownership #videoChangeOwnershipModal></my-video-change-ownership>
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss
index 2db81a3fe..39d0cf2f7 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss
+++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss
@@ -23,14 +23,11 @@
23 .action-button-delete-selection { 23 .action-button-delete-selection {
24 @include peertube-button; 24 @include peertube-button;
25 @include orange-button; 25 @include orange-button;
26 } 26 @include button-with-icon(21px);
27
28 .icon.icon-delete-white {
29 @include icon(21px);
30 27
31 position: relative; 28 my-global-icon {
32 top: -2px; 29 @include apply-svg-color(#fff);
33 background-image: url('../../../assets/images/global/delete-white.svg'); 30 }
34 } 31 }
35 } 32 }
36} 33}
@@ -97,7 +94,7 @@
97 } 94 }
98} 95}
99 96
100@media screen and (max-width: 800px) { 97@media screen and (max-width: $small-view) {
101 .video { 98 .video {
102 flex-direction: column; 99 flex-direction: column;
103 height: auto; 100 height: auto;
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts
index 2d88ac760..41608f796 100644
--- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts
+++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.ts
@@ -5,7 +5,7 @@ import { ActivatedRoute, Router } from '@angular/router'
5import { Location } from '@angular/common' 5import { Location } from '@angular/common'
6import { immutableAssign } from '@app/shared/misc/utils' 6import { immutableAssign } from '@app/shared/misc/utils'
7import { ComponentPagination } from '@app/shared/rest/component-pagination.model' 7import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
8import { NotificationsService } from 'angular2-notifications' 8import { Notifier } from '@app/core'
9import { AuthService } from '../../core/auth' 9import { AuthService } from '../../core/auth'
10import { ConfirmService } from '../../core/confirm' 10import { ConfirmService } from '../../core/confirm'
11import { AbstractVideoList } from '../../shared/video/abstract-video-list' 11import { AbstractVideoList } from '../../shared/video/abstract-video-list'
@@ -40,7 +40,7 @@ export class MyAccountVideosComponent extends AbstractVideoList implements OnIni
40 protected router: Router, 40 protected router: Router,
41 protected route: ActivatedRoute, 41 protected route: ActivatedRoute,
42 protected authService: AuthService, 42 protected authService: AuthService,
43 protected notificationsService: NotificationsService, 43 protected notifier: Notifier,
44 protected location: Location, 44 protected location: Location,
45 protected screenService: ScreenService, 45 protected screenService: ScreenService,
46 protected i18n: I18n, 46 protected i18n: I18n,
@@ -102,16 +102,13 @@ export class MyAccountVideosComponent extends AbstractVideoList implements OnIni
102 .pipe(concatAll()) 102 .pipe(concatAll())
103 .subscribe( 103 .subscribe(
104 res => { 104 res => {
105 this.notificationsService.success( 105 this.notifier.success(this.i18n('{{deleteLength}} videos deleted.', { deleteLength: toDeleteVideosIds.length }))
106 this.i18n('Success'),
107 this.i18n('{{deleteLength}} videos deleted.', { deleteLength: toDeleteVideosIds.length })
108 )
109 106
110 this.abortSelectionMode() 107 this.abortSelectionMode()
111 this.reloadVideos() 108 this.reloadVideos()
112 }, 109 },
113 110
114 err => this.notificationsService.error(this.i18n('Error'), err.message) 111 err => this.notifier.error(err.message)
115 ) 112 )
116 } 113 }
117 114
@@ -124,15 +121,12 @@ export class MyAccountVideosComponent extends AbstractVideoList implements OnIni
124 121
125 this.videoService.removeVideo(video.id) 122 this.videoService.removeVideo(video.id)
126 .subscribe( 123 .subscribe(
127 status => { 124 () => {
128 this.notificationsService.success( 125 this.notifier.success(this.i18n('Video {{videoName}} deleted.', { videoName: video.name }))
129 this.i18n('Success'),
130 this.i18n('Video {{videoName}} deleted.', { videoName: video.name })
131 )
132 this.reloadVideos() 126 this.reloadVideos()
133 }, 127 },
134 128
135 error => this.notificationsService.error(this.i18n('Error'), error.message) 129 error => this.notifier.error(error.message)
136 ) 130 )
137 } 131 }
138 132
diff --git a/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html b/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html
index 7c0df850d..22f127904 100644
--- a/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html
+++ b/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html
@@ -1,7 +1,8 @@
1<ng-template #modal let-close="close" let-dismiss="dismiss"> 1<ng-template #modal let-close="close" let-dismiss="dismiss">
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Change ownership</h4> 3 <h4 i18n class="modal-title">Change ownership</h4>
4 <span class="close" aria-label="Close" role="button" (click)="dismiss()"></span> 4
5 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="dismiss()"></my-global-icon>
5 </div> 6 </div>
6 7
7 <div class="modal-body" [formGroup]="form"> 8 <div class="modal-body" [formGroup]="form">
diff --git a/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts b/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts
index 9f94f3c13..37d7cf2a4 100644
--- a/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts
+++ b/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts
@@ -1,5 +1,5 @@
1import { Component, ElementRef, OnInit, ViewChild } from '@angular/core' 1import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 3import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
4import { FormReactive, UserService } from '../../../shared/index' 4import { FormReactive, UserService } from '../../../shared/index'
5import { Video } from '@app/shared/video/video.model' 5import { Video } from '@app/shared/video/video.model'
@@ -25,7 +25,7 @@ export class VideoChangeOwnershipComponent extends FormReactive implements OnIni
25 protected formValidatorService: FormValidatorService, 25 protected formValidatorService: FormValidatorService,
26 private videoChangeOwnershipValidatorsService: VideoChangeOwnershipValidatorsService, 26 private videoChangeOwnershipValidatorsService: VideoChangeOwnershipValidatorsService,
27 private videoOwnershipService: VideoOwnershipService, 27 private videoOwnershipService: VideoOwnershipService,
28 private notificationsService: NotificationsService, 28 private notifier: Notifier,
29 private userService: UserService, 29 private userService: UserService,
30 private modalService: NgbModal, 30 private modalService: NgbModal,
31 private i18n: I18n 31 private i18n: I18n
@@ -53,11 +53,9 @@ export class VideoChangeOwnershipComponent extends FormReactive implements OnIni
53 const query = event.query 53 const query = event.query
54 this.userService.autocomplete(query) 54 this.userService.autocomplete(query)
55 .subscribe( 55 .subscribe(
56 usernames => { 56 usernames => this.usernamePropositions = usernames,
57 this.usernamePropositions = usernames
58 },
59 57
60 err => this.notificationsService.error('Error', err.message) 58 err => this.notifier.error(err.message)
61 ) 59 )
62 } 60 }
63 61
@@ -67,9 +65,9 @@ export class VideoChangeOwnershipComponent extends FormReactive implements OnIni
67 this.videoOwnershipService 65 this.videoOwnershipService
68 .changeOwnership(this.video.id, username) 66 .changeOwnership(this.video.id, username)
69 .subscribe( 67 .subscribe(
70 () => this.notificationsService.success(this.i18n('Success'), this.i18n('Ownership change request sent.')), 68 () => this.notifier.success(this.i18n('Ownership change request sent.')),
71 69
72 err => this.notificationsService.error(this.i18n('Error'), err.message) 70 err => this.notifier.error(err.message)
73 ) 71 )
74 } 72 }
75} 73}
diff --git a/client/src/app/+my-account/my-account.component.html b/client/src/app/+my-account/my-account.component.html
index 41333c25a..3999252be 100644
--- a/client/src/app/+my-account/my-account.component.html
+++ b/client/src/app/+my-account/my-account.component.html
@@ -1,40 +1,5 @@
1<div class="row"> 1<div class="row">
2 <div class="sub-menu"> 2 <my-top-menu-dropdown [menuEntries]="menuEntries"></my-top-menu-dropdown>
3 <a i18n routerLink="/my-account/settings" routerLinkActive="active" class="title-page">My settings</a>
4
5 <div ngbDropdown class="my-library">
6 <span role="button" class="title-page" [ngClass]="{ active: libraryLabel !== '' }" ngbDropdownToggle>
7 <ng-container i18n>My library</ng-container>
8 <ng-container *ngIf="libraryLabel"> - {{ libraryLabel }}</ng-container>
9 </span>
10
11 <div ngbDropdownMenu>
12 <a class="dropdown-item" i18n routerLink="/my-account/video-channels">My channels</a>
13
14 <a class="dropdown-item" i18n routerLink="/my-account/videos">My videos</a>
15
16 <a class="dropdown-item" i18n routerLink="/my-account/subscriptions">My subscriptions</a>
17
18 <a class="dropdown-item" *ngIf="isVideoImportEnabled()" i18n routerLink="/my-account/video-imports">My imports</a>
19 </div>
20 </div>
21
22 <div ngbDropdown class="misc">
23 <span role="button" class="title-page" [ngClass]="{ active: miscLabel !== '' }" ngbDropdownToggle>
24 <ng-container i18n>Misc</ng-container>
25 <ng-container *ngIf="miscLabel"> - {{ miscLabel }}</ng-container>
26 </span>
27
28 <div ngbDropdownMenu>
29 <a class="dropdown-item" i18n routerLink="/my-account/blocklist/accounts">Muted accounts</a>
30
31 <a class="dropdown-item" i18n routerLink="/my-account/blocklist/servers">Muted instances</a>
32
33 <a class="dropdown-item" i18n routerLink="/my-account/ownership">Ownership changes</a>
34 </div>
35 </div>
36
37 </div>
38 3
39 <div class="margin-content"> 4 <div class="margin-content">
40 <router-outlet></router-outlet> 5 <router-outlet></router-outlet>
diff --git a/client/src/app/+my-account/my-account.component.scss b/client/src/app/+my-account/my-account.component.scss
index 6243c6dcf..4f111efdf 100644
--- a/client/src/app/+my-account/my-account.component.scss
+++ b/client/src/app/+my-account/my-account.component.scss
@@ -1,14 +1,3 @@
1.my-library, .misc { 1.row {
2 span[role=button] { 2 flex-direction: column;
3 cursor: pointer;
4 }
5
6 a {
7 display: block;
8 }
9} 3}
10
11/deep/ .dropdown-toggle::after {
12 position: relative;
13 top: 2px;
14} \ No newline at end of file
diff --git a/client/src/app/+my-account/my-account.component.ts b/client/src/app/+my-account/my-account.component.ts
index d728caf07..8a4102d80 100644
--- a/client/src/app/+my-account/my-account.component.ts
+++ b/client/src/app/+my-account/my-account.component.ts
@@ -1,38 +1,80 @@
1import { Component, OnDestroy, OnInit } from '@angular/core' 1import { Component } from '@angular/core'
2import { ServerService } from '@app/core' 2import { ServerService } from '@app/core'
3import { NavigationStart, Router } from '@angular/router'
4import { filter } from 'rxjs/operators'
5import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
6import { Subscription } from 'rxjs' 4import { TopMenuDropdownParam } from '@app/shared/menu/top-menu-dropdown.component'
7 5
8@Component({ 6@Component({
9 selector: 'my-my-account', 7 selector: 'my-my-account',
10 templateUrl: './my-account.component.html', 8 templateUrl: './my-account.component.html',
11 styleUrls: [ './my-account.component.scss' ] 9 styleUrls: [ './my-account.component.scss' ]
12}) 10})
13export class MyAccountComponent implements OnInit, OnDestroy { 11export class MyAccountComponent {
14 12 menuEntries: TopMenuDropdownParam[] = []
15 libraryLabel = ''
16 miscLabel = ''
17
18 private routeSub: Subscription
19 13
20 constructor ( 14 constructor (
21 private serverService: ServerService, 15 private serverService: ServerService,
22 private router: Router,
23 private i18n: I18n 16 private i18n: I18n
24 ) {} 17 ) {
18
19 const libraryEntries: TopMenuDropdownParam = {
20 label: this.i18n('My library'),
21 children: [
22 {
23 label: this.i18n('My channels'),
24 routerLink: '/my-account/video-channels'
25 },
26 {
27 label: this.i18n('My videos'),
28 routerLink: '/my-account/videos'
29 },
30 {
31 label: this.i18n('My subscriptions'),
32 routerLink: '/my-account/subscriptions'
33 },
34 {
35 label: this.i18n('My history'),
36 routerLink: '/my-account/history/videos'
37 }
38 ]
39 }
25 40
26 ngOnInit () { 41 if (this.isVideoImportEnabled()) {
27 this.updateLabels(this.router.url) 42 libraryEntries.children.push({
43 label: 'My imports',
44 routerLink: '/my-account/video-imports'
45 })
46 }
28 47
29 this.routeSub = this.router.events 48 const miscEntries: TopMenuDropdownParam = {
30 .pipe(filter(event => event instanceof NavigationStart)) 49 label: this.i18n('Misc'),
31 .subscribe((event: NavigationStart) => this.updateLabels(event.url)) 50 children: [
32 } 51 {
52 label: this.i18n('Muted accounts'),
53 routerLink: '/my-account/blocklist/accounts'
54 },
55 {
56 label: this.i18n('Muted instances'),
57 routerLink: '/my-account/blocklist/servers'
58 },
59 {
60 label: this.i18n('Ownership changes'),
61 routerLink: '/my-account/ownership'
62 }
63 ]
64 }
33 65
34 ngOnDestroy () { 66 this.menuEntries = [
35 if (this.routeSub) this.routeSub.unsubscribe() 67 {
68 label: this.i18n('My settings'),
69 routerLink: '/my-account/settings'
70 },
71 {
72 label: this.i18n('My notifications'),
73 routerLink: '/my-account/notifications'
74 },
75 libraryEntries,
76 miscEntries
77 ]
36 } 78 }
37 79
38 isVideoImportEnabled () { 80 isVideoImportEnabled () {
@@ -41,27 +83,4 @@ export class MyAccountComponent implements OnInit, OnDestroy {
41 return importConfig.http.enabled || importConfig.torrent.enabled 83 return importConfig.http.enabled || importConfig.torrent.enabled
42 } 84 }
43 85
44 private updateLabels (url: string) {
45 const [ path ] = url.split('?')
46
47 if (path.startsWith('/my-account/video-channels')) {
48 this.libraryLabel = this.i18n('Channels')
49 } else if (path.startsWith('/my-account/videos')) {
50 this.libraryLabel = this.i18n('Videos')
51 } else if (path.startsWith('/my-account/subscriptions')) {
52 this.libraryLabel = this.i18n('Subscriptions')
53 } else if (path.startsWith('/my-account/video-imports')) {
54 this.libraryLabel = this.i18n('Video imports')
55 } else {
56 this.libraryLabel = ''
57 }
58
59 if (path.startsWith('/my-account/blocklist/accounts')) {
60 this.miscLabel = this.i18n('Muted accounts')
61 } else if (path.startsWith('/my-account/blocklist/servers')) {
62 this.miscLabel = this.i18n('Muted instances')
63 } else {
64 this.miscLabel = ''
65 }
66 }
67} 86}
diff --git a/client/src/app/+my-account/my-account.module.ts b/client/src/app/+my-account/my-account.module.ts
index 017ebd57d..18f51f171 100644
--- a/client/src/app/+my-account/my-account.module.ts
+++ b/client/src/app/+my-account/my-account.module.ts
@@ -1,6 +1,7 @@
1import { TableModule } from 'primeng/table' 1import { TableModule } from 'primeng/table'
2import { NgModule } from '@angular/core' 2import { NgModule } from '@angular/core'
3import { AutoCompleteModule } from 'primeng/autocomplete' 3import { AutoCompleteModule } from 'primeng/autocomplete'
4import { InputSwitchModule } from 'primeng/inputswitch'
4import { SharedModule } from '../shared' 5import { SharedModule } from '../shared'
5import { MyAccountRoutingModule } from './my-account-routing.module' 6import { MyAccountRoutingModule } from './my-account-routing.module'
6import { MyAccountChangePasswordComponent } from './my-account-settings/my-account-change-password/my-account-change-password.component' 7import { MyAccountChangePasswordComponent } from './my-account-settings/my-account-change-password/my-account-change-password.component'
@@ -21,6 +22,9 @@ import { MyAccountDangerZoneComponent } from '@app/+my-account/my-account-settin
21import { MyAccountSubscriptionsComponent } from '@app/+my-account/my-account-subscriptions/my-account-subscriptions.component' 22import { MyAccountSubscriptionsComponent } from '@app/+my-account/my-account-subscriptions/my-account-subscriptions.component'
22import { MyAccountBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-blocklist.component' 23import { MyAccountBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-blocklist.component'
23import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-server-blocklist.component' 24import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-server-blocklist.component'
25import { MyAccountHistoryComponent } from '@app/+my-account/my-account-history/my-account-history.component'
26import { MyAccountNotificationsComponent } from '@app/+my-account/my-account-notifications/my-account-notifications.component'
27import { MyAccountNotificationPreferencesComponent } from '@app/+my-account/my-account-settings/my-account-notification-preferences'
24 28
25@NgModule({ 29@NgModule({
26 imports: [ 30 imports: [
@@ -28,7 +32,8 @@ import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-b
28 MyAccountRoutingModule, 32 MyAccountRoutingModule,
29 AutoCompleteModule, 33 AutoCompleteModule,
30 SharedModule, 34 SharedModule,
31 TableModule 35 TableModule,
36 InputSwitchModule
32 ], 37 ],
33 38
34 declarations: [ 39 declarations: [
@@ -49,7 +54,10 @@ import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-b
49 MyAccountDangerZoneComponent, 54 MyAccountDangerZoneComponent,
50 MyAccountSubscriptionsComponent, 55 MyAccountSubscriptionsComponent,
51 MyAccountBlocklistComponent, 56 MyAccountBlocklistComponent,
52 MyAccountServerBlocklistComponent 57 MyAccountServerBlocklistComponent,
58 MyAccountHistoryComponent,
59 MyAccountNotificationsComponent,
60 MyAccountNotificationPreferencesComponent
53 ], 61 ],
54 62
55 exports: [ 63 exports: [
diff --git a/client/src/app/+my-account/shared/actor-avatar-info.component.ts b/client/src/app/+my-account/shared/actor-avatar-info.component.ts
index 54bacc212..72c815a0c 100644
--- a/client/src/app/+my-account/shared/actor-avatar-info.component.ts
+++ b/client/src/app/+my-account/shared/actor-avatar-info.component.ts
@@ -1,8 +1,8 @@
1import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core' 1import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core'
2import { ServerService } from '../../core/server' 2import { ServerService } from '../../core/server'
3import { NotificationsService } from 'angular2-notifications'
4import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 3import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
5import { Account } from '@app/shared/account/account.model' 4import { Account } from '@app/shared/account/account.model'
5import { Notifier } from '@app/core'
6 6
7@Component({ 7@Component({
8 selector: 'my-actor-avatar-info', 8 selector: 'my-actor-avatar-info',
@@ -18,13 +18,13 @@ export class ActorAvatarInfoComponent {
18 18
19 constructor ( 19 constructor (
20 private serverService: ServerService, 20 private serverService: ServerService,
21 private notificationsService: NotificationsService 21 private notifier: Notifier
22 ) {} 22 ) {}
23 23
24 onAvatarChange () { 24 onAvatarChange () {
25 const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ] 25 const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ]
26 if (avatarfile.size > this.maxAvatarSize) { 26 if (avatarfile.size > this.maxAvatarSize) {
27 this.notificationsService.error('Error', 'This image is too large.') 27 this.notifier.error('Error', 'This image is too large.')
28 return 28 return
29 } 29 }
30 30
diff --git a/client/src/app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts b/client/src/app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts
index 995f42ffc..cfd471fa4 100644
--- a/client/src/app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts
+++ b/client/src/app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts
@@ -1,9 +1,8 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { I18n } from '@ngx-translate/i18n-polyfill' 2import { I18n } from '@ngx-translate/i18n-polyfill'
3import { NotificationsService } from 'angular2-notifications' 3import { Notifier, RedirectService } from '@app/core'
4import { ServerService } from '@app/core/server' 4import { ServerService } from '@app/core/server'
5import { RedirectService } from '@app/core' 5import { FormReactive, UserService } from '@app/shared'
6import { UserService, FormReactive } from '@app/shared'
7import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
8import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service' 7import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service'
9 8
@@ -20,7 +19,7 @@ export class VerifyAccountAskSendEmailComponent extends FormReactive implements
20 private userValidatorsService: UserValidatorsService, 19 private userValidatorsService: UserValidatorsService,
21 private userService: UserService, 20 private userService: UserService,
22 private serverService: ServerService, 21 private serverService: ServerService,
23 private notificationsService: NotificationsService, 22 private notifier: Notifier,
24 private redirectService: RedirectService, 23 private redirectService: RedirectService,
25 private i18n: I18n 24 private i18n: I18n
26 ) { 25 ) {
@@ -46,12 +45,12 @@ export class VerifyAccountAskSendEmailComponent extends FormReactive implements
46 'An email with verification link will be sent to {{email}}.', 45 'An email with verification link will be sent to {{email}}.',
47 { email } 46 { email }
48 ) 47 )
49 this.notificationsService.success(this.i18n('Success'), message) 48 this.notifier.success(message)
50 this.redirectService.redirectToHomepage() 49 this.redirectService.redirectToHomepage()
51 }, 50 },
52 51
53 err => { 52 err => {
54 this.notificationsService.error(this.i18n('Error'), err.message) 53 this.notifier.error(err.message)
55 } 54 }
56 ) 55 )
57 } 56 }
diff --git a/client/src/app/+verify-account/verify-account-email/verify-account-email.component.html b/client/src/app/+verify-account/verify-account-email/verify-account-email.component.html
index 30ace5e10..a83d4a3c2 100644
--- a/client/src/app/+verify-account/verify-account-email/verify-account-email.component.html
+++ b/client/src/app/+verify-account/verify-account-email/verify-account-email.component.html
@@ -9,7 +9,7 @@
9 <ng-template #verificationError> 9 <ng-template #verificationError>
10 <div> 10 <div>
11 <span i18n>An error occurred. </span> 11 <span i18n>An error occurred. </span>
12 <a i18n routerLink="/verify-account/ask-email">Request new verification email.</a> 12 <a i18n routerLink="/verify-account/ask-send-email">Request new verification email.</a>
13 </div> 13 </div>
14 </ng-template> 14 </ng-template>
15</div> 15</div>
diff --git a/client/src/app/+verify-account/verify-account-email/verify-account-email.component.ts b/client/src/app/+verify-account/verify-account-email/verify-account-email.component.ts
index e4a5522c8..f9ecf664b 100644
--- a/client/src/app/+verify-account/verify-account-email/verify-account-email.component.ts
+++ b/client/src/app/+verify-account/verify-account-email/verify-account-email.component.ts
@@ -1,7 +1,7 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { NotificationsService } from 'angular2-notifications' 4import { Notifier } from '@app/core'
5import { UserService } from '@app/shared' 5import { UserService } from '@app/shared'
6 6
7@Component({ 7@Component({
@@ -17,7 +17,7 @@ export class VerifyAccountEmailComponent implements OnInit {
17 17
18 constructor ( 18 constructor (
19 private userService: UserService, 19 private userService: UserService,
20 private notificationsService: NotificationsService, 20 private notifier: Notifier,
21 private router: Router, 21 private router: Router,
22 private route: ActivatedRoute, 22 private route: ActivatedRoute,
23 private i18n: I18n 23 private i18n: I18n
@@ -29,7 +29,7 @@ export class VerifyAccountEmailComponent implements OnInit {
29 this.verificationString = this.route.snapshot.queryParams['verificationString'] 29 this.verificationString = this.route.snapshot.queryParams['verificationString']
30 30
31 if (!this.userId || !this.verificationString) { 31 if (!this.userId || !this.verificationString) {
32 this.notificationsService.error(this.i18n('Error'), this.i18n('Unable to find user id or verification string.')) 32 this.notifier.error(this.i18n('Unable to find user id or verification string.'))
33 } else { 33 } else {
34 this.verifyEmail() 34 this.verifyEmail()
35 } 35 }
@@ -46,7 +46,7 @@ export class VerifyAccountEmailComponent implements OnInit {
46 }, 46 },
47 47
48 err => { 48 err => {
49 this.notificationsService.error(this.i18n('Error'), err.message) 49 this.notifier.error(err.message)
50 } 50 }
51 ) 51 )
52 } 52 }
diff --git a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts
index ea7b0e118..895b19064 100644
--- a/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts
+++ b/client/src/app/+video-channels/video-channel-about/video-channel-about.component.ts
@@ -3,7 +3,7 @@ import { VideoChannelService } from '@app/shared/video-channel/video-channel.ser
3import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 3import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { Subscription } from 'rxjs' 5import { Subscription } from 'rxjs'
6import { MarkdownService } from '@app/videos/shared' 6import { MarkdownService } from '@app/shared/renderer'
7 7
8@Component({ 8@Component({
9 selector: 'my-video-channel-about', 9 selector: 'my-video-channel-about',
diff --git a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts
index 1f0744fb1..dea378a6e 100644
--- a/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts
+++ b/client/src/app/+video-channels/video-channel-videos/video-channel-videos.component.ts
@@ -2,7 +2,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { Location } from '@angular/common' 3import { Location } from '@angular/common'
4import { immutableAssign } from '@app/shared/misc/utils' 4import { immutableAssign } from '@app/shared/misc/utils'
5import { NotificationsService } from 'angular2-notifications'
6import { AuthService } from '../../core/auth' 5import { AuthService } from '../../core/auth'
7import { ConfirmService } from '../../core/confirm' 6import { ConfirmService } from '../../core/confirm'
8import { AbstractVideoList } from '../../shared/video/abstract-video-list' 7import { AbstractVideoList } from '../../shared/video/abstract-video-list'
@@ -13,6 +12,7 @@ import { tap } from 'rxjs/operators'
13import { I18n } from '@ngx-translate/i18n-polyfill' 12import { I18n } from '@ngx-translate/i18n-polyfill'
14import { Subscription } from 'rxjs' 13import { Subscription } from 'rxjs'
15import { ScreenService } from '@app/shared/misc/screen.service' 14import { ScreenService } from '@app/shared/misc/screen.service'
15import { Notifier } from '@app/core'
16 16
17@Component({ 17@Component({
18 selector: 'my-video-channel-videos', 18 selector: 'my-video-channel-videos',
@@ -35,7 +35,7 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On
35 protected router: Router, 35 protected router: Router,
36 protected route: ActivatedRoute, 36 protected route: ActivatedRoute,
37 protected authService: AuthService, 37 protected authService: AuthService,
38 protected notificationsService: NotificationsService, 38 protected notifier: Notifier,
39 protected confirmService: ConfirmService, 39 protected confirmService: ConfirmService,
40 protected location: Location, 40 protected location: Location,
41 protected screenService: ScreenService, 41 protected screenService: ScreenService,
@@ -55,7 +55,7 @@ export class VideoChannelVideosComponent extends AbstractVideoList implements On
55 this.videoChannelSub = this.videoChannelService.videoChannelLoaded 55 this.videoChannelSub = this.videoChannelService.videoChannelLoaded
56 .subscribe(videoChannel => { 56 .subscribe(videoChannel => {
57 this.videoChannel = videoChannel 57 this.videoChannel = videoChannel
58 this.currentRoute = '/video-channels/' + this.videoChannel.uuid + '/videos' 58 this.currentRoute = '/video-channels/' + this.videoChannel.nameWithHost + '/videos'
59 59
60 this.reloadVideos() 60 this.reloadVideos()
61 this.generateSyndicationList() 61 this.generateSyndicationList()
diff --git a/client/src/app/+video-channels/video-channels-routing.module.ts b/client/src/app/+video-channels/video-channels-routing.module.ts
index 935578d2a..3ac3533d9 100644
--- a/client/src/app/+video-channels/video-channels-routing.module.ts
+++ b/client/src/app/+video-channels/video-channels-routing.module.ts
@@ -7,7 +7,7 @@ import { VideoChannelAboutComponent } from './video-channel-about/video-channel-
7 7
8const videoChannelsRoutes: Routes = [ 8const videoChannelsRoutes: Routes = [
9 { 9 {
10 path: ':videoChannelId', 10 path: ':videoChannelName',
11 component: VideoChannelsComponent, 11 component: VideoChannelsComponent,
12 canActivateChild: [ MetaGuard ], 12 canActivateChild: [ MetaGuard ],
13 children: [ 13 children: [
diff --git a/client/src/app/+video-channels/video-channels.component.ts b/client/src/app/+video-channels/video-channels.component.ts
index 0c5c814c7..41ff82e98 100644
--- a/client/src/app/+video-channels/video-channels.component.ts
+++ b/client/src/app/+video-channels/video-channels.component.ts
@@ -34,9 +34,9 @@ export class VideoChannelsComponent implements OnInit, OnDestroy {
34 ngOnInit () { 34 ngOnInit () {
35 this.routeSub = this.route.params 35 this.routeSub = this.route.params
36 .pipe( 36 .pipe(
37 map(params => params[ 'videoChannelId' ]), 37 map(params => params[ 'videoChannelName' ]),
38 distinctUntilChanged(), 38 distinctUntilChanged(),
39 switchMap(videoChannelId => this.videoChannelService.getVideoChannel(videoChannelId)), 39 switchMap(videoChannelName => this.videoChannelService.getVideoChannel(videoChannelName)),
40 catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 404 ])) 40 catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 404 ]))
41 ) 41 )
42 .subscribe(videoChannel => this.videoChannel = videoChannel) 42 .subscribe(videoChannel => this.videoChannel = videoChannel)
diff --git a/client/src/app/app-routing.module.ts b/client/src/app/app-routing.module.ts
index 545d6aeda..cff37a7d6 100644
--- a/client/src/app/app-routing.module.ts
+++ b/client/src/app/app-routing.module.ts
@@ -43,7 +43,8 @@ const routes: Routes = [
43 imports: [ 43 imports: [
44 RouterModule.forRoot(routes, { 44 RouterModule.forRoot(routes, {
45 useHash: Boolean(history.pushState) === false, 45 useHash: Boolean(history.pushState) === false,
46 preloadingStrategy: PreloadSelectedModulesList 46 preloadingStrategy: PreloadSelectedModulesList,
47 anchorScrolling: 'enabled'
47 }) 48 })
48 ], 49 ],
49 providers: [ 50 providers: [
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html
index 03f7e88ed..d398d4f35 100644
--- a/client/src/app/app.component.html
+++ b/client/src/app/app.component.html
@@ -30,12 +30,27 @@
30 30
31 <footer class="row"> 31 <footer class="row">
32 <a href="https://joinpeertube.org" title="PeerTube website" target="_blank" rel="noopener noreferrer">PeerTube v{{ serverVersion }}{{ serverCommit }}</a>&nbsp;-&nbsp; 32 <a href="https://joinpeertube.org" title="PeerTube website" target="_blank" rel="noopener noreferrer">PeerTube v{{ serverVersion }}{{ serverCommit }}</a>&nbsp;-&nbsp;
33 <a href="https://github.com/Chocobozzz/PeerTube/blob/develop/LICENSE" title="PeerTube license" target="_blank" rel="noopener noreferrer">CopyLeft 2015-2018</a> 33 <a href="https://github.com/Chocobozzz/PeerTube/blob/develop/LICENSE" title="PeerTube license" target="_blank" rel="noopener noreferrer">CopyLeft 2015-2019</a>
34 </footer> 34 </footer>
35 </div> 35 </div>
36 </div> 36 </div>
37</div> 37</div>
38 38
39<ngx-loading-bar [includeSpinner]="false"></ngx-loading-bar> 39<ngx-loading-bar [includeSpinner]="false"></ngx-loading-bar>
40
40<my-confirm></my-confirm> 41<my-confirm></my-confirm>
41<simple-notifications [options]="notificationOptions"></simple-notifications> 42
43<p-toast position="bottom-right">
44 <ng-template let-message pTemplate="message">
45 <div class="notification-block">
46 <div class="message">
47 <h3>{{ message.summary }}</h3>
48 <p>{{ message.detail }}</p>
49 </div>
50
51 <span *ngIf="message.severity === 'success'" class="glyphicon glyphicon-ok"></span>
52 <span *ngIf="message.severity === 'info'" class="glyphicon glyphicon-info-sign"></span>
53 <span *ngIf="message.severity === 'error'" class="glyphicon glyphicon-remove"></span>
54 </div>
55 </ng-template>
56</p-toast>
diff --git a/client/src/app/app.component.scss b/client/src/app/app.component.scss
index b51a81eb1..881f3ff31 100644
--- a/client/src/app/app.component.scss
+++ b/client/src/app/app.component.scss
@@ -91,8 +91,3 @@ footer {
91 height: $footer-height; 91 height: $footer-height;
92 justify-content: center; 92 justify-content: center;
93} 93}
94
95simple-notifications {
96 position: relative;
97 z-index: 1500;
98}
diff --git a/client/src/app/app.component.ts b/client/src/app/app.component.ts
index dc4d0bf6a..7583fdee8 100644
--- a/client/src/app/app.component.ts
+++ b/client/src/app/app.component.ts
@@ -15,19 +15,6 @@ import { fromEvent } from 'rxjs'
15 styleUrls: [ './app.component.scss' ] 15 styleUrls: [ './app.component.scss' ]
16}) 16})
17export class AppComponent implements OnInit { 17export class AppComponent implements OnInit {
18 notificationOptions = {
19 timeOut: 5000,
20 lastOnBottom: true,
21 clickToClose: true,
22 maxLength: 0,
23 maxStack: 7,
24 showProgressBar: false,
25 pauseOnHover: false,
26 preventDuplicates: false,
27 preventLastDuplicates: 'visible',
28 rtl: false
29 }
30
31 isMenuDisplayed = true 18 isMenuDisplayed = true
32 isMenuChangedByUser = false 19 isMenuChangedByUser = false
33 20
diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts
index 371199442..0bbc2e08b 100644
--- a/client/src/app/app.module.ts
+++ b/client/src/app/app.module.ts
@@ -12,13 +12,12 @@ import { AppComponent } from './app.component'
12import { CoreModule } from './core' 12import { CoreModule } from './core'
13import { HeaderComponent } from './header' 13import { HeaderComponent } from './header'
14import { LoginModule } from './login' 14import { LoginModule } from './login'
15import { MenuComponent } from './menu' 15import { AvatarNotificationComponent, LanguageChooserComponent, MenuComponent } from './menu'
16import { SharedModule } from './shared' 16import { SharedModule } from './shared'
17import { SignupModule } from './signup' 17import { SignupModule } from './signup'
18import { VideosModule } from './videos' 18import { VideosModule } from './videos'
19import { buildFileLocale, getCompleteLocale, isDefaultLocale } from '../../../shared/models/i18n' 19import { buildFileLocale, getCompleteLocale, isDefaultLocale } from '../../../shared/models/i18n'
20import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils' 20import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils'
21import { LanguageChooserComponent } from '@app/menu/language-chooser.component'
22import { SearchModule } from '@app/search' 21import { SearchModule } from '@app/search'
23 22
24export function metaFactory (serverService: ServerService): MetaLoader { 23export function metaFactory (serverService: ServerService): MetaLoader {
@@ -40,6 +39,7 @@ export function metaFactory (serverService: ServerService): MetaLoader {
40 39
41 MenuComponent, 40 MenuComponent,
42 LanguageChooserComponent, 41 LanguageChooserComponent,
42 AvatarNotificationComponent,
43 HeaderComponent 43 HeaderComponent
44 ], 44 ],
45 imports: [ 45 imports: [
diff --git a/client/src/app/core/auth/auth-user.model.ts b/client/src/app/core/auth/auth-user.model.ts
index acd13d9c5..abb11fdc2 100644
--- a/client/src/app/core/auth/auth-user.model.ts
+++ b/client/src/app/core/auth/auth-user.model.ts
@@ -1,8 +1,9 @@
1import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' 1import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
2import { UserRight } from '../../../../../shared/models/users/user-right.enum' 2import { UserRight } from '../../../../../shared/models/users/user-right.enum'
3import { User as ServerUserModel } from '../../../../../shared/models/users/user.model'
3// Do not use the barrel (dependency loop) 4// Do not use the barrel (dependency loop)
4import { hasUserRight, UserRole } from '../../../../../shared/models/users/user-role' 5import { hasUserRight, UserRole } from '../../../../../shared/models/users/user-role'
5import { User, UserConstructorHash } from '../../shared/users/user.model' 6import { User } from '../../shared/users/user.model'
6import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type' 7import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type'
7 8
8export type TokenOptions = { 9export type TokenOptions = {
@@ -70,6 +71,7 @@ export class AuthUser extends User {
70 ID: 'id', 71 ID: 'id',
71 ROLE: 'role', 72 ROLE: 'role',
72 EMAIL: 'email', 73 EMAIL: 'email',
74 VIDEOS_HISTORY_ENABLED: 'videos-history-enabled',
73 USERNAME: 'username', 75 USERNAME: 'username',
74 NSFW_POLICY: 'nsfw_policy', 76 NSFW_POLICY: 'nsfw_policy',
75 WEBTORRENT_ENABLED: 'peertube-videojs-' + 'webtorrent_enabled', 77 WEBTORRENT_ENABLED: 'peertube-videojs-' + 'webtorrent_enabled',
@@ -89,7 +91,8 @@ export class AuthUser extends User {
89 role: parseInt(peertubeLocalStorage.getItem(this.KEYS.ROLE), 10) as UserRole, 91 role: parseInt(peertubeLocalStorage.getItem(this.KEYS.ROLE), 10) as UserRole,
90 nsfwPolicy: peertubeLocalStorage.getItem(this.KEYS.NSFW_POLICY) as NSFWPolicyType, 92 nsfwPolicy: peertubeLocalStorage.getItem(this.KEYS.NSFW_POLICY) as NSFWPolicyType,
91 webTorrentEnabled: peertubeLocalStorage.getItem(this.KEYS.WEBTORRENT_ENABLED) === 'true', 93 webTorrentEnabled: peertubeLocalStorage.getItem(this.KEYS.WEBTORRENT_ENABLED) === 'true',
92 autoPlayVideo: peertubeLocalStorage.getItem(this.KEYS.AUTO_PLAY_VIDEO) === 'true' 94 autoPlayVideo: peertubeLocalStorage.getItem(this.KEYS.AUTO_PLAY_VIDEO) === 'true',
95 videosHistoryEnabled: peertubeLocalStorage.getItem(this.KEYS.VIDEOS_HISTORY_ENABLED) === 'true'
93 }, 96 },
94 Tokens.load() 97 Tokens.load()
95 ) 98 )
@@ -104,12 +107,13 @@ export class AuthUser extends User {
104 peertubeLocalStorage.removeItem(this.KEYS.ROLE) 107 peertubeLocalStorage.removeItem(this.KEYS.ROLE)
105 peertubeLocalStorage.removeItem(this.KEYS.NSFW_POLICY) 108 peertubeLocalStorage.removeItem(this.KEYS.NSFW_POLICY)
106 peertubeLocalStorage.removeItem(this.KEYS.WEBTORRENT_ENABLED) 109 peertubeLocalStorage.removeItem(this.KEYS.WEBTORRENT_ENABLED)
110 peertubeLocalStorage.removeItem(this.KEYS.VIDEOS_HISTORY_ENABLED)
107 peertubeLocalStorage.removeItem(this.KEYS.AUTO_PLAY_VIDEO) 111 peertubeLocalStorage.removeItem(this.KEYS.AUTO_PLAY_VIDEO)
108 peertubeLocalStorage.removeItem(this.KEYS.EMAIL) 112 peertubeLocalStorage.removeItem(this.KEYS.EMAIL)
109 Tokens.flush() 113 Tokens.flush()
110 } 114 }
111 115
112 constructor (userHash: UserConstructorHash, hashTokens: TokenOptions) { 116 constructor (userHash: Partial<ServerUserModel>, hashTokens: TokenOptions) {
113 super(userHash) 117 super(userHash)
114 this.tokens = new Tokens(hashTokens) 118 this.tokens = new Tokens(hashTokens)
115 } 119 }
diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts
index 443772c9e..eaa822e0f 100644
--- a/client/src/app/core/auth/auth.service.ts
+++ b/client/src/app/core/auth/auth.service.ts
@@ -3,18 +3,18 @@ import { catchError, map, mergeMap, share, tap } from 'rxjs/operators'
3import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http' 3import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'
4import { Injectable } from '@angular/core' 4import { Injectable } from '@angular/core'
5import { Router } from '@angular/router' 5import { Router } from '@angular/router'
6import { NotificationsService } from 'angular2-notifications' 6import { Notifier } from '@app/core/notification/notifier.service'
7import { OAuthClientLocal, User as UserServerModel, UserRefreshToken } from '../../../../../shared' 7import { OAuthClientLocal, User as UserServerModel, UserRefreshToken } from '../../../../../shared'
8import { User } from '../../../../../shared/models/users' 8import { User } from '../../../../../shared/models/users'
9import { UserLogin } from '../../../../../shared/models/users/user-login.model' 9import { UserLogin } from '../../../../../shared/models/users/user-login.model'
10import { environment } from '../../../environments/environment' 10import { environment } from '../../../environments/environment'
11import { RestExtractor } from '../../shared/rest' 11import { RestExtractor } from '../../shared/rest/rest-extractor.service'
12import { AuthStatus } from './auth-status.model' 12import { AuthStatus } from './auth-status.model'
13import { AuthUser } from './auth-user.model' 13import { AuthUser } from './auth-user.model'
14import { objectToUrlEncoded } from '@app/shared/misc/utils' 14import { objectToUrlEncoded } from '@app/shared/misc/utils'
15import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' 15import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
16import { I18n } from '@ngx-translate/i18n-polyfill' 16import { I18n } from '@ngx-translate/i18n-polyfill'
17import { HotkeysService, Hotkey } from 'angular2-hotkeys' 17import { Hotkey, HotkeysService } from 'angular2-hotkeys'
18 18
19interface UserLoginWithUsername extends UserLogin { 19interface UserLoginWithUsername extends UserLogin {
20 access_token: string 20 access_token: string
@@ -38,7 +38,6 @@ export class AuthService {
38 loginChangedSource: Observable<AuthStatus> 38 loginChangedSource: Observable<AuthStatus>
39 userInformationLoaded = new ReplaySubject<boolean>(1) 39 userInformationLoaded = new ReplaySubject<boolean>(1)
40 hotkeys: Hotkey[] 40 hotkeys: Hotkey[]
41 redirectUrl: string
42 41
43 private clientId: string = peertubeLocalStorage.getItem(AuthService.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_ID) 42 private clientId: string = peertubeLocalStorage.getItem(AuthService.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_ID)
44 private clientSecret: string = peertubeLocalStorage.getItem(AuthService.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_SECRET) 43 private clientSecret: string = peertubeLocalStorage.getItem(AuthService.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_SECRET)
@@ -48,7 +47,7 @@ export class AuthService {
48 47
49 constructor ( 48 constructor (
50 private http: HttpClient, 49 private http: HttpClient,
51 private notificationsService: NotificationsService, 50 private notifier: Notifier,
52 private hotkeysService: HotkeysService, 51 private hotkeysService: HotkeysService,
53 private restExtractor: RestExtractor, 52 private restExtractor: RestExtractor,
54 private router: Router, 53 private router: Router,
@@ -106,9 +105,8 @@ export class AuthService {
106 ) 105 )
107 } 106 }
108 107
109 // We put a bigger timeout 108 // We put a bigger timeout: this is an important message
110 // This is an important message 109 this.notifier.error(errorMessage, this.i18n('Error'), 7000)
111 this.notificationsService.error(this.i18n('Error'), errorMessage, { timeOut: 7000 })
112 } 110 }
113 ) 111 )
114 } 112 }
@@ -178,8 +176,6 @@ export class AuthService {
178 this.setStatus(AuthStatus.LoggedOut) 176 this.setStatus(AuthStatus.LoggedOut)
179 177
180 this.hotkeysService.remove(this.hotkeys) 178 this.hotkeysService.remove(this.hotkeys)
181
182 this.redirectUrl = null
183 } 179 }
184 180
185 refreshAccessToken () { 181 refreshAccessToken () {
diff --git a/client/src/app/core/auth/index.ts b/client/src/app/core/auth/index.ts
index bc7bfec0e..8e5caa7ed 100644
--- a/client/src/app/core/auth/index.ts
+++ b/client/src/app/core/auth/index.ts
@@ -1,4 +1,3 @@
1export * from './auth-status.model' 1export * from './auth-status.model'
2export * from './auth-user.model' 2export * from './auth-user.model'
3export * from './auth.service' 3export * from './auth.service'
4export * from '../routing/login-guard.service'
diff --git a/client/src/app/core/confirm/index.ts b/client/src/app/core/confirm/index.ts
index 44aabfc13..aca591e1a 100644
--- a/client/src/app/core/confirm/index.ts
+++ b/client/src/app/core/confirm/index.ts
@@ -1,2 +1 @@
1export * from './confirm.component'
2export * from './confirm.service' export * from './confirm.service'
diff --git a/client/src/app/core/core.module.ts b/client/src/app/core/core.module.ts
index df2ec696d..4ef3b1e73 100644
--- a/client/src/app/core/core.module.ts
+++ b/client/src/app/core/core.module.ts
@@ -7,16 +7,18 @@ import { LoadingBarModule } from '@ngx-loading-bar/core'
7import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client' 7import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client'
8import { LoadingBarRouterModule } from '@ngx-loading-bar/router' 8import { LoadingBarRouterModule } from '@ngx-loading-bar/router'
9 9
10import { SimpleNotificationsModule } from 'angular2-notifications'
11
12import { AuthService } from './auth' 10import { AuthService } from './auth'
13import { ConfirmComponent, ConfirmService } from './confirm' 11import { ConfirmService } from './confirm'
14import { throwIfAlreadyLoaded } from './module-import-guard' 12import { throwIfAlreadyLoaded } from './module-import-guard'
15import { LoginGuard, RedirectService, UserRightGuard } from './routing' 13import { LoginGuard, RedirectService, UserRightGuard } from './routing'
16import { ServerService } from './server' 14import { ServerService } from './server'
17import { ThemeService } from './theme' 15import { ThemeService } from './theme'
18import { HotkeyModule } from 'angular2-hotkeys' 16import { HotkeyModule } from 'angular2-hotkeys'
19import { CheatSheetComponent } from '@app/core/hotkeys' 17import { CheatSheetComponent } from './hotkeys'
18import { ToastModule } from 'primeng/toast'
19import { Notifier } from './notification'
20import { MessageService } from 'primeng/api'
21import { UserNotificationSocket } from '@app/core/notification/user-notification-socket.service'
20 22
21@NgModule({ 23@NgModule({
22 imports: [ 24 imports: [
@@ -25,11 +27,10 @@ import { CheatSheetComponent } from '@app/core/hotkeys'
25 FormsModule, 27 FormsModule,
26 BrowserAnimationsModule, 28 BrowserAnimationsModule,
27 29
28 SimpleNotificationsModule.forRoot(),
29
30 LoadingBarHttpClientModule, 30 LoadingBarHttpClientModule,
31 LoadingBarRouterModule, 31 LoadingBarRouterModule,
32 LoadingBarModule.forRoot(), 32 LoadingBarModule,
33 ToastModule,
33 34
34 HotkeyModule.forRoot({ 35 HotkeyModule.forRoot({
35 cheatSheetCloseEsc: true 36 cheatSheetCloseEsc: true
@@ -37,16 +38,15 @@ import { CheatSheetComponent } from '@app/core/hotkeys'
37 ], 38 ],
38 39
39 declarations: [ 40 declarations: [
40 ConfirmComponent,
41 CheatSheetComponent 41 CheatSheetComponent
42 ], 42 ],
43 43
44 exports: [ 44 exports: [
45 SimpleNotificationsModule,
46 LoadingBarHttpClientModule, 45 LoadingBarHttpClientModule,
47 LoadingBarModule, 46 LoadingBarModule,
48 47
49 ConfirmComponent, 48 ToastModule,
49
50 CheatSheetComponent 50 CheatSheetComponent
51 ], 51 ],
52 52
@@ -57,7 +57,10 @@ import { CheatSheetComponent } from '@app/core/hotkeys'
57 ThemeService, 57 ThemeService,
58 LoginGuard, 58 LoginGuard,
59 UserRightGuard, 59 UserRightGuard,
60 RedirectService 60 RedirectService,
61 Notifier,
62 MessageService,
63 UserNotificationSocket
61 ] 64 ]
62}) 65})
63export class CoreModule { 66export class CoreModule {
diff --git a/client/src/app/core/index.ts b/client/src/app/core/index.ts
index 524589d74..f664aff41 100644
--- a/client/src/app/core/index.ts
+++ b/client/src/app/core/index.ts
@@ -2,6 +2,7 @@ export * from './auth'
2export * from './confirm' 2export * from './confirm'
3export * from './routing' 3export * from './routing'
4export * from './server' 4export * from './server'
5export * from './notification'
5export * from './theme' 6export * from './theme'
6 7
7export * from './core.module' 8export * from './core.module'
diff --git a/client/src/app/core/notification/index.ts b/client/src/app/core/notification/index.ts
new file mode 100644
index 000000000..3e8d9ea65
--- /dev/null
+++ b/client/src/app/core/notification/index.ts
@@ -0,0 +1,2 @@
1export * from './notifier.service'
2export * from './user-notification-socket.service'
diff --git a/client/src/app/core/notification/notifier.service.ts b/client/src/app/core/notification/notifier.service.ts
new file mode 100644
index 000000000..9833c65a0
--- /dev/null
+++ b/client/src/app/core/notification/notifier.service.ts
@@ -0,0 +1,41 @@
1import { Injectable } from '@angular/core'
2import { MessageService } from 'primeng/api'
3import { I18n } from '@ngx-translate/i18n-polyfill'
4
5@Injectable()
6export class Notifier {
7 readonly TIMEOUT = 5000
8
9 constructor (
10 private i18n: I18n,
11 private messageService: MessageService) {
12 }
13
14 info (text: string, title?: string, timeout?: number) {
15 if (!title) title = this.i18n('Info')
16
17 return this.notify('info', text, title, timeout)
18 }
19
20 error (text: string, title?: string, timeout?: number) {
21 if (!title) title = this.i18n('Error')
22
23 return this.notify('error', text, title, timeout)
24 }
25
26 success (text: string, title?: string, timeout?: number) {
27 if (!title) title = this.i18n('Success')
28
29 return this.notify('success', text, title, timeout)
30 }
31
32 private notify (severity: 'success' | 'info' | 'warn' | 'error', text: string, title: string, timeout?: number) {
33 this.messageService.add({
34 severity,
35 summary: title,
36 detail: text,
37 closable: true,
38 life: timeout || this.TIMEOUT
39 })
40 }
41}
diff --git a/client/src/app/core/notification/user-notification-socket.service.ts b/client/src/app/core/notification/user-notification-socket.service.ts
new file mode 100644
index 000000000..f367d9ae4
--- /dev/null
+++ b/client/src/app/core/notification/user-notification-socket.service.ts
@@ -0,0 +1,41 @@
1import { Injectable } from '@angular/core'
2import { environment } from '../../../environments/environment'
3import { UserNotification as UserNotificationServer } from '../../../../../shared'
4import { Subject } from 'rxjs'
5import * as io from 'socket.io-client'
6import { AuthService } from '../auth'
7
8export type NotificationEvent = 'new' | 'read' | 'read-all'
9
10@Injectable()
11export class UserNotificationSocket {
12 private notificationSubject = new Subject<{ type: NotificationEvent, notification?: UserNotificationServer }>()
13
14 private socket: SocketIOClient.Socket
15
16 constructor (
17 private auth: AuthService
18 ) {}
19
20 dispatch (type: NotificationEvent, notification?: UserNotificationServer) {
21 this.notificationSubject.next({ type, notification })
22 }
23
24 getMyNotificationsSocket () {
25 const socket = this.getSocket()
26
27 socket.on('new-notification', (n: UserNotificationServer) => this.dispatch('new', n))
28
29 return this.notificationSubject.asObservable()
30 }
31
32 private getSocket () {
33 if (this.socket) return this.socket
34
35 this.socket = io(environment.apiUrl + '/user-notifications', {
36 query: { accessToken: this.auth.getAccessToken() }
37 })
38
39 return this.socket
40 }
41}
diff --git a/client/src/app/core/routing/login-guard.service.ts b/client/src/app/core/routing/login-guard.service.ts
index 40ff8f505..7b1c37ee8 100644
--- a/client/src/app/core/routing/login-guard.service.ts
+++ b/client/src/app/core/routing/login-guard.service.ts
@@ -1,11 +1,5 @@
1import { Injectable } from '@angular/core' 1import { Injectable } from '@angular/core'
2import { 2import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router, RouterStateSnapshot } from '@angular/router'
3 ActivatedRouteSnapshot,
4 CanActivateChild,
5 RouterStateSnapshot,
6 CanActivate,
7 Router
8} from '@angular/router'
9 3
10import { AuthService } from '../auth/auth.service' 4import { AuthService } from '../auth/auth.service'
11 5
@@ -20,8 +14,6 @@ export class LoginGuard implements CanActivate, CanActivateChild {
20 canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { 14 canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
21 if (this.auth.isLoggedIn() === true) return true 15 if (this.auth.isLoggedIn() === true) return true
22 16
23 this.auth.redirectUrl = state.url
24
25 this.router.navigate([ '/login' ]) 17 this.router.navigate([ '/login' ])
26 return false 18 return false
27 } 19 }
diff --git a/client/src/app/core/routing/redirect.service.ts b/client/src/app/core/routing/redirect.service.ts
index 1881be117..e1db4097b 100644
--- a/client/src/app/core/routing/redirect.service.ts
+++ b/client/src/app/core/routing/redirect.service.ts
@@ -1,5 +1,5 @@
1import { Injectable } from '@angular/core' 1import { Injectable } from '@angular/core'
2import { Router } from '@angular/router' 2import { NavigationEnd, Router } from '@angular/router'
3import { ServerService } from '../server' 3import { ServerService } from '../server'
4 4
5@Injectable() 5@Injectable()
@@ -8,6 +8,9 @@ export class RedirectService {
8 static INIT_DEFAULT_ROUTE = '/videos/trending' 8 static INIT_DEFAULT_ROUTE = '/videos/trending'
9 static DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE 9 static DEFAULT_ROUTE = RedirectService.INIT_DEFAULT_ROUTE
10 10
11 private previousUrl: string
12 private currentUrl: string
13
11 constructor ( 14 constructor (
12 private router: Router, 15 private router: Router,
13 private serverService: ServerService 16 private serverService: ServerService
@@ -18,6 +21,7 @@ export class RedirectService {
18 RedirectService.DEFAULT_ROUTE = config.instance.defaultClientRoute 21 RedirectService.DEFAULT_ROUTE = config.instance.defaultClientRoute
19 } 22 }
20 23
24 // Load default route
21 this.serverService.configLoaded 25 this.serverService.configLoaded
22 .subscribe(() => { 26 .subscribe(() => {
23 const defaultRouteConfig = this.serverService.getConfig().instance.defaultClientRoute 27 const defaultRouteConfig = this.serverService.getConfig().instance.defaultClientRoute
@@ -26,6 +30,21 @@ export class RedirectService {
26 RedirectService.DEFAULT_ROUTE = defaultRouteConfig 30 RedirectService.DEFAULT_ROUTE = defaultRouteConfig
27 } 31 }
28 }) 32 })
33
34 // Track previous url
35 this.currentUrl = this.router.url
36 router.events.subscribe(event => {
37 if (event instanceof NavigationEnd) {
38 this.previousUrl = this.currentUrl
39 this.currentUrl = event.url
40 }
41 })
42 }
43
44 redirectToPreviousRoute () {
45 if (this.previousUrl) return this.router.navigateByUrl(this.previousUrl)
46
47 return this.redirectToHomepage()
29 } 48 }
30 49
31 redirectToHomepage (skipLocationChange = false) { 50 redirectToHomepage (skipLocationChange = false) {
diff --git a/client/src/app/core/routing/user-right-guard.service.ts b/client/src/app/core/routing/user-right-guard.service.ts
index 65d029977..50c3d8c19 100644
--- a/client/src/app/core/routing/user-right-guard.service.ts
+++ b/client/src/app/core/routing/user-right-guard.service.ts
@@ -7,7 +7,7 @@ import {
7 Router 7 Router
8} from '@angular/router' 8} from '@angular/router'
9 9
10import { AuthService } from '../auth' 10import { AuthService } from '../auth/auth.service'
11 11
12@Injectable() 12@Injectable()
13export class UserRightGuard implements CanActivate, CanActivateChild { 13export class UserRightGuard implements CanActivate, CanActivateChild {
diff --git a/client/src/app/core/server/server.service.ts b/client/src/app/core/server/server.service.ts
index da8bd26db..4ae72427b 100644
--- a/client/src/app/core/server/server.service.ts
+++ b/client/src/app/core/server/server.service.ts
@@ -13,6 +13,7 @@ import { sortBy } from '@app/shared/misc/utils'
13 13
14@Injectable() 14@Injectable()
15export class ServerService { 15export class ServerService {
16 private static BASE_SERVER_URL = environment.apiUrl + '/api/v1/server/'
16 private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config/' 17 private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config/'
17 private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/' 18 private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/'
18 private static BASE_LOCALE_URL = environment.apiUrl + '/client/locales/' 19 private static BASE_LOCALE_URL = environment.apiUrl + '/client/locales/'
@@ -37,6 +38,12 @@ export class ServerService {
37 css: '' 38 css: ''
38 } 39 }
39 }, 40 },
41 email: {
42 enabled: false
43 },
44 contactForm: {
45 enabled: false
46 },
40 serverVersion: 'Unknown', 47 serverVersion: 'Unknown',
41 signup: { 48 signup: {
42 allowed: false, 49 allowed: false,
@@ -80,6 +87,11 @@ export class ServerService {
80 enabled: false 87 enabled: false
81 } 88 }
82 } 89 }
90 },
91 trending: {
92 videos: {
93 intervalDays: 0
94 }
83 } 95 }
84 } 96 }
85 private videoCategories: Array<VideoConstant<number>> = [] 97 private videoCategories: Array<VideoConstant<number>> = []
@@ -141,10 +153,6 @@ export class ServerService {
141 return this.videoPrivacies 153 return this.videoPrivacies
142 } 154 }
143 155
144 getAbout () {
145 return this.http.get<About>(ServerService.BASE_CONFIG_URL + '/about')
146 }
147
148 private loadVideoAttributeEnum ( 156 private loadVideoAttributeEnum (
149 attributeName: 'categories' | 'licences' | 'languages' | 'privacies', 157 attributeName: 'categories' | 'licences' | 'languages' | 'privacies',
150 hashToPopulate: VideoConstant<string | number>[], 158 hashToPopulate: VideoConstant<string | number>[],
diff --git a/client/src/app/header/header.component.html b/client/src/app/header/header.component.html
index c23e0c55d..46a87c79c 100644
--- a/client/src/app/header/header.component.html
+++ b/client/src/app/header/header.component.html
@@ -5,6 +5,6 @@
5<span (click)="doSearch()" class="icon icon-search"></span> 5<span (click)="doSearch()" class="icon icon-search"></span>
6 6
7<a class="upload-button" routerLink="/videos/upload"> 7<a class="upload-button" routerLink="/videos/upload">
8 <span class="icon icon-upload"></span> 8 <my-global-icon iconName="upload"></my-global-icon>
9 <span i18n class="upload-button-label">Upload</span> 9 <span i18n class="upload-button-label">Upload</span>
10</a> 10</a>
diff --git a/client/src/app/header/header.component.scss b/client/src/app/header/header.component.scss
index 2f9820665..cea415d9b 100644
--- a/client/src/app/header/header.component.scss
+++ b/client/src/app/header/header.component.scss
@@ -6,6 +6,7 @@
6 padding-left: 10px; 6 padding-left: 10px;
7 margin-right: 15px; 7 margin-right: 15px;
8 padding-right: 40px; // For the search icon 8 padding-right: 40px; // For the search icon
9 font-size: 14px;
9 10
10 &::placeholder { 11 &::placeholder {
11 color: var(--inputPlaceholderColor); 12 color: var(--inputPlaceholderColor);
@@ -40,6 +41,7 @@
40.upload-button { 41.upload-button {
41 @include peertube-button-link; 42 @include peertube-button-link;
42 @include orange-button; 43 @include orange-button;
44 @include button-with-icon(22px, 3px, -1px);
43 45
44 margin-right: 25px; 46 margin-right: 25px;
45 47
@@ -47,15 +49,6 @@
47 margin-right: 0; 49 margin-right: 0;
48 } 50 }
49 51
50 .icon.icon-upload {
51 @include icon(22px);
52
53 background-image: url('../../assets/images/header/upload-white.svg');
54 height: 24px;
55 vertical-align: middle;
56 margin-right: 6px;
57 }
58
59 @media screen and (max-width: 600px) { 52 @media screen and (max-width: 600px) {
60 margin-right: 10px; 53 margin-right: 10px;
61 padding: 0 10px; 54 padding: 0 10px;
diff --git a/client/src/app/login/login.component.html b/client/src/app/login/login.component.html
index 93dbed525..4efe3fb22 100644
--- a/client/src/app/login/login.component.html
+++ b/client/src/app/login/login.component.html
@@ -55,11 +55,17 @@
55<ng-template #forgotPasswordModal> 55<ng-template #forgotPasswordModal>
56 <div class="modal-header"> 56 <div class="modal-header">
57 <h4 i18n class="modal-title">Forgot your password</h4> 57 <h4 i18n class="modal-title">Forgot your password</h4>
58 <span class="close" aria-hidden="true" (click)="hideForgotPasswordModal()"></span> 58
59 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hideForgotPasswordModal()"></my-global-icon>
59 </div> 60 </div>
60 61
61 <div class="modal-body"> 62 <div class="modal-body">
62 <div class="form-group"> 63
64 <div *ngIf="isEmailDisabled()" class="alert alert-danger" i18n>
65 We are sorry, you cannot recover you password because your instance administrator did not configure the PeerTube email system.
66 </div>
67
68 <div class="form-group" [hidden]="isEmailDisabled()">
63 <label i18n for="forgot-password-email">Email</label> 69 <label i18n for="forgot-password-email">Email</label>
64 <input 70 <input
65 type="email" id="forgot-password-email" i18n-placeholder placeholder="Email address" required 71 type="email" id="forgot-password-email" i18n-placeholder placeholder="Email address" required
diff --git a/client/src/app/login/login.component.ts b/client/src/app/login/login.component.ts
index 7553e6456..fc2442c0e 100644
--- a/client/src/app/login/login.component.ts
+++ b/client/src/app/login/login.component.ts
@@ -1,7 +1,6 @@
1import { Component, ElementRef, OnInit, ViewChild } from '@angular/core' 1import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'
2import { RedirectService, ServerService } from '@app/core' 2import { Notifier, RedirectService, ServerService } from '@app/core'
3import { UserService } from '@app/shared' 3import { UserService } from '@app/shared'
4import { NotificationsService } from 'angular2-notifications'
5import { AuthService } from '../core' 4import { AuthService } from '../core'
6import { FormReactive } from '../shared' 5import { FormReactive } from '../shared'
7import { I18n } from '@ngx-translate/i18n-polyfill' 6import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -19,7 +18,6 @@ import { Router } from '@angular/router'
19export class LoginComponent extends FormReactive implements OnInit { 18export class LoginComponent extends FormReactive implements OnInit {
20 @ViewChild('emailInput') input: ElementRef 19 @ViewChild('emailInput') input: ElementRef
21 @ViewChild('forgotPasswordModal') forgotPasswordModal: ElementRef 20 @ViewChild('forgotPasswordModal') forgotPasswordModal: ElementRef
22 @ViewChild('forgotPasswordEmailInput') forgotPasswordEmailInput: ElementRef
23 21
24 error: string = null 22 error: string = null
25 forgotPasswordEmail = '' 23 forgotPasswordEmail = ''
@@ -35,7 +33,7 @@ export class LoginComponent extends FormReactive implements OnInit {
35 private userService: UserService, 33 private userService: UserService,
36 private serverService: ServerService, 34 private serverService: ServerService,
37 private redirectService: RedirectService, 35 private redirectService: RedirectService,
38 private notificationsService: NotificationsService, 36 private notifier: Notifier,
39 private i18n: I18n 37 private i18n: I18n
40 ) { 38 ) {
41 super() 39 super()
@@ -45,6 +43,10 @@ export class LoginComponent extends FormReactive implements OnInit {
45 return this.serverService.getConfig().signup.allowed === true 43 return this.serverService.getConfig().signup.allowed === true
46 } 44 }
47 45
46 isEmailDisabled () {
47 return this.serverService.getConfig().email.enabled === false
48 }
49
48 ngOnInit () { 50 ngOnInit () {
49 this.buildForm({ 51 this.buildForm({
50 username: this.loginValidatorsService.LOGIN_USERNAME, 52 username: this.loginValidatorsService.LOGIN_USERNAME,
@@ -61,7 +63,7 @@ export class LoginComponent extends FormReactive implements OnInit {
61 63
62 this.authService.login(username, password) 64 this.authService.login(username, password)
63 .subscribe( 65 .subscribe(
64 () => this.redirect(), 66 () => this.redirectService.redirectToPreviousRoute(),
65 67
66 err => { 68 err => {
67 if (err.message.indexOf('credentials are invalid') !== -1) this.error = this.i18n('Incorrect username or password.') 69 if (err.message.indexOf('credentials are invalid') !== -1) this.error = this.i18n('Incorrect username or password.')
@@ -71,15 +73,6 @@ export class LoginComponent extends FormReactive implements OnInit {
71 ) 73 )
72 } 74 }
73 75
74 redirect () {
75 const redirect = this.authService.redirectUrl
76 if (redirect) {
77 this.router.navigate([ redirect ])
78 } else {
79 this.redirectService.redirectToHomepage()
80 }
81 }
82
83 askResetPassword () { 76 askResetPassword () {
84 this.userService.askResetPassword(this.forgotPasswordEmail) 77 this.userService.askResetPassword(this.forgotPasswordEmail)
85 .subscribe( 78 .subscribe(
@@ -88,18 +81,14 @@ export class LoginComponent extends FormReactive implements OnInit {
88 'An email with the reset password instructions will be sent to {{email}}.', 81 'An email with the reset password instructions will be sent to {{email}}.',
89 { email: this.forgotPasswordEmail } 82 { email: this.forgotPasswordEmail }
90 ) 83 )
91 this.notificationsService.success(this.i18n('Success'), message) 84 this.notifier.success(message)
92 this.hideForgotPasswordModal() 85 this.hideForgotPasswordModal()
93 }, 86 },
94 87
95 err => this.notificationsService.error(this.i18n('Error'), err.message) 88 err => this.notifier.error(err.message)
96 ) 89 )
97 } 90 }
98 91
99 onForgotPasswordModalShown () {
100 this.forgotPasswordEmailInput.nativeElement.focus()
101 }
102
103 openForgotPasswordModal () { 92 openForgotPasswordModal () {
104 this.openedForgotPasswordModal = this.modalService.open(this.forgotPasswordModal) 93 this.openedForgotPasswordModal = this.modalService.open(this.forgotPasswordModal)
105 } 94 }
diff --git a/client/src/app/menu/avatar-notification.component.html b/client/src/app/menu/avatar-notification.component.html
new file mode 100644
index 000000000..4ef3f0e89
--- /dev/null
+++ b/client/src/app/menu/avatar-notification.component.html
@@ -0,0 +1,23 @@
1<div
2 [ngbPopover]="popContent" autoClose="outside" placement="bottom-left" container="body" popoverClass="popover-notifications"
3 i18n-title title="View your notifications" class="notification-avatar" #popover="ngbPopover"
4>
5 <div *ngIf="unreadNotifications > 0" class="unread-notifications">{{ unreadNotifications }}</div>
6
7 <img [src]="user.accountAvatarUrl" alt="Avatar" />
8</div>
9
10<ng-template #popContent>
11 <div class="notifications-header">
12 <div i18n>Notifications</div>
13
14 <a
15 i18n-title title="Update your notification preferences" class="glyphicon glyphicon-cog"
16 routerLink="/my-account/settings" fragment="notifications"
17 ></a>
18 </div>
19
20 <my-user-notifications [ignoreLoadingBar]="true" [infiniteScroll]="false" itemsPerPage="10"></my-user-notifications>
21
22 <a class="all-notifications" routerLink="/my-account/notifications" i18n>See all your notifications</a>
23</ng-template>
diff --git a/client/src/app/menu/avatar-notification.component.scss b/client/src/app/menu/avatar-notification.component.scss
new file mode 100644
index 000000000..e785db788
--- /dev/null
+++ b/client/src/app/menu/avatar-notification.component.scss
@@ -0,0 +1,91 @@
1@import '_variables';
2@import '_mixins';
3
4/deep/ {
5 .popover-notifications.popover {
6 max-width: none;
7
8 .popover-body {
9 padding: 0;
10 font-size: 14px;
11 font-family: $main-fonts;
12 overflow-y: auto;
13 max-height: 500px;
14 width: 400px;
15 box-shadow: 0 6px 14px rgba(0, 0, 0, 0.30);
16
17 .notifications-header {
18 display: flex;
19 justify-content: space-between;
20
21 background-color: rgba(0, 0, 0, 0.10);
22 align-items: center;
23 padding: 0 10px;
24 font-size: 16px;
25 height: 50px;
26
27 a {
28 @include disable-default-a-behaviour;
29
30 color: rgba(20, 20, 20, 0.5);
31
32 &:hover {
33 color: rgba(20, 20, 20, 0.8);
34 }
35 }
36 }
37
38 .all-notifications {
39 display: flex;
40 align-items: center;
41 justify-content: center;
42 font-weight: $font-semibold;
43 color: var(--mainForegroundColor);
44 padding: 7px 0;
45 }
46 }
47 }
48}
49
50.notification-avatar {
51 cursor: pointer;
52 position: relative;
53
54 img,
55 .unread-notifications {
56 margin-left: 20px;
57 }
58
59 img {
60 @include avatar(34px);
61
62 margin-right: 10px;
63 }
64
65 .unread-notifications {
66 position: absolute;
67 top: -5px;
68 left: -5px;
69
70 display: flex;
71 align-items: center;
72 justify-content: center;
73
74 background-color: var(--mainColor);
75 color: var(#fff);
76 font-size: 10px;
77 font-weight: $font-semibold;
78
79 border-radius: 15px;
80 width: 15px;
81 height: 15px;
82 }
83}
84
85@media screen and (max-width: $mobile-view) {
86 /deep/ {
87 .popover-notifications.popover .popover-body {
88 width: 400px;
89 }
90 }
91}
diff --git a/client/src/app/menu/avatar-notification.component.ts b/client/src/app/menu/avatar-notification.component.ts
new file mode 100644
index 000000000..f1af08096
--- /dev/null
+++ b/client/src/app/menu/avatar-notification.component.ts
@@ -0,0 +1,65 @@
1import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'
2import { User } from '../shared/users/user.model'
3import { UserNotificationService } from '@app/shared/users/user-notification.service'
4import { Subscription } from 'rxjs'
5import { Notifier, UserNotificationSocket } from '@app/core'
6import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
7import { NavigationEnd, Router } from '@angular/router'
8import { filter } from 'rxjs/operators'
9
10@Component({
11 selector: 'my-avatar-notification',
12 templateUrl: './avatar-notification.component.html',
13 styleUrls: [ './avatar-notification.component.scss' ]
14})
15export class AvatarNotificationComponent implements OnInit, OnDestroy {
16 @ViewChild('popover') popover: NgbPopover
17 @Input() user: User
18
19 unreadNotifications = 0
20
21 private notificationSub: Subscription
22 private routeSub: Subscription
23
24 constructor (
25 private userNotificationService: UserNotificationService,
26 private userNotificationSocket: UserNotificationSocket,
27 private notifier: Notifier,
28 private router: Router
29 ) {}
30
31 ngOnInit () {
32 this.userNotificationService.countUnreadNotifications()
33 .subscribe(
34 result => {
35 this.unreadNotifications = Math.min(result, 99) // Limit number to 99
36 this.subscribeToNotifications()
37 },
38
39 err => this.notifier.error(err.message)
40 )
41
42 this.routeSub = this.router.events
43 .pipe(filter(event => event instanceof NavigationEnd))
44 .subscribe(() => this.closePopover())
45 }
46
47 ngOnDestroy () {
48 if (this.notificationSub) this.notificationSub.unsubscribe()
49 if (this.routeSub) this.routeSub.unsubscribe()
50 }
51
52 closePopover () {
53 this.popover.close()
54 }
55
56 private subscribeToNotifications () {
57 this.notificationSub = this.userNotificationSocket.getMyNotificationsSocket()
58 .subscribe(data => {
59 if (data.type === 'new') return this.unreadNotifications++
60 if (data.type === 'read') return this.unreadNotifications--
61 if (data.type === 'read-all') return this.unreadNotifications = 0
62 })
63 }
64
65}
diff --git a/client/src/app/menu/index.ts b/client/src/app/menu/index.ts
index 421271c12..39dbde750 100644
--- a/client/src/app/menu/index.ts
+++ b/client/src/app/menu/index.ts
@@ -1 +1,3 @@
1export * from './language-chooser.component'
2export * from './avatar-notification.component'
1export * from './menu.component' 3export * from './menu.component'
diff --git a/client/src/app/menu/language-chooser.component.html b/client/src/app/menu/language-chooser.component.html
index c37bf2826..a62b33dda 100644
--- a/client/src/app/menu/language-chooser.component.html
+++ b/client/src/app/menu/language-chooser.component.html
@@ -1,9 +1,14 @@
1<ng-template #modal let-hide="close"> 1<ng-template #modal let-hide="close">
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Change the language</h4> 3 <h4 i18n class="modal-title">Change the language</h4>
4 <span class="close" aria-label="Close" role="button" (click)="hide()"></span> 4 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
5 </div> 5 </div>
6 6
7
8 <a i18n class="help-to-translate" target="_blank" rel="noreferrer noopener" href="https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/translation.md">
9 Help to translate PeerTube!
10 </a>
11
7 <div class="modal-body"> 12 <div class="modal-body">
8 <a *ngFor="let lang of languages" [href]="buildLanguageLink(lang)">{{ lang.label }}</a> 13 <a *ngFor="let lang of languages" [href]="buildLanguageLink(lang)">{{ lang.label }}</a>
9 </div> 14 </div>
diff --git a/client/src/app/menu/language-chooser.component.scss b/client/src/app/menu/language-chooser.component.scss
index 944e86f46..72deb3952 100644
--- a/client/src/app/menu/language-chooser.component.scss
+++ b/client/src/app/menu/language-chooser.component.scss
@@ -1,6 +1,11 @@
1@import '_variables'; 1@import '_variables';
2@import '_mixins'; 2@import '_mixins';
3 3
4.help-to-translate {
5 @include peertube-button-link;
6 @include orange-button;
7}
8
4.modal-body { 9.modal-body {
5 text-align: center; 10 text-align: center;
6 11
@@ -9,4 +14,4 @@
9 font-size: 16px; 14 font-size: 16px;
10 margin: 15px; 15 margin: 15px;
11 } 16 }
12} \ No newline at end of file 17}
diff --git a/client/src/app/menu/menu.component.html b/client/src/app/menu/menu.component.html
index e04bdf3d6..aa5bfa9c9 100644
--- a/client/src/app/menu/menu.component.html
+++ b/client/src/app/menu/menu.component.html
@@ -2,9 +2,7 @@
2 <menu> 2 <menu>
3 <div class="top-menu"> 3 <div class="top-menu">
4 <div *ngIf="isLoggedIn" class="logged-in-block"> 4 <div *ngIf="isLoggedIn" class="logged-in-block">
5 <a routerLink="/my-account/settings"> 5 <my-avatar-notification [user]="user"></my-avatar-notification>
6 <img [src]="user.accountAvatarUrl" alt="Avatar" />
7 </a>
8 6
9 <div class="logged-in-info"> 7 <div class="logged-in-info">
10 <a routerLink="/my-account/settings" class="logged-in-username">{{ user.account?.displayName }}</a> 8 <a routerLink="/my-account/settings" class="logged-in-username">{{ user.account?.displayName }}</a>
@@ -97,4 +95,4 @@
97 </menu> 95 </menu>
98</div> 96</div>
99 97
100<my-language-chooser #languageChooserModal></my-language-chooser> \ No newline at end of file 98<my-language-chooser #languageChooserModal></my-language-chooser>
diff --git a/client/src/app/menu/menu.component.scss b/client/src/app/menu/menu.component.scss
index b271ebfd2..f30b89413 100644
--- a/client/src/app/menu/menu.component.scss
+++ b/client/src/app/menu/menu.component.scss
@@ -16,7 +16,7 @@ menu {
16 height: 100%; 16 height: 100%;
17 white-space: nowrap; 17 white-space: nowrap;
18 text-overflow: ellipsis; 18 text-overflow: ellipsis;
19 overflow: hidden; 19 overflow: auto;
20 color: var(--menuForegroundColor); 20 color: var(--menuForegroundColor);
21 display: flex; 21 display: flex;
22 flex-direction: column; 22 flex-direction: column;
@@ -39,13 +39,6 @@ menu {
39 justify-content: center; 39 justify-content: center;
40 margin-bottom: 35px; 40 margin-bottom: 35px;
41 41
42 img {
43 @include avatar(34px);
44
45 margin-left: 20px;
46 margin-right: 10px;
47 }
48
49 .logged-in-info { 42 .logged-in-info {
50 flex-grow: 1; 43 flex-grow: 1;
51 44
@@ -250,7 +243,7 @@ menu {
250 } 243 }
251} 244}
252 245
253@media screen and (max-width: 400px) { 246@media screen and (max-width: $mobile-view) {
254 .menu-wrapper { 247 .menu-wrapper {
255 width: 100% !important; 248 width: 100% !important;
256 } 249 }
diff --git a/client/src/app/reset-password/reset-password.component.ts b/client/src/app/reset-password/reset-password.component.ts
index af1298de6..07b93ee73 100644
--- a/client/src/app/reset-password/reset-password.component.ts
+++ b/client/src/app/reset-password/reset-password.component.ts
@@ -1,8 +1,7 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { UserService, UserValidatorsService } from '@app/shared' 3import { UserService, UserValidatorsService, FormReactive } from '@app/shared'
4import { NotificationsService } from 'angular2-notifications' 4import { Notifier } from '@app/core'
5import { FormReactive } from '../shared'
6import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
7import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
8import { ResetPasswordValidatorsService } from '@app/shared/forms/form-validators/reset-password-validators.service' 7import { ResetPasswordValidatorsService } from '@app/shared/forms/form-validators/reset-password-validators.service'
@@ -22,7 +21,7 @@ export class ResetPasswordComponent extends FormReactive implements OnInit {
22 private resetPasswordValidatorsService: ResetPasswordValidatorsService, 21 private resetPasswordValidatorsService: ResetPasswordValidatorsService,
23 private userValidatorsService: UserValidatorsService, 22 private userValidatorsService: UserValidatorsService,
24 private userService: UserService, 23 private userService: UserService,
25 private notificationsService: NotificationsService, 24 private notifier: Notifier,
26 private router: Router, 25 private router: Router,
27 private route: ActivatedRoute, 26 private route: ActivatedRoute,
28 private i18n: I18n 27 private i18n: I18n
@@ -40,7 +39,7 @@ export class ResetPasswordComponent extends FormReactive implements OnInit {
40 this.verificationString = this.route.snapshot.queryParams['verificationString'] 39 this.verificationString = this.route.snapshot.queryParams['verificationString']
41 40
42 if (!this.userId || !this.verificationString) { 41 if (!this.userId || !this.verificationString) {
43 this.notificationsService.error(this.i18n('Error'), this.i18n('Unable to find user id or verification string.')) 42 this.notifier.error(this.i18n('Unable to find user id or verification string.'))
44 this.router.navigate([ '/' ]) 43 this.router.navigate([ '/' ])
45 } 44 }
46 } 45 }
@@ -49,11 +48,11 @@ export class ResetPasswordComponent extends FormReactive implements OnInit {
49 this.userService.resetPassword(this.userId, this.verificationString, this.form.value.password) 48 this.userService.resetPassword(this.userId, this.verificationString, this.form.value.password)
50 .subscribe( 49 .subscribe(
51 () => { 50 () => {
52 this.notificationsService.success(this.i18n('Success'), this.i18n('Your password has been successfully reset!')) 51 this.notifier.success(this.i18n('Your password has been successfully reset!'))
53 this.router.navigate([ '/login' ]) 52 this.router.navigate([ '/login' ])
54 }, 53 },
55 54
56 err => this.notificationsService.error('Error', err.message) 55 err => this.notifier.error(err.message)
57 ) 56 )
58 } 57 }
59 58
diff --git a/client/src/app/search/search-filters.component.ts b/client/src/app/search/search-filters.component.ts
index 8d7f84ac1..3fdc6df35 100644
--- a/client/src/app/search/search-filters.component.ts
+++ b/client/src/app/search/search-filters.component.ts
@@ -1,10 +1,6 @@
1import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' 1import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
2import { ActivatedRoute } from '@angular/router' 2import { ServerService } from '@app/core'
3import { RedirectService, ServerService } from '@app/core'
4import { NotificationsService } from 'angular2-notifications'
5import { SearchService } from '@app/search/search.service'
6import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
7import { MetaService } from '@ngx-meta/core'
8import { AdvancedSearch } from '@app/search/advanced-search.model' 4import { AdvancedSearch } from '@app/search/advanced-search.model'
9import { VideoConstant } from '../../../../shared' 5import { VideoConstant } from '../../../../shared'
10 6
diff --git a/client/src/app/search/search.component.html b/client/src/app/search/search.component.html
index 3a87ea1de..82a5f0f26 100644
--- a/client/src/app/search/search.component.html
+++ b/client/src/app/search/search.component.html
@@ -48,7 +48,7 @@
48 </div> 48 </div>
49 49
50 <div *ngIf="isVideo(result)" class="entry video"> 50 <div *ngIf="isVideo(result)" class="entry video">
51 <my-video-thumbnail [video]="result"></my-video-thumbnail> 51 <my-video-thumbnail [video]="result" [nsfw]="isVideoBlur(result)"></my-video-thumbnail>
52 52
53 <div class="video-info"> 53 <div class="video-info">
54 <a tabindex="-1" class="video-info-name" [routerLink]="['/videos/watch', result.uuid]" [attr.title]="result.name">{{ result.name }}</a> 54 <a tabindex="-1" class="video-info-name" [routerLink]="['/videos/watch', result.uuid]" [attr.title]="result.name">{{ result.name }}</a>
diff --git a/client/src/app/search/search.component.scss b/client/src/app/search/search.component.scss
index 3e074621b..6de13d276 100644
--- a/client/src/app/search/search.component.scss
+++ b/client/src/app/search/search.component.scss
@@ -87,10 +87,10 @@
87 text-overflow: ellipsis; 87 text-overflow: ellipsis;
88 white-space: nowrap; 88 white-space: nowrap;
89 font-size: 14px; 89 font-size: 14px;
90 color: #585858; 90 color: $grey-foreground-color;
91 91
92 &:hover { 92 &:hover {
93 color: #303030; 93 color: $grey-foreground-hover-color;
94 } 94 }
95 } 95 }
96 } 96 }
diff --git a/client/src/app/search/search.component.ts b/client/src/app/search/search.component.ts
index 3d17e6d96..c4a4b1fde 100644
--- a/client/src/app/search/search.component.ts
+++ b/client/src/app/search/search.component.ts
@@ -1,7 +1,6 @@
1import { Component, OnDestroy, OnInit } from '@angular/core' 1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { AuthService } from '@app/core' 3import { AuthService, Notifier, ServerService } from '@app/core'
4import { NotificationsService } from 'angular2-notifications'
5import { forkJoin, Subscription } from 'rxjs' 4import { forkJoin, Subscription } from 'rxjs'
6import { SearchService } from '@app/search/search.service' 5import { SearchService } from '@app/search/search.service'
7import { ComponentPagination } from '@app/shared/rest/component-pagination.model' 6import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
@@ -40,9 +39,10 @@ export class SearchComponent implements OnInit, OnDestroy {
40 private route: ActivatedRoute, 39 private route: ActivatedRoute,
41 private router: Router, 40 private router: Router,
42 private metaService: MetaService, 41 private metaService: MetaService,
43 private notificationsService: NotificationsService, 42 private notifier: Notifier,
44 private searchService: SearchService, 43 private searchService: SearchService,
45 private authService: AuthService 44 private authService: AuthService,
45 private serverService: ServerService
46 ) { } 46 ) { }
47 47
48 ngOnInit () { 48 ngOnInit () {
@@ -68,7 +68,7 @@ export class SearchComponent implements OnInit, OnDestroy {
68 this.search() 68 this.search()
69 }, 69 },
70 70
71 err => this.notificationsService.error('Error', err.text) 71 err => this.notifier.error(err.text)
72 ) 72 )
73 } 73 }
74 74
@@ -76,6 +76,10 @@ export class SearchComponent implements OnInit, OnDestroy {
76 if (this.subActivatedRoute) this.subActivatedRoute.unsubscribe() 76 if (this.subActivatedRoute) this.subActivatedRoute.unsubscribe()
77 } 77 }
78 78
79 isVideoBlur (video: Video) {
80 return video.isVideoNSFWForUser(this.authService.getUser(), this.serverService.getConfig())
81 }
82
79 isVideoChannel (d: VideoChannel | Video): d is VideoChannel { 83 isVideoChannel (d: VideoChannel | Video): d is VideoChannel {
80 return d instanceof VideoChannel 84 return d instanceof VideoChannel
81 } 85 }
@@ -112,9 +116,7 @@ export class SearchComponent implements OnInit, OnDestroy {
112 this.firstSearch = false 116 this.firstSearch = false
113 }, 117 },
114 118
115 error => { 119 err => this.notifier.error(err.message)
116 this.notificationsService.error(this.i18n('Error'), error.message)
117 }
118 ) 120 )
119 121
120 } 122 }
diff --git a/client/src/app/shared/actor/actor.model.ts b/client/src/app/shared/actor/actor.model.ts
index 811afb449..adecec1fc 100644
--- a/client/src/app/shared/actor/actor.model.ts
+++ b/client/src/app/shared/actor/actor.model.ts
@@ -16,7 +16,7 @@ export abstract class Actor implements ActorServer {
16 16
17 avatarUrl: string 17 avatarUrl: string
18 18
19 static GET_ACTOR_AVATAR_URL (actor: { avatar: Avatar }) { 19 static GET_ACTOR_AVATAR_URL (actor: { avatar?: { path: string } }) {
20 const absoluteAPIUrl = getAbsoluteAPIUrl() 20 const absoluteAPIUrl = getAbsoluteAPIUrl()
21 21
22 if (actor && actor.avatar) return absoluteAPIUrl + actor.avatar.path 22 if (actor && actor.avatar) return absoluteAPIUrl + actor.avatar.path
diff --git a/client/src/app/shared/buttons/action-dropdown.component.html b/client/src/app/shared/buttons/action-dropdown.component.html
index 90651f217..114b1d71f 100644
--- a/client/src/app/shared/buttons/action-dropdown.component.html
+++ b/client/src/app/shared/buttons/action-dropdown.component.html
@@ -3,7 +3,7 @@
3 class="action-button" [ngClass]="{ small: buttonSize === 'small', grey: theme === 'grey', orange: theme === 'orange' }" 3 class="action-button" [ngClass]="{ small: buttonSize === 'small', grey: theme === 'grey', orange: theme === 'orange' }"
4 ngbDropdownToggle role="button" 4 ngbDropdownToggle role="button"
5 > 5 >
6 <span *ngIf="!label" class="icon icon-action"></span> 6 <my-global-icon *ngIf="!label" class="more-icon" iconName="more"></my-global-icon>
7 <span *ngIf="label" class="dropdown-toggle">{{ label }}</span> 7 <span *ngIf="label" class="dropdown-toggle">{{ label }}</span>
8 </div> 8 </div>
9 9
diff --git a/client/src/app/shared/buttons/action-dropdown.component.scss b/client/src/app/shared/buttons/action-dropdown.component.scss
index a4fcceeee..985b2ca88 100644
--- a/client/src/app/shared/buttons/action-dropdown.component.scss
+++ b/client/src/app/shared/buttons/action-dropdown.component.scss
@@ -24,14 +24,11 @@
24 } 24 }
25 25
26 &:hover, &:active, &:focus { 26 &:hover, &:active, &:focus {
27 background-color: $grey-color; 27 background-color: $grey-background-color;
28 } 28 }
29 29
30 .icon-action { 30 .more-icon {
31 @include icon(21px); 31 width: 21px;
32
33 background-image: url('../../../assets/images/video/more.svg');
34 top: -1px;
35 } 32 }
36 33
37 &.small { 34 &.small {
diff --git a/client/src/app/shared/buttons/button.component.html b/client/src/app/shared/buttons/button.component.html
index 87a8daccf..b6df67102 100644
--- a/client/src/app/shared/buttons/button.component.html
+++ b/client/src/app/shared/buttons/button.component.html
@@ -1,4 +1,4 @@
1<span class="action-button" [ngClass]="className" [title]="getTitle()"> 1<span class="action-button" [ngClass]="className" [title]="getTitle()">
2 <span class="icon" [ngClass]="icon"></span> 2 <my-global-icon [iconName]="icon"></my-global-icon>
3 <span class="button-label">{{ label }}</span> 3 <span class="button-label">{{ label }}</span>
4</span> 4</span>
diff --git a/client/src/app/shared/buttons/button.component.scss b/client/src/app/shared/buttons/button.component.scss
index 168102f09..04199a2a9 100644
--- a/client/src/app/shared/buttons/button.component.scss
+++ b/client/src/app/shared/buttons/button.component.scss
@@ -3,41 +3,18 @@
3 3
4.action-button { 4.action-button {
5 @include peertube-button-link; 5 @include peertube-button-link;
6 @include button-with-icon(21px, 0, -2px);
6 7
7 font-size: 15px;
8 font-weight: $font-semibold; 8 font-weight: $font-semibold;
9 color: #585858; 9 color: $grey-foreground-color;
10 background-color: #E5E5E5; 10 background-color: $grey-background-color;
11 11
12 &:hover { 12 &:hover {
13 background-color: #EFEFEF; 13 background-color: $grey-background-hover-color;
14 } 14 }
15 15
16 .icon { 16 my-global-icon {
17 @include icon(21px); 17 @include apply-svg-color($grey-foreground-color);
18
19 position: relative;
20 top: -2px;
21
22 &.icon-edit {
23 background-image: url('../../../assets/images/global/edit-grey.svg');
24 }
25
26 &.icon-delete-grey {
27 background-image: url('../../../assets/images/global/delete-grey.svg');
28 }
29
30 &.icon-im-with-her {
31 background-image: url('../../../assets/images/global/im-with-her.svg');
32 }
33
34 &.icon-tick {
35 background-image: url('../../../assets/images/global/tick.svg');
36 }
37
38 &.icon-cross {
39 background-image: url('../../../assets/images/global/cross.svg');
40 }
41 } 18 }
42} 19}
43 20
diff --git a/client/src/app/shared/buttons/button.component.ts b/client/src/app/shared/buttons/button.component.ts
index 1a1162f09..a91e9c7eb 100644
--- a/client/src/app/shared/buttons/button.component.ts
+++ b/client/src/app/shared/buttons/button.component.ts
@@ -1,4 +1,5 @@
1import { Component, Input } from '@angular/core' 1import { Component, Input } from '@angular/core'
2import { GlobalIconName } from '@app/shared/icons/global-icon.component'
2 3
3@Component({ 4@Component({
4 selector: 'my-button', 5 selector: 'my-button',
@@ -9,7 +10,7 @@ import { Component, Input } from '@angular/core'
9export class ButtonComponent { 10export class ButtonComponent {
10 @Input() label = '' 11 @Input() label = ''
11 @Input() className: string = undefined 12 @Input() className: string = undefined
12 @Input() icon: string = undefined 13 @Input() icon: GlobalIconName = undefined
13 @Input() title: string = undefined 14 @Input() title: string = undefined
14 15
15 getTitle () { 16 getTitle () {
diff --git a/client/src/app/shared/buttons/delete-button.component.html b/client/src/app/shared/buttons/delete-button.component.html
index 6c55d8104..4d12a84c0 100644
--- a/client/src/app/shared/buttons/delete-button.component.html
+++ b/client/src/app/shared/buttons/delete-button.component.html
@@ -1,5 +1,5 @@
1<span class="action-button action-button-delete" [title]="getTitle()" role="button"> 1<span class="action-button action-button-delete" [title]="getTitle()" role="button">
2 <span class="icon icon-delete-grey"></span> 2 <my-global-icon iconName="delete"></my-global-icon>
3 3
4 <span class="button-label" *ngIf="label">{{ label }}</span> 4 <span class="button-label" *ngIf="label">{{ label }}</span>
5 <span class="button-label" i18n *ngIf="!label">Delete</span> 5 <span class="button-label" i18n *ngIf="!label">Delete</span>
diff --git a/client/src/app/shared/buttons/edit-button.component.html b/client/src/app/shared/buttons/edit-button.component.html
index cecb780f3..da3addbae 100644
--- a/client/src/app/shared/buttons/edit-button.component.html
+++ b/client/src/app/shared/buttons/edit-button.component.html
@@ -1,5 +1,5 @@
1<a class="action-button action-button-edit" [routerLink]="routerLink" i18n-title title="Edit"> 1<a class="action-button action-button-edit" [routerLink]="routerLink" i18n-title title="Edit">
2 <span class="icon icon-edit"></span> 2 <my-global-icon iconName="edit"></my-global-icon>
3 3
4 <span class="button-label" *ngIf="label">{{ label }}</span> 4 <span class="button-label" *ngIf="label">{{ label }}</span>
5 <span i18n class="button-label" *ngIf="!label">Edit</span> 5 <span i18n class="button-label" *ngIf="!label">Edit</span>
diff --git a/client/src/app/core/confirm/confirm.component.html b/client/src/app/shared/confirm/confirm.component.html
index 43f0c6190..65df1cd4d 100644
--- a/client/src/app/core/confirm/confirm.component.html
+++ b/client/src/app/shared/confirm/confirm.component.html
@@ -2,7 +2,8 @@
2 2
3 <div class="modal-header"> 3 <div class="modal-header">
4 <h4 class="modal-title">{{ title }}</h4> 4 <h4 class="modal-title">{{ title }}</h4>
5 <span class="close" aria-label="Close" role="button" (click)="dismiss()"></span> 5
6 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="dismiss()"></my-global-icon>
6 </div> 7 </div>
7 8
8 <div class="modal-body" > 9 <div class="modal-body" >
diff --git a/client/src/app/core/confirm/confirm.component.scss b/client/src/app/shared/confirm/confirm.component.scss
index 93dd7926b..93dd7926b 100644
--- a/client/src/app/core/confirm/confirm.component.scss
+++ b/client/src/app/shared/confirm/confirm.component.scss
diff --git a/client/src/app/core/confirm/confirm.component.ts b/client/src/app/shared/confirm/confirm.component.ts
index 5138b7848..63c163da6 100644
--- a/client/src/app/core/confirm/confirm.component.ts
+++ b/client/src/app/shared/confirm/confirm.component.ts
@@ -1,5 +1,5 @@
1import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core' 1import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core'
2import { ConfirmService } from './confirm.service' 2import { ConfirmService } from '@app/core/confirm/confirm.service'
3import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 4import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
5import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' 5import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
diff --git a/client/src/app/shared/forms/form-reactive.ts b/client/src/app/shared/forms/form-reactive.ts
index 0bb7d25e6..b9873af2c 100644
--- a/client/src/app/shared/forms/form-reactive.ts
+++ b/client/src/app/shared/forms/form-reactive.ts
@@ -1,11 +1,9 @@
1import { FormGroup } from '@angular/forms' 1import { FormGroup } from '@angular/forms'
2import { BuildFormArgument, BuildFormDefaultValues, FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 2import { BuildFormArgument, BuildFormDefaultValues, FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
3 3
4export type FormReactiveErrors = { [ id: string ]: string } 4export type FormReactiveErrors = { [ id: string ]: string | FormReactiveErrors }
5export type FormReactiveValidationMessages = { 5export type FormReactiveValidationMessages = {
6 [ id: string ]: { 6 [ id: string ]: { [ name: string ]: string } | FormReactiveValidationMessages
7 [ name: string ]: string
8 }
9} 7}
10 8
11export abstract class FormReactive { 9export abstract class FormReactive {
@@ -13,7 +11,7 @@ export abstract class FormReactive {
13 protected formChanged = false 11 protected formChanged = false
14 12
15 form: FormGroup 13 form: FormGroup
16 formErrors: FormReactiveErrors 14 formErrors: any // To avoid casting in template because of string | FormReactiveErrors
17 validationMessages: FormReactiveValidationMessages 15 validationMessages: FormReactiveValidationMessages
18 16
19 buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) { 17 buildForm (obj: BuildFormArgument, defaultValues: BuildFormDefaultValues = {}) {
@@ -23,29 +21,49 @@ export abstract class FormReactive {
23 this.formErrors = formErrors 21 this.formErrors = formErrors
24 this.validationMessages = validationMessages 22 this.validationMessages = validationMessages
25 23
26 this.form.valueChanges.subscribe(() => this.onValueChanged(false)) 24 this.form.valueChanges.subscribe(() => this.onValueChanged(this.form, this.formErrors, this.validationMessages, false))
25 }
26
27 protected forceCheck () {
28 return this.onValueChanged(this.form, this.formErrors, this.validationMessages, true)
29 }
30
31 protected check () {
32 return this.onValueChanged(this.form, this.formErrors, this.validationMessages, false)
27 } 33 }
28 34
29 protected onValueChanged (forceCheck = false) { 35 private onValueChanged (
30 for (const field in this.formErrors) { 36 form: FormGroup,
37 formErrors: FormReactiveErrors,
38 validationMessages: FormReactiveValidationMessages,
39 forceCheck = false
40 ) {
41 for (const field of Object.keys(formErrors)) {
42 if (formErrors[field] && typeof formErrors[field] === 'object') {
43 this.onValueChanged(
44 form.controls[field] as FormGroup,
45 formErrors[field] as FormReactiveErrors,
46 validationMessages[field] as FormReactiveValidationMessages,
47 forceCheck
48 )
49 continue
50 }
51
31 // clear previous error message (if any) 52 // clear previous error message (if any)
32 this.formErrors[ field ] = '' 53 formErrors[ field ] = ''
33 const control = this.form.get(field) 54 const control = form.get(field)
34 55
35 if (control.dirty) this.formChanged = true 56 if (control.dirty) this.formChanged = true
36 57
37 // Don't care if dirty on force check 58 // Don't care if dirty on force check
38 const isDirty = control.dirty || forceCheck === true 59 const isDirty = control.dirty || forceCheck === true
39 if (control && isDirty && !control.valid) { 60 if (control && isDirty && !control.valid) {
40 const messages = this.validationMessages[ field ] 61 const messages = validationMessages[ field ]
41 for (const key in control.errors) { 62 for (const key in control.errors) {
42 this.formErrors[ field ] += messages[ key ] + ' ' 63 formErrors[ field ] += messages[ key ] + ' '
43 } 64 }
44 } 65 }
45 } 66 }
46 } 67 }
47 68
48 protected forceCheck () {
49 return this.onValueChanged(true)
50 }
51} 69}
diff --git a/client/src/app/shared/forms/form-validators/form-validator.service.ts b/client/src/app/shared/forms/form-validators/form-validator.service.ts
index 19a8bef25..249fdf119 100644
--- a/client/src/app/shared/forms/form-validators/form-validator.service.ts
+++ b/client/src/app/shared/forms/form-validators/form-validator.service.ts
@@ -7,10 +7,10 @@ export type BuildFormValidator = {
7 MESSAGES: { [ name: string ]: string } 7 MESSAGES: { [ name: string ]: string }
8} 8}
9export type BuildFormArgument = { 9export type BuildFormArgument = {
10 [ id: string ]: BuildFormValidator 10 [ id: string ]: BuildFormValidator | BuildFormArgument
11} 11}
12export type BuildFormDefaultValues = { 12export type BuildFormDefaultValues = {
13 [ name: string ]: string | string[] 13 [ name: string ]: string | string[] | BuildFormDefaultValues
14} 14}
15 15
16@Injectable() 16@Injectable()
@@ -29,7 +29,16 @@ export class FormValidatorService {
29 formErrors[name] = '' 29 formErrors[name] = ''
30 30
31 const field = obj[name] 31 const field = obj[name]
32 if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES 32 if (this.isRecursiveField(field)) {
33 const result = this.buildForm(field as BuildFormArgument, defaultValues[name] as BuildFormDefaultValues)
34 group[name] = result.form
35 formErrors[name] = result.formErrors
36 validationMessages[name] = result.validationMessages
37
38 continue
39 }
40
41 if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES as { [ name: string ]: string }
33 42
34 const defaultValue = defaultValues[name] || '' 43 const defaultValue = defaultValues[name] || ''
35 44
@@ -52,13 +61,27 @@ export class FormValidatorService {
52 formErrors[name] = '' 61 formErrors[name] = ''
53 62
54 const field = obj[name] 63 const field = obj[name]
55 if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES 64 if (this.isRecursiveField(field)) {
65 this.updateForm(
66 form[name],
67 formErrors[name] as FormReactiveErrors,
68 validationMessages[name] as FormReactiveValidationMessages,
69 obj[name] as BuildFormArgument,
70 defaultValues[name] as BuildFormDefaultValues
71 )
72 continue
73 }
74
75 if (field && field.MESSAGES) validationMessages[name] = field.MESSAGES as { [ name: string ]: string }
56 76
57 const defaultValue = defaultValues[name] || '' 77 const defaultValue = defaultValues[name] || ''
58 78
59 if (field && field.VALIDATORS) form.addControl(name, new FormControl(defaultValue, field.VALIDATORS)) 79 if (field && field.VALIDATORS) form.addControl(name, new FormControl(defaultValue, field.VALIDATORS as ValidatorFn[]))
60 else form.addControl(name, new FormControl(defaultValue)) 80 else form.addControl(name, new FormControl(defaultValue))
61 } 81 }
62 } 82 }
63 83
84 private isRecursiveField (field: any) {
85 return field && typeof field === 'object' && !field.MESSAGES && !field.VALIDATORS
86 }
64} 87}
diff --git a/client/src/app/shared/forms/form-validators/index.ts b/client/src/app/shared/forms/form-validators/index.ts
index 74e385b3d..fdcbedb71 100644
--- a/client/src/app/shared/forms/form-validators/index.ts
+++ b/client/src/app/shared/forms/form-validators/index.ts
@@ -1,6 +1,7 @@
1export * from './custom-config-validators.service' 1export * from './custom-config-validators.service'
2export * from './form-validator.service' 2export * from './form-validator.service'
3export * from './host' 3export * from './host'
4export * from './instance-validators.service'
4export * from './login-validators.service' 5export * from './login-validators.service'
5export * from './reset-password-validators.service' 6export * from './reset-password-validators.service'
6export * from './user-validators.service' 7export * from './user-validators.service'
diff --git a/client/src/app/shared/forms/form-validators/instance-validators.service.ts b/client/src/app/shared/forms/form-validators/instance-validators.service.ts
new file mode 100644
index 000000000..5bb852858
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/instance-validators.service.ts
@@ -0,0 +1,48 @@
1import { I18n } from '@ngx-translate/i18n-polyfill'
2import { Validators } from '@angular/forms'
3import { BuildFormValidator } from '@app/shared'
4import { Injectable } from '@angular/core'
5
6@Injectable()
7export class InstanceValidatorsService {
8 readonly FROM_EMAIL: BuildFormValidator
9 readonly FROM_NAME: BuildFormValidator
10 readonly BODY: BuildFormValidator
11
12 constructor (private i18n: I18n) {
13
14 this.FROM_EMAIL = {
15 VALIDATORS: [ Validators.required, Validators.email ],
16 MESSAGES: {
17 'required': this.i18n('Email is required.'),
18 'email': this.i18n('Email must be valid.')
19 }
20 }
21
22 this.FROM_NAME = {
23 VALIDATORS: [
24 Validators.required,
25 Validators.minLength(1),
26 Validators.maxLength(120)
27 ],
28 MESSAGES: {
29 'required': this.i18n('Your name is required.'),
30 'minlength': this.i18n('Your name must be at least 1 character long.'),
31 'maxlength': this.i18n('Your name cannot be more than 120 characters long.')
32 }
33 }
34
35 this.BODY = {
36 VALIDATORS: [
37 Validators.required,
38 Validators.minLength(3),
39 Validators.maxLength(5000)
40 ],
41 MESSAGES: {
42 'required': this.i18n('A message is required.'),
43 'minlength': this.i18n('The message must be at least 3 characters long.'),
44 'maxlength': this.i18n('The message cannot be more than 5000 characters long.')
45 }
46 }
47 }
48}
diff --git a/client/src/app/shared/forms/form-validators/user-validators.service.ts b/client/src/app/shared/forms/form-validators/user-validators.service.ts
index d14fa4777..6589b2580 100644
--- a/client/src/app/shared/forms/form-validators/user-validators.service.ts
+++ b/client/src/app/shared/forms/form-validators/user-validators.service.ts
@@ -23,15 +23,15 @@ export class UserValidatorsService {
23 this.USER_USERNAME = { 23 this.USER_USERNAME = {
24 VALIDATORS: [ 24 VALIDATORS: [
25 Validators.required, 25 Validators.required,
26 Validators.minLength(3), 26 Validators.minLength(1),
27 Validators.maxLength(20), 27 Validators.maxLength(50),
28 Validators.pattern(/^[a-z0-9._]+$/) 28 Validators.pattern(/^[a-z0-9][a-z0-9._]*$/)
29 ], 29 ],
30 MESSAGES: { 30 MESSAGES: {
31 'required': this.i18n('Username is required.'), 31 'required': this.i18n('Username is required.'),
32 'minlength': this.i18n('Username must be at least 3 characters long.'), 32 'minlength': this.i18n('Username must be at least 1 character long.'),
33 'maxlength': this.i18n('Username cannot be more than 20 characters long.'), 33 'maxlength': this.i18n('Username cannot be more than 50 characters long.'),
34 'pattern': this.i18n('Username should be only lowercase alphanumeric characters.') 34 'pattern': this.i18n('Username should be lowercase alphanumeric; dots and underscores are allowed.')
35 } 35 }
36 } 36 }
37 37
@@ -88,13 +88,13 @@ export class UserValidatorsService {
88 this.USER_DISPLAY_NAME = { 88 this.USER_DISPLAY_NAME = {
89 VALIDATORS: [ 89 VALIDATORS: [
90 Validators.required, 90 Validators.required,
91 Validators.minLength(3), 91 Validators.minLength(1),
92 Validators.maxLength(120) 92 Validators.maxLength(50)
93 ], 93 ],
94 MESSAGES: { 94 MESSAGES: {
95 'required': this.i18n('Display name is required.'), 95 'required': this.i18n('Display name is required.'),
96 'minlength': this.i18n('Display name must be at least 3 characters long.'), 96 'minlength': this.i18n('Display name must be at least 1 character long.'),
97 'maxlength': this.i18n('Display name cannot be more than 120 characters long.') 97 'maxlength': this.i18n('Display name cannot be more than 50 characters long.')
98 } 98 }
99 } 99 }
100 100
diff --git a/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts b/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts
index 6e9806611..fcc966b84 100644
--- a/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts
+++ b/client/src/app/shared/forms/form-validators/video-abuse-validators.service.ts
@@ -10,20 +10,20 @@ export class VideoAbuseValidatorsService {
10 10
11 constructor (private i18n: I18n) { 11 constructor (private i18n: I18n) {
12 this.VIDEO_ABUSE_REASON = { 12 this.VIDEO_ABUSE_REASON = {
13 VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ], 13 VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ],
14 MESSAGES: { 14 MESSAGES: {
15 'required': this.i18n('Report reason is required.'), 15 'required': this.i18n('Report reason is required.'),
16 'minlength': this.i18n('Report reason must be at least 2 characters long.'), 16 'minlength': this.i18n('Report reason must be at least 2 characters long.'),
17 'maxlength': this.i18n('Report reason cannot be more than 300 characters long.') 17 'maxlength': this.i18n('Report reason cannot be more than 3000 characters long.')
18 } 18 }
19 } 19 }
20 20
21 this.VIDEO_ABUSE_MODERATION_COMMENT = { 21 this.VIDEO_ABUSE_MODERATION_COMMENT = {
22 VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(300) ], 22 VALIDATORS: [ Validators.required, Validators.minLength(2), Validators.maxLength(3000) ],
23 MESSAGES: { 23 MESSAGES: {
24 'required': this.i18n('Moderation comment is required.'), 24 'required': this.i18n('Moderation comment is required.'),
25 'minlength': this.i18n('Moderation comment must be at least 2 characters long.'), 25 'minlength': this.i18n('Moderation comment must be at least 2 characters long.'),
26 'maxlength': this.i18n('Moderation comment cannot be more than 300 characters long.') 26 'maxlength': this.i18n('Moderation comment cannot be more than 3000 characters long.')
27 } 27 }
28 } 28 }
29 } 29 }
diff --git a/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts b/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts
index f62ff65f7..1c519c10a 100644
--- a/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts
+++ b/client/src/app/shared/forms/form-validators/video-channel-validators.service.ts
@@ -14,28 +14,28 @@ export class VideoChannelValidatorsService {
14 this.VIDEO_CHANNEL_NAME = { 14 this.VIDEO_CHANNEL_NAME = {
15 VALIDATORS: [ 15 VALIDATORS: [
16 Validators.required, 16 Validators.required,
17 Validators.minLength(3), 17 Validators.minLength(1),
18 Validators.maxLength(20), 18 Validators.maxLength(50),
19 Validators.pattern(/^[a-z0-9._]+$/) 19 Validators.pattern(/^[a-z0-9][a-z0-9._]*$/)
20 ], 20 ],
21 MESSAGES: { 21 MESSAGES: {
22 'required': this.i18n('Name is required.'), 22 'required': this.i18n('Name is required.'),
23 'minlength': this.i18n('Name must be at least 3 characters long.'), 23 'minlength': this.i18n('Name must be at least 1 character long.'),
24 'maxlength': this.i18n('Name cannot be more than 20 characters long.'), 24 'maxlength': this.i18n('Name cannot be more than 50 characters long.'),
25 'pattern': this.i18n('Name should be only lowercase alphanumeric characters.') 25 'pattern': this.i18n('Name should be lowercase alphanumeric; dots and underscores are allowed.')
26 } 26 }
27 } 27 }
28 28
29 this.VIDEO_CHANNEL_DISPLAY_NAME = { 29 this.VIDEO_CHANNEL_DISPLAY_NAME = {
30 VALIDATORS: [ 30 VALIDATORS: [
31 Validators.required, 31 Validators.required,
32 Validators.minLength(3), 32 Validators.minLength(1),
33 Validators.maxLength(120) 33 Validators.maxLength(50)
34 ], 34 ],
35 MESSAGES: { 35 MESSAGES: {
36 'required': i18n('Display name is required.'), 36 'required': i18n('Display name is required.'),
37 'minlength': i18n('Display name must be at least 3 characters long.'), 37 'minlength': i18n('Display name must be at least 1 character long.'),
38 'maxlength': i18n('Display name cannot be more than 120 characters long.') 38 'maxlength': i18n('Display name cannot be more than 50 characters long.')
39 } 39 }
40 } 40 }
41 41
diff --git a/client/src/app/shared/forms/markdown-textarea.component.ts b/client/src/app/shared/forms/markdown-textarea.component.ts
index b99169ed2..e87aca0d4 100644
--- a/client/src/app/shared/forms/markdown-textarea.component.ts
+++ b/client/src/app/shared/forms/markdown-textarea.component.ts
@@ -1,10 +1,10 @@
1import { debounceTime, distinctUntilChanged } from 'rxjs/operators' 1import { debounceTime, distinctUntilChanged } from 'rxjs/operators'
2import { Component, forwardRef, Input, OnInit } from '@angular/core' 2import { Component, forwardRef, Input, OnInit } from '@angular/core'
3import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' 3import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
4import { MarkdownService } from '@app/videos/shared'
5import { Subject } from 'rxjs' 4import { Subject } from 'rxjs'
6import truncate from 'lodash-es/truncate' 5import truncate from 'lodash-es/truncate'
7import { ScreenService } from '@app/shared/misc/screen.service' 6import { ScreenService } from '@app/shared/misc/screen.service'
7import { MarkdownService } from '@app/shared/renderer'
8 8
9@Component({ 9@Component({
10 selector: 'my-markdown-textarea', 10 selector: 'my-markdown-textarea',
diff --git a/client/src/app/shared/forms/peertube-checkbox.component.html b/client/src/app/shared/forms/peertube-checkbox.component.html
index fb3006b53..7b8bcf601 100644
--- a/client/src/app/shared/forms/peertube-checkbox.component.html
+++ b/client/src/app/shared/forms/peertube-checkbox.component.html
@@ -1,10 +1,10 @@
1<div class="root"> 1<div class="root">
2 <label class="form-group-checkbox"> 2 <label class="form-group-checkbox">
3 <input type="checkbox" [(ngModel)]="checked" (ngModelChange)="onModelChange()" [id]="inputName" [disabled]="isDisabled" /> 3 <input type="checkbox" [(ngModel)]="checked" (ngModelChange)="onModelChange()" [id]="inputName" [disabled]="disabled" />
4 <span role="checkbox" [attr.aria-checked]="checked"></span> 4 <span role="checkbox" [attr.aria-checked]="checked"></span>
5 <span *ngIf="labelText">{{ labelText }}</span> 5 <span *ngIf="labelText">{{ labelText }}</span>
6 <span *ngIf="labelHtml" [innerHTML]="labelHtml"></span> 6 <span *ngIf="labelHtml" [innerHTML]="labelHtml"></span>
7 </label> 7 </label>
8 8
9 <my-help *ngIf="helpHtml" tooltipPlacement="top" helpType="custom" i18n-customHtml [customHtml]="helpHtml"></my-help> 9 <my-help *ngIf="helpHtml" tooltipPlacement="top" helpType="custom" i18n-customHtml [customHtml]="helpHtml"></my-help>
10</div> \ No newline at end of file 10</div>
diff --git a/client/src/app/shared/forms/peertube-checkbox.component.ts b/client/src/app/shared/forms/peertube-checkbox.component.ts
index bbc9904df..c1a6915e8 100644
--- a/client/src/app/shared/forms/peertube-checkbox.component.ts
+++ b/client/src/app/shared/forms/peertube-checkbox.component.ts
@@ -19,8 +19,7 @@ export class PeertubeCheckboxComponent implements ControlValueAccessor {
19 @Input() labelText: string 19 @Input() labelText: string
20 @Input() labelHtml: string 20 @Input() labelHtml: string
21 @Input() helpHtml: string 21 @Input() helpHtml: string
22 22 @Input() disabled = false
23 isDisabled = false
24 23
25 propagateChange = (_: any) => { /* empty */ } 24 propagateChange = (_: any) => { /* empty */ }
26 25
@@ -41,6 +40,6 @@ export class PeertubeCheckboxComponent implements ControlValueAccessor {
41 } 40 }
42 41
43 setDisabledState (isDisabled: boolean) { 42 setDisabledState (isDisabled: boolean) {
44 this.isDisabled = isDisabled 43 this.disabled = isDisabled
45 } 44 }
46} 45}
diff --git a/client/src/app/shared/forms/reactive-file.component.ts b/client/src/app/shared/forms/reactive-file.component.ts
index 8d22aa56c..f60c38e8d 100644
--- a/client/src/app/shared/forms/reactive-file.component.ts
+++ b/client/src/app/shared/forms/reactive-file.component.ts
@@ -1,6 +1,6 @@
1import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core' 1import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core'
2import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' 2import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
3import { NotificationsService } from 'angular2-notifications' 3import { Notifier } from '@app/core'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5 5
6@Component({ 6@Component({
@@ -30,7 +30,7 @@ export class ReactiveFileComponent implements OnInit, ControlValueAccessor {
30 private file: File 30 private file: File
31 31
32 constructor ( 32 constructor (
33 private notificationsService: NotificationsService, 33 private notifier: Notifier,
34 private i18n: I18n 34 private i18n: I18n
35 ) {} 35 ) {}
36 36
@@ -49,7 +49,18 @@ export class ReactiveFileComponent implements OnInit, ControlValueAccessor {
49 const [ file ] = event.target.files 49 const [ file ] = event.target.files
50 50
51 if (file.size > this.maxFileSize) { 51 if (file.size > this.maxFileSize) {
52 this.notificationsService.error(this.i18n('Error'), this.i18n('This file is too large.')) 52 this.notifier.error(this.i18n('This file is too large.'))
53 return
54 }
55
56 const extension = '.' + file.name.split('.').pop()
57 if (this.extensions.includes(extension) === false) {
58 const message = this.i18n(
59 'PeerTube cannot handle this kind of file. Accepted extensions are {{extensions}}.',
60 { extensions: this.allowedExtensionsMessage }
61 )
62 this.notifier.error(message)
63
53 return 64 return
54 } 65 }
55 66
diff --git a/client/src/app/shared/icons/global-icon.component.html b/client/src/app/shared/icons/global-icon.component.html
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/client/src/app/shared/icons/global-icon.component.html
diff --git a/client/src/app/shared/icons/global-icon.component.scss b/client/src/app/shared/icons/global-icon.component.scss
new file mode 100644
index 000000000..6805fb6f7
--- /dev/null
+++ b/client/src/app/shared/icons/global-icon.component.scss
@@ -0,0 +1,4 @@
1/deep/ svg {
2 width: inherit;
3 height: inherit;
4}
diff --git a/client/src/app/shared/icons/global-icon.component.ts b/client/src/app/shared/icons/global-icon.component.ts
new file mode 100644
index 000000000..e8ada0324
--- /dev/null
+++ b/client/src/app/shared/icons/global-icon.component.ts
@@ -0,0 +1,48 @@
1import { Component, ElementRef, Input, OnInit } from '@angular/core'
2
3const icons = {
4 'add': require('../../../assets/images/global/add.html'),
5 'syndication': require('../../../assets/images/global/syndication.html'),
6 'help': require('../../../assets/images/global/help.html'),
7 'sparkle': require('../../../assets/images/global/sparkle.html'),
8 'alert': require('../../../assets/images/global/alert.html'),
9 'cloud-error': require('../../../assets/images/global/cloud-error.html'),
10 'user-add': require('../../../assets/images/global/user-add.html'),
11 'no': require('../../../assets/images/global/no.html'),
12 'cloud-download': require('../../../assets/images/global/cloud-download.html'),
13 'undo': require('../../../assets/images/global/undo.html'),
14 'circle-tick': require('../../../assets/images/global/circle-tick.html'),
15 'cog': require('../../../assets/images/global/cog.html'),
16 'download': require('../../../assets/images/global/download.html'),
17 'edit': require('../../../assets/images/global/edit.html'),
18 'im-with-her': require('../../../assets/images/global/im-with-her.html'),
19 'delete': require('../../../assets/images/global/delete.html'),
20 'cross': require('../../../assets/images/global/cross.html'),
21 'validate': require('../../../assets/images/global/validate.html'),
22 'tick': require('../../../assets/images/global/tick.html'),
23 'dislike': require('../../../assets/images/video/dislike.html'),
24 'heart': require('../../../assets/images/video/heart.html'),
25 'like': require('../../../assets/images/video/like.html'),
26 'more': require('../../../assets/images/video/more.html'),
27 'share': require('../../../assets/images/video/share.html'),
28 'upload': require('../../../assets/images/video/upload.html')
29}
30
31export type GlobalIconName = keyof typeof icons
32
33@Component({
34 selector: 'my-global-icon',
35 template: '',
36 styleUrls: [ './global-icon.component.scss' ]
37})
38export class GlobalIconComponent implements OnInit {
39 @Input() iconName: GlobalIconName
40
41 constructor (private el: ElementRef) {}
42
43 ngOnInit () {
44 const nativeElement = this.el.nativeElement
45
46 nativeElement.innerHTML = icons[this.iconName]
47 }
48}
diff --git a/client/src/app/shared/instance/instance.service.ts b/client/src/app/shared/instance/instance.service.ts
new file mode 100644
index 000000000..61321ecce
--- /dev/null
+++ b/client/src/app/shared/instance/instance.service.ts
@@ -0,0 +1,36 @@
1import { catchError } from 'rxjs/operators'
2import { HttpClient } from '@angular/common/http'
3import { Injectable } from '@angular/core'
4import { environment } from '../../../environments/environment'
5import { RestExtractor, RestService } from '../rest'
6import { About } from '../../../../../shared/models/server'
7
8@Injectable()
9export class InstanceService {
10 private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config'
11 private static BASE_SERVER_URL = environment.apiUrl + '/api/v1/server'
12
13 constructor (
14 private authHttp: HttpClient,
15 private restService: RestService,
16 private restExtractor: RestExtractor
17 ) {
18 }
19
20 getAbout () {
21 return this.authHttp.get<About>(InstanceService.BASE_CONFIG_URL + '/about')
22 .pipe(catchError(res => this.restExtractor.handleError(res)))
23 }
24
25 contactAdministrator (fromEmail: string, fromName: string, message: string) {
26 const body = {
27 fromEmail,
28 fromName,
29 body: message
30 }
31
32 return this.authHttp.post(InstanceService.BASE_SERVER_URL + '/contact', body)
33 .pipe(catchError(res => this.restExtractor.handleError(res)))
34
35 }
36}
diff --git a/client/src/app/shared/menu/top-menu-dropdown.component.html b/client/src/app/shared/menu/top-menu-dropdown.component.html
new file mode 100644
index 000000000..d3c896019
--- /dev/null
+++ b/client/src/app/shared/menu/top-menu-dropdown.component.html
@@ -0,0 +1,21 @@
1<div class="sub-menu">
2 <ng-container *ngFor="let menuEntry of menuEntries">
3
4 <a *ngIf="menuEntry.routerLink" [routerLink]="menuEntry.routerLink" routerLinkActive="active" class="title-page">{{ menuEntry.label }}</a>
5
6 <div *ngIf="!menuEntry.routerLink" ngbDropdown class="parent-entry" #dropdown="ngbDropdown" (mouseleave)="closeDropdownIfHovered(dropdown)">
7 <span
8 (mouseenter)="openDropdownOnHover(dropdown)" [ngClass]="{ active: !!suffixLabels[menuEntry.label] }" ngbDropdownAnchor
9 (click)="dropdownAnchorClicked(dropdown)" role="button" class="title-page"
10 >
11 <ng-container i18n>{{ menuEntry.label }}</ng-container>
12 <ng-container *ngIf="!!suffixLabels[menuEntry.label]"> - {{ suffixLabels[menuEntry.label] }}</ng-container>
13 </span>
14
15 <div ngbDropdownMenu>
16 <a *ngFor="let menuChild of menuEntry.children" class="dropdown-item" [routerLink]="menuChild.routerLink">{{ menuChild.label }}</a>
17 </div>
18 </div>
19
20 </ng-container>
21</div>
diff --git a/client/src/app/shared/menu/top-menu-dropdown.component.scss b/client/src/app/shared/menu/top-menu-dropdown.component.scss
new file mode 100644
index 000000000..77159532f
--- /dev/null
+++ b/client/src/app/shared/menu/top-menu-dropdown.component.scss
@@ -0,0 +1,18 @@
1.parent-entry {
2 span[role=button] {
3 cursor: pointer;
4 }
5
6 a {
7 display: block;
8 }
9}
10
11/deep/ .dropdown-toggle::after {
12 position: relative;
13 top: 2px;
14}
15
16/deep/ .dropdown-menu {
17 margin-top: 0 !important;
18}
diff --git a/client/src/app/shared/menu/top-menu-dropdown.component.ts b/client/src/app/shared/menu/top-menu-dropdown.component.ts
new file mode 100644
index 000000000..e859c30dd
--- /dev/null
+++ b/client/src/app/shared/menu/top-menu-dropdown.component.ts
@@ -0,0 +1,83 @@
1import { Component, Input, OnDestroy, OnInit } from '@angular/core'
2import { filter, take } from 'rxjs/operators'
3import { NavigationEnd, Router } from '@angular/router'
4import { Subscription } from 'rxjs'
5import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'
6
7export type TopMenuDropdownParam = {
8 label: string
9 routerLink?: string
10
11 children?: {
12 label: string
13 routerLink: string
14 }[]
15}
16
17@Component({
18 selector: 'my-top-menu-dropdown',
19 templateUrl: './top-menu-dropdown.component.html',
20 styleUrls: [ './top-menu-dropdown.component.scss' ]
21})
22export class TopMenuDropdownComponent implements OnInit, OnDestroy {
23 @Input() menuEntries: TopMenuDropdownParam[] = []
24
25 suffixLabels: { [ parentLabel: string ]: string }
26
27 private openedOnHover = false
28 private routeSub: Subscription
29
30 constructor (private router: Router) {}
31
32 ngOnInit () {
33 this.updateChildLabels(window.location.pathname)
34
35 this.routeSub = this.router.events
36 .pipe(filter(event => event instanceof NavigationEnd))
37 .subscribe(() => this.updateChildLabels(window.location.pathname))
38 }
39
40 ngOnDestroy () {
41 if (this.routeSub) this.routeSub.unsubscribe()
42 }
43
44 openDropdownOnHover (dropdown: NgbDropdown) {
45 this.openedOnHover = true
46 dropdown.open()
47
48 // Menu was closed
49 dropdown.openChange
50 .pipe(take(1))
51 .subscribe(e => this.openedOnHover = false)
52 }
53
54 dropdownAnchorClicked (dropdown: NgbDropdown) {
55 if (this.openedOnHover) {
56 this.openedOnHover = false
57 return
58 }
59
60 return dropdown.toggle()
61 }
62
63 closeDropdownIfHovered (dropdown: NgbDropdown) {
64 if (this.openedOnHover === false) return
65
66 dropdown.close()
67 this.openedOnHover = false
68 }
69
70 private updateChildLabels (path: string) {
71 this.suffixLabels = {}
72
73 for (const entry of this.menuEntries) {
74 if (!entry.children) continue
75
76 for (const child of entry.children) {
77 if (path.startsWith(child.routerLink)) {
78 this.suffixLabels[entry.label] = child.label
79 }
80 }
81 }
82 }
83}
diff --git a/client/src/app/shared/misc/help.component.html b/client/src/app/shared/misc/help.component.html
index 28ccb1e26..444425c9f 100644
--- a/client/src/app/shared/misc/help.component.html
+++ b/client/src/app/shared/misc/help.component.html
@@ -18,10 +18,13 @@
18 container="body" 18 container="body"
19 title="Get help" 19 title="Get help"
20 i18n-title 20 i18n-title
21 popoverClass="help-popover"
21 [attr.aria-pressed]="isPopoverOpened" 22 [attr.aria-pressed]="isPopoverOpened"
22 [ngbPopover]="tooltipTemplate" 23 [ngbPopover]="tooltipTemplate"
23 [placement]="tooltipPlacement" 24 [placement]="tooltipPlacement"
24 [autoClose]="true" 25 [autoClose]="true"
25 (onHidden)="onPopoverHidden()" 26 (onHidden)="onPopoverHidden()"
26 (onShown)="onPopoverShown()" 27 (onShown)="onPopoverShown()"
27></span> 28>
29 <my-global-icon iconName="help"></my-global-icon>
30</span>
diff --git a/client/src/app/shared/misc/help.component.scss b/client/src/app/shared/misc/help.component.scss
index 5c73a8031..3898f3cda 100644
--- a/client/src/app/shared/misc/help.component.scss
+++ b/client/src/app/shared/misc/help.component.scss
@@ -2,29 +2,40 @@
2@import '_mixins'; 2@import '_mixins';
3 3
4.help-tooltip-button { 4.help-tooltip-button {
5 @include icon(17px); 5 cursor: pointer;
6
7 position: relative;
8 top: -2px;
9 background-image: url('../../../assets/images/global/help.svg');
10 border: none; 6 border: none;
11 margin: 5px; 7
8 my-global-icon {
9 width: 17px;
10 position: relative;
11 top: -2px;
12 margin: 5px;
13
14 @include apply-svg-color(var(--mainForegroundColor))
15 }
12} 16}
13 17
14/deep/ { 18/deep/ {
15 .popover-body { 19 .help-popover {
16 text-align: left;
17 padding: 10px;
18 max-width: 300px; 20 max-width: 300px;
19 21
20 font-size: 13px; 22 .popover-body {
21 font-family: $main-fonts; 23 font-family: $main-fonts;
22 background-color: #fff; 24 text-align: left;
23 color: #000; 25 padding: 10px;
24 box-shadow: 0 0 6px rgba(0, 0, 0, 0.5); 26 font-size: 13px;
27 background-color: var(--mainBackgroundColor);
28 color: var(--mainForegroundColor);
29 box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
30
31 p {
32 margin-bottom: 0;
33 }
25 34
26 ul { 35 ul {
27 padding-left: 20px; 36 padding-left: 20px;
37 margin-bottom: 0;
38 }
28 } 39 }
29 } 40 }
30} 41}
diff --git a/client/src/app/shared/misc/help.component.ts b/client/src/app/shared/misc/help.component.ts
index ba0452e77..f3426f70f 100644
--- a/client/src/app/shared/misc/help.component.ts
+++ b/client/src/app/shared/misc/help.component.ts
@@ -1,6 +1,6 @@
1import { Component, Input, OnChanges, OnInit } from '@angular/core' 1import { Component, Input, OnChanges, OnInit } from '@angular/core'
2import { MarkdownService } from '@app/videos/shared'
3import { I18n } from '@ngx-translate/i18n-polyfill' 2import { I18n } from '@ngx-translate/i18n-polyfill'
3import { MarkdownService } from '@app/shared/renderer'
4 4
5@Component({ 5@Component({
6 selector: 'my-help', 6 selector: 'my-help',
diff --git a/client/src/app/shared/misc/utils.ts b/client/src/app/shared/misc/utils.ts
index 78e8e9682..7cc6055c2 100644
--- a/client/src/app/shared/misc/utils.ts
+++ b/client/src/app/shared/misc/utils.ts
@@ -102,12 +102,18 @@ function objectToFormData (obj: any, form?: FormData, namespace?: string) {
102 return fd 102 return fd
103} 103}
104 104
105function lineFeedToHtml (obj: any, keyToNormalize: string) { 105function objectLineFeedToHtml (obj: any, keyToNormalize: string) {
106 return immutableAssign(obj, { 106 return immutableAssign(obj, {
107 [keyToNormalize]: obj[keyToNormalize].replace(/\r?\n|\r/g, '<br />') 107 [keyToNormalize]: lineFeedToHtml(obj[keyToNormalize])
108 }) 108 })
109} 109}
110 110
111function lineFeedToHtml (text: string) {
112 if (!text) return text
113
114 return text.replace(/\r?\n|\r/g, '<br />')
115}
116
111function removeElementFromArray <T> (arr: T[], elem: T) { 117function removeElementFromArray <T> (arr: T[], elem: T) {
112 const index = arr.indexOf(elem) 118 const index = arr.indexOf(elem)
113 if (index !== -1) arr.splice(index, 1) 119 if (index !== -1) arr.splice(index, 1)
@@ -131,6 +137,7 @@ function scrollToTop () {
131export { 137export {
132 sortBy, 138 sortBy,
133 durationToString, 139 durationToString,
140 lineFeedToHtml,
134 objectToUrlEncoded, 141 objectToUrlEncoded,
135 getParameterByName, 142 getParameterByName,
136 populateAsyncUserVideoChannels, 143 populateAsyncUserVideoChannels,
@@ -138,7 +145,7 @@ export {
138 dateToHuman, 145 dateToHuman,
139 immutableAssign, 146 immutableAssign,
140 objectToFormData, 147 objectToFormData,
141 lineFeedToHtml, 148 objectLineFeedToHtml,
142 removeElementFromArray, 149 removeElementFromArray,
143 scrollToTop 150 scrollToTop
144} 151}
diff --git a/client/src/app/shared/moderation/user-ban-modal.component.html b/client/src/app/shared/moderation/user-ban-modal.component.html
index fa5cb7404..f38ea543d 100644
--- a/client/src/app/shared/moderation/user-ban-modal.component.html
+++ b/client/src/app/shared/moderation/user-ban-modal.component.html
@@ -1,7 +1,8 @@
1<ng-template #modal> 1<ng-template #modal>
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Ban</h4> 3 <h4 i18n class="modal-title">Ban</h4>
4 <span class="close" aria-hidden="true" (click)="hideBanUserModal()"></span> 4
5 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
5 </div> 6 </div>
6 7
7 <div class="modal-body"> 8 <div class="modal-body">
@@ -19,7 +20,7 @@
19 </div> 20 </div>
20 21
21 <div class="form-group inputs"> 22 <div class="form-group inputs">
22 <span i18n class="action-button action-button-cancel" (click)="hideBanUserModal()">Cancel</span> 23 <span i18n class="action-button action-button-cancel" (click)="hide()">Cancel</span>
23 24
24 <input 25 <input
25 type="submit" i18n-value value="Ban this user" class="action-button-submit" 26 type="submit" i18n-value value="Ban this user" class="action-button-submit"
@@ -29,4 +30,4 @@
29 </form> 30 </form>
30 </div> 31 </div>
31 32
32</ng-template> \ No newline at end of file 33</ng-template>
diff --git a/client/src/app/shared/moderation/user-ban-modal.component.ts b/client/src/app/shared/moderation/user-ban-modal.component.ts
index 60bd442dd..942765301 100644
--- a/client/src/app/shared/moderation/user-ban-modal.component.ts
+++ b/client/src/app/shared/moderation/user-ban-modal.component.ts
@@ -1,5 +1,5 @@
1import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' 1import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 4import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
5import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' 5import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
@@ -23,7 +23,7 @@ export class UserBanModalComponent extends FormReactive implements OnInit {
23 constructor ( 23 constructor (
24 protected formValidatorService: FormValidatorService, 24 protected formValidatorService: FormValidatorService,
25 private modalService: NgbModal, 25 private modalService: NgbModal,
26 private notificationsService: NotificationsService, 26 private notifier: Notifier,
27 private userService: UserService, 27 private userService: UserService,
28 private userValidatorsService: UserValidatorsService, 28 private userValidatorsService: UserValidatorsService,
29 private i18n: I18n 29 private i18n: I18n
@@ -42,7 +42,7 @@ export class UserBanModalComponent extends FormReactive implements OnInit {
42 this.openedModal = this.modalService.open(this.modal) 42 this.openedModal = this.modalService.open(this.modal)
43 } 43 }
44 44
45 hideBanUserModal () { 45 hide () {
46 this.usersToBan = undefined 46 this.usersToBan = undefined
47 this.openedModal.close() 47 this.openedModal.close()
48 } 48 }
@@ -57,13 +57,13 @@ export class UserBanModalComponent extends FormReactive implements OnInit {
57 ? this.i18n('{{num}} users banned.', { num: this.usersToBan.length }) 57 ? this.i18n('{{num}} users banned.', { num: this.usersToBan.length })
58 : this.i18n('User {{username}} banned.', { username: this.usersToBan.username }) 58 : this.i18n('User {{username}} banned.', { username: this.usersToBan.username })
59 59
60 this.notificationsService.success(this.i18n('Success'), message) 60 this.notifier.success(message)
61 61
62 this.userBanned.emit(this.usersToBan) 62 this.userBanned.emit(this.usersToBan)
63 this.hideBanUserModal() 63 this.hide()
64 }, 64 },
65 65
66 err => this.notificationsService.error(this.i18n('Error'), err.message) 66 err => this.notifier.error(err.message)
67 ) 67 )
68 } 68 }
69 69
diff --git a/client/src/app/shared/moderation/user-moderation-dropdown.component.ts b/client/src/app/shared/moderation/user-moderation-dropdown.component.ts
index d391246e0..9a2461ebf 100644
--- a/client/src/app/shared/moderation/user-moderation-dropdown.component.ts
+++ b/client/src/app/shared/moderation/user-moderation-dropdown.component.ts
@@ -1,10 +1,9 @@
1import { Component, EventEmitter, Input, OnChanges, Output, ViewChild } from '@angular/core' 1import { Component, EventEmitter, Input, OnChanges, Output, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications'
3import { I18n } from '@ngx-translate/i18n-polyfill' 2import { I18n } from '@ngx-translate/i18n-polyfill'
4import { DropdownAction } from '@app/shared/buttons/action-dropdown.component' 3import { DropdownAction } from '@app/shared/buttons/action-dropdown.component'
5import { UserBanModalComponent } from '@app/shared/moderation/user-ban-modal.component' 4import { UserBanModalComponent } from '@app/shared/moderation/user-ban-modal.component'
6import { UserService } from '@app/shared/users' 5import { UserService } from '@app/shared/users'
7import { AuthService, ConfirmService, ServerService } from '@app/core' 6import { AuthService, ConfirmService, Notifier, ServerService } from '@app/core'
8import { User, UserRight } from '../../../../../shared/models/users' 7import { User, UserRight } from '../../../../../shared/models/users'
9import { Account } from '@app/shared/account/account.model' 8import { Account } from '@app/shared/account/account.model'
10import { BlocklistService } from '@app/shared/blocklist' 9import { BlocklistService } from '@app/shared/blocklist'
@@ -30,7 +29,7 @@ export class UserModerationDropdownComponent implements OnChanges {
30 29
31 constructor ( 30 constructor (
32 private authService: AuthService, 31 private authService: AuthService,
33 private notificationsService: NotificationsService, 32 private notifier: Notifier,
34 private confirmService: ConfirmService, 33 private confirmService: ConfirmService,
35 private serverService: ServerService, 34 private serverService: ServerService,
36 private userService: UserService, 35 private userService: UserService,
@@ -48,7 +47,7 @@ export class UserModerationDropdownComponent implements OnChanges {
48 47
49 openBanUserModal (user: User) { 48 openBanUserModal (user: User) {
50 if (user.username === 'root') { 49 if (user.username === 'root') {
51 this.notificationsService.error(this.i18n('Error'), this.i18n('You cannot ban root.')) 50 this.notifier.error(this.i18n('You cannot ban root.'))
52 return 51 return
53 } 52 }
54 53
@@ -67,21 +66,18 @@ export class UserModerationDropdownComponent implements OnChanges {
67 this.userService.unbanUsers(user) 66 this.userService.unbanUsers(user)
68 .subscribe( 67 .subscribe(
69 () => { 68 () => {
70 this.notificationsService.success( 69 this.notifier.success(this.i18n('User {{username}} unbanned.', { username: user.username }))
71 this.i18n('Success'),
72 this.i18n('User {{username}} unbanned.', { username: user.username })
73 )
74 70
75 this.userChanged.emit() 71 this.userChanged.emit()
76 }, 72 },
77 73
78 err => this.notificationsService.error(this.i18n('Error'), err.message) 74 err => this.notifier.error(err.message)
79 ) 75 )
80 } 76 }
81 77
82 async removeUser (user: User) { 78 async removeUser (user: User) {
83 if (user.username === 'root') { 79 if (user.username === 'root') {
84 this.notificationsService.error(this.i18n('Error'), this.i18n('You cannot delete root.')) 80 this.notifier.error(this.i18n('You cannot delete root.'))
85 return 81 return
86 } 82 }
87 83
@@ -91,29 +87,23 @@ export class UserModerationDropdownComponent implements OnChanges {
91 87
92 this.userService.removeUser(user).subscribe( 88 this.userService.removeUser(user).subscribe(
93 () => { 89 () => {
94 this.notificationsService.success( 90 this.notifier.success(this.i18n('User {{username}} deleted.', { username: user.username }))
95 this.i18n('Success'),
96 this.i18n('User {{username}} deleted.', { username: user.username })
97 )
98 this.userDeleted.emit() 91 this.userDeleted.emit()
99 }, 92 },
100 93
101 err => this.notificationsService.error(this.i18n('Error'), err.message) 94 err => this.notifier.error(err.message)
102 ) 95 )
103 } 96 }
104 97
105 setEmailAsVerified (user: User) { 98 setEmailAsVerified (user: User) {
106 this.userService.updateUser(user.id, { emailVerified: true }).subscribe( 99 this.userService.updateUser(user.id, { emailVerified: true }).subscribe(
107 () => { 100 () => {
108 this.notificationsService.success( 101 this.notifier.success(this.i18n('User {{username}} email set as verified', { username: user.username }))
109 this.i18n('Success'),
110 this.i18n('User {{username}} email set as verified', { username: user.username })
111 )
112 102
113 this.userChanged.emit() 103 this.userChanged.emit()
114 }, 104 },
115 105
116 err => this.notificationsService.error(this.i18n('Error'), err.message) 106 err => this.notifier.error(err.message)
117 ) 107 )
118 } 108 }
119 109
@@ -121,16 +111,13 @@ export class UserModerationDropdownComponent implements OnChanges {
121 this.blocklistService.blockAccountByUser(account) 111 this.blocklistService.blockAccountByUser(account)
122 .subscribe( 112 .subscribe(
123 () => { 113 () => {
124 this.notificationsService.success( 114 this.notifier.success(this.i18n('Account {{nameWithHost}} muted.', { nameWithHost: account.nameWithHost }))
125 this.i18n('Success'),
126 this.i18n('Account {{nameWithHost}} muted.', { nameWithHost: account.nameWithHost })
127 )
128 115
129 this.account.mutedByUser = true 116 this.account.mutedByUser = true
130 this.userChanged.emit() 117 this.userChanged.emit()
131 }, 118 },
132 119
133 err => this.notificationsService.error(this.i18n('Error'), err.message) 120 err => this.notifier.error(err.message)
134 ) 121 )
135 } 122 }
136 123
@@ -138,16 +125,13 @@ export class UserModerationDropdownComponent implements OnChanges {
138 this.blocklistService.unblockAccountByUser(account) 125 this.blocklistService.unblockAccountByUser(account)
139 .subscribe( 126 .subscribe(
140 () => { 127 () => {
141 this.notificationsService.success( 128 this.notifier.success(this.i18n('Account {{nameWithHost}} unmuted.', { nameWithHost: account.nameWithHost }))
142 this.i18n('Success'),
143 this.i18n('Account {{nameWithHost}} unmuted.', { nameWithHost: account.nameWithHost })
144 )
145 129
146 this.account.mutedByUser = false 130 this.account.mutedByUser = false
147 this.userChanged.emit() 131 this.userChanged.emit()
148 }, 132 },
149 133
150 err => this.notificationsService.error(this.i18n('Error'), err.message) 134 err => this.notifier.error(err.message)
151 ) 135 )
152 } 136 }
153 137
@@ -155,16 +139,13 @@ export class UserModerationDropdownComponent implements OnChanges {
155 this.blocklistService.blockServerByUser(host) 139 this.blocklistService.blockServerByUser(host)
156 .subscribe( 140 .subscribe(
157 () => { 141 () => {
158 this.notificationsService.success( 142 this.notifier.success(this.i18n('Instance {{host}} muted.', { host }))
159 this.i18n('Success'),
160 this.i18n('Instance {{host}} muted.', { host })
161 )
162 143
163 this.account.mutedServerByUser = true 144 this.account.mutedServerByUser = true
164 this.userChanged.emit() 145 this.userChanged.emit()
165 }, 146 },
166 147
167 err => this.notificationsService.error(this.i18n('Error'), err.message) 148 err => this.notifier.error(err.message)
168 ) 149 )
169 } 150 }
170 151
@@ -172,16 +153,13 @@ export class UserModerationDropdownComponent implements OnChanges {
172 this.blocklistService.unblockServerByUser(host) 153 this.blocklistService.unblockServerByUser(host)
173 .subscribe( 154 .subscribe(
174 () => { 155 () => {
175 this.notificationsService.success( 156 this.notifier.success(this.i18n('Instance {{host}} unmuted.', { host }))
176 this.i18n('Success'),
177 this.i18n('Instance {{host}} unmuted.', { host })
178 )
179 157
180 this.account.mutedServerByUser = false 158 this.account.mutedServerByUser = false
181 this.userChanged.emit() 159 this.userChanged.emit()
182 }, 160 },
183 161
184 err => this.notificationsService.error(this.i18n('Error'), err.message) 162 err => this.notifier.error(err.message)
185 ) 163 )
186 } 164 }
187 165
@@ -189,16 +167,13 @@ export class UserModerationDropdownComponent implements OnChanges {
189 this.blocklistService.blockAccountByInstance(account) 167 this.blocklistService.blockAccountByInstance(account)
190 .subscribe( 168 .subscribe(
191 () => { 169 () => {
192 this.notificationsService.success( 170 this.notifier.success(this.i18n('Account {{nameWithHost}} muted by the instance.', { nameWithHost: account.nameWithHost }))
193 this.i18n('Success'),
194 this.i18n('Account {{nameWithHost}} muted by the instance.', { nameWithHost: account.nameWithHost })
195 )
196 171
197 this.account.mutedByInstance = true 172 this.account.mutedByInstance = true
198 this.userChanged.emit() 173 this.userChanged.emit()
199 }, 174 },
200 175
201 err => this.notificationsService.error(this.i18n('Error'), err.message) 176 err => this.notifier.error(err.message)
202 ) 177 )
203 } 178 }
204 179
@@ -206,16 +181,13 @@ export class UserModerationDropdownComponent implements OnChanges {
206 this.blocklistService.unblockAccountByInstance(account) 181 this.blocklistService.unblockAccountByInstance(account)
207 .subscribe( 182 .subscribe(
208 () => { 183 () => {
209 this.notificationsService.success( 184 this.notifier.success(this.i18n('Account {{nameWithHost}} unmuted by the instance.', { nameWithHost: account.nameWithHost }))
210 this.i18n('Success'),
211 this.i18n('Account {{nameWithHost}} unmuted by the instance.', { nameWithHost: account.nameWithHost })
212 )
213 185
214 this.account.mutedByInstance = false 186 this.account.mutedByInstance = false
215 this.userChanged.emit() 187 this.userChanged.emit()
216 }, 188 },
217 189
218 err => this.notificationsService.error(this.i18n('Error'), err.message) 190 err => this.notifier.error(err.message)
219 ) 191 )
220 } 192 }
221 193
@@ -223,16 +195,13 @@ export class UserModerationDropdownComponent implements OnChanges {
223 this.blocklistService.blockServerByInstance(host) 195 this.blocklistService.blockServerByInstance(host)
224 .subscribe( 196 .subscribe(
225 () => { 197 () => {
226 this.notificationsService.success( 198 this.notifier.success(this.i18n('Instance {{host}} muted by the instance.', { host }))
227 this.i18n('Success'),
228 this.i18n('Instance {{host}} muted by the instance.', { host })
229 )
230 199
231 this.account.mutedServerByInstance = true 200 this.account.mutedServerByInstance = true
232 this.userChanged.emit() 201 this.userChanged.emit()
233 }, 202 },
234 203
235 err => this.notificationsService.error(this.i18n('Error'), err.message) 204 err => this.notifier.error(err.message)
236 ) 205 )
237 } 206 }
238 207
@@ -240,16 +209,13 @@ export class UserModerationDropdownComponent implements OnChanges {
240 this.blocklistService.unblockServerByInstance(host) 209 this.blocklistService.unblockServerByInstance(host)
241 .subscribe( 210 .subscribe(
242 () => { 211 () => {
243 this.notificationsService.success( 212 this.notifier.success(this.i18n('Instance {{host}} unmuted by the instance.', { host }))
244 this.i18n('Success'),
245 this.i18n('Instance {{host}} unmuted by the instance.', { host })
246 )
247 213
248 this.account.mutedServerByInstance = false 214 this.account.mutedServerByInstance = false
249 this.userChanged.emit() 215 this.userChanged.emit()
250 }, 216 },
251 217
252 err => this.notificationsService.error(this.i18n('Error'), err.message) 218 err => this.notifier.error(err.message)
253 ) 219 )
254 } 220 }
255 221
@@ -277,18 +243,18 @@ export class UserModerationDropdownComponent implements OnChanges {
277 }, 243 },
278 { 244 {
279 label: this.i18n('Ban'), 245 label: this.i18n('Ban'),
280 handler: ({ user }: { user: User }) => this.openBanUserModal(user), 246 handler: ({ user }) => this.openBanUserModal(user),
281 isDisplayed: ({ user }: { user: User }) => !user.blocked 247 isDisplayed: ({ user }) => !user.blocked
282 }, 248 },
283 { 249 {
284 label: this.i18n('Unban'), 250 label: this.i18n('Unban'),
285 handler: ({ user }: { user: User }) => this.unbanUser(user), 251 handler: ({ user }) => this.unbanUser(user),
286 isDisplayed: ({ user }: { user: User }) => user.blocked 252 isDisplayed: ({ user }) => user.blocked
287 }, 253 },
288 { 254 {
289 label: this.i18n('Set Email as Verified'), 255 label: this.i18n('Set Email as Verified'),
290 handler: ({ user }: { user: User }) => this.setEmailAsVerified(user), 256 handler: ({ user }) => this.setEmailAsVerified(user),
291 isDisplayed: ({ user }: { user: User }) => this.requiresEmailVerification && !user.blocked && user.emailVerified === false 257 isDisplayed: ({ user }) => this.requiresEmailVerification && !user.blocked && user.emailVerified === false
292 } 258 }
293 ]) 259 ])
294 } 260 }
@@ -299,23 +265,23 @@ export class UserModerationDropdownComponent implements OnChanges {
299 this.userActions.push([ 265 this.userActions.push([
300 { 266 {
301 label: this.i18n('Mute this account'), 267 label: this.i18n('Mute this account'),
302 isDisplayed: ({ account }: { account: Account }) => account.mutedByUser === false, 268 isDisplayed: ({ account }) => account.mutedByUser === false,
303 handler: ({ account }: { account: Account }) => this.blockAccountByUser(account) 269 handler: ({ account }) => this.blockAccountByUser(account)
304 }, 270 },
305 { 271 {
306 label: this.i18n('Unmute this account'), 272 label: this.i18n('Unmute this account'),
307 isDisplayed: ({ account }: { account: Account }) => account.mutedByUser === true, 273 isDisplayed: ({ account }) => account.mutedByUser === true,
308 handler: ({ account }: { account: Account }) => this.unblockAccountByUser(account) 274 handler: ({ account }) => this.unblockAccountByUser(account)
309 }, 275 },
310 { 276 {
311 label: this.i18n('Mute the instance'), 277 label: this.i18n('Mute the instance'),
312 isDisplayed: ({ account }: { account: Account }) => !account.userId && account.mutedServerByInstance === false, 278 isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === false,
313 handler: ({ account }: { account: Account }) => this.blockServerByUser(account.host) 279 handler: ({ account }) => this.blockServerByUser(account.host)
314 }, 280 },
315 { 281 {
316 label: this.i18n('Unmute the instance'), 282 label: this.i18n('Unmute the instance'),
317 isDisplayed: ({ account }: { account: Account }) => !account.userId && account.mutedServerByInstance === true, 283 isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === true,
318 handler: ({ account }: { account: Account }) => this.unblockServerByUser(account.host) 284 handler: ({ account }) => this.unblockServerByUser(account.host)
319 } 285 }
320 ]) 286 ])
321 287
@@ -326,13 +292,13 @@ export class UserModerationDropdownComponent implements OnChanges {
326 instanceActions = instanceActions.concat([ 292 instanceActions = instanceActions.concat([
327 { 293 {
328 label: this.i18n('Mute this account by your instance'), 294 label: this.i18n('Mute this account by your instance'),
329 isDisplayed: ({ account }: { account: Account }) => account.mutedByInstance === false, 295 isDisplayed: ({ account }) => account.mutedByInstance === false,
330 handler: ({ account }: { account: Account }) => this.blockAccountByInstance(account) 296 handler: ({ account }) => this.blockAccountByInstance(account)
331 }, 297 },
332 { 298 {
333 label: this.i18n('Unmute this account by your instance'), 299 label: this.i18n('Unmute this account by your instance'),
334 isDisplayed: ({ account }: { account: Account }) => account.mutedByInstance === true, 300 isDisplayed: ({ account }) => account.mutedByInstance === true,
335 handler: ({ account }: { account: Account }) => this.unblockAccountByInstance(account) 301 handler: ({ account }) => this.unblockAccountByInstance(account)
336 } 302 }
337 ]) 303 ])
338 } 304 }
@@ -342,13 +308,13 @@ export class UserModerationDropdownComponent implements OnChanges {
342 instanceActions = instanceActions.concat([ 308 instanceActions = instanceActions.concat([
343 { 309 {
344 label: this.i18n('Mute the instance by your instance'), 310 label: this.i18n('Mute the instance by your instance'),
345 isDisplayed: ({ account }: { account: Account }) => !account.userId && account.mutedServerByInstance === false, 311 isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === false,
346 handler: ({ account }: { account: Account }) => this.blockServerByInstance(account.host) 312 handler: ({ account }) => this.blockServerByInstance(account.host)
347 }, 313 },
348 { 314 {
349 label: this.i18n('Unmute the instance by your instance'), 315 label: this.i18n('Unmute the instance by your instance'),
350 isDisplayed: ({ account }: { account: Account }) => !account.userId && account.mutedServerByInstance === true, 316 isDisplayed: ({ account }) => !account.userId && account.mutedServerByInstance === true,
351 handler: ({ account }: { account: Account }) => this.unblockServerByInstance(account.host) 317 handler: ({ account }) => this.unblockServerByInstance(account.host)
352 } 318 }
353 ]) 319 ])
354 } 320 }
diff --git a/client/src/app/shared/renderer/html-renderer.service.ts b/client/src/app/shared/renderer/html-renderer.service.ts
new file mode 100644
index 000000000..d49df9b6d
--- /dev/null
+++ b/client/src/app/shared/renderer/html-renderer.service.ts
@@ -0,0 +1,35 @@
1import { Injectable } from '@angular/core'
2import { LinkifierService } from '@app/shared/renderer/linkifier.service'
3import * as sanitizeHtml from 'sanitize-html'
4
5@Injectable()
6export class HtmlRendererService {
7
8 constructor (private linkifier: LinkifierService) {
9
10 }
11
12 toSafeHtml (text: string) {
13 // Convert possible markdown to html
14 const html = this.linkifier.linkify(text)
15
16 return sanitizeHtml(html, {
17 allowedTags: [ 'a', 'p', 'span', 'br' ],
18 allowedSchemes: [ 'http', 'https' ],
19 allowedAttributes: {
20 'a': [ 'href', 'class', 'target' ]
21 },
22 transformTags: {
23 a: (tagName, attribs) => {
24 return {
25 tagName,
26 attribs: Object.assign(attribs, {
27 target: '_blank',
28 rel: 'noopener noreferrer'
29 })
30 }
31 }
32 }
33 })
34 }
35}
diff --git a/client/src/app/shared/renderer/index.ts b/client/src/app/shared/renderer/index.ts
new file mode 100644
index 000000000..39202b385
--- /dev/null
+++ b/client/src/app/shared/renderer/index.ts
@@ -0,0 +1,3 @@
1export * from './html-renderer.service'
2export * from './linkifier.service'
3export * from './markdown.service'
diff --git a/client/src/app/videos/+video-watch/comment/linkifier.service.ts b/client/src/app/shared/renderer/linkifier.service.ts
index 2529c9eaf..2529c9eaf 100644
--- a/client/src/app/videos/+video-watch/comment/linkifier.service.ts
+++ b/client/src/app/shared/renderer/linkifier.service.ts
diff --git a/client/src/app/videos/shared/markdown.service.ts b/client/src/app/shared/renderer/markdown.service.ts
index 07017eca5..07017eca5 100644
--- a/client/src/app/videos/shared/markdown.service.ts
+++ b/client/src/app/shared/renderer/markdown.service.ts
diff --git a/client/src/app/shared/rest/component-pagination.model.ts b/client/src/app/shared/rest/component-pagination.model.ts
index 0b8ecc318..85160d445 100644
--- a/client/src/app/shared/rest/component-pagination.model.ts
+++ b/client/src/app/shared/rest/component-pagination.model.ts
@@ -3,3 +3,14 @@ export interface ComponentPagination {
3 itemsPerPage: number 3 itemsPerPage: number
4 totalItems?: number 4 totalItems?: number
5} 5}
6
7export function hasMoreItems (componentPagination: ComponentPagination) {
8 // No results
9 if (componentPagination.totalItems === 0) return false
10
11 // Not loaded yet
12 if (!componentPagination.totalItems) return true
13
14 const maxPage = componentPagination.totalItems / componentPagination.itemsPerPage
15 return maxPage > componentPagination.currentPage
16}
diff --git a/client/src/app/shared/rest/rest-extractor.service.ts b/client/src/app/shared/rest/rest-extractor.service.ts
index f149569ef..e6518dd1d 100644
--- a/client/src/app/shared/rest/rest-extractor.service.ts
+++ b/client/src/app/shared/rest/rest-extractor.service.ts
@@ -80,6 +80,7 @@ export class RestExtractor {
80 errorMessage = errorMessage ? errorMessage : 'Unknown error.' 80 errorMessage = errorMessage ? errorMessage : 'Unknown error.'
81 console.error(`Backend returned code ${err.status}, errorMessage is: ${errorMessage}`) 81 console.error(`Backend returned code ${err.status}, errorMessage is: ${errorMessage}`)
82 } else { 82 } else {
83 console.error(err)
83 errorMessage = err 84 errorMessage = err
84 } 85 }
85 86
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index a2fa27b72..6f8625c7e 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -6,7 +6,6 @@ import { RouterModule } from '@angular/router'
6import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component' 6import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component'
7import { HelpComponent } from '@app/shared/misc/help.component' 7import { HelpComponent } from '@app/shared/misc/help.component'
8import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' 8import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive'
9import { MarkdownService } from '@app/videos/shared'
10 9
11import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes' 10import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes'
12import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared' 11import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared'
@@ -34,6 +33,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
34import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 33import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
35import { 34import {
36 CustomConfigValidatorsService, 35 CustomConfigValidatorsService,
36 InstanceValidatorsService,
37 LoginValidatorsService, 37 LoginValidatorsService,
38 ReactiveFileComponent, 38 ReactiveFileComponent,
39 ResetPasswordValidatorsService, 39 ResetPasswordValidatorsService,
@@ -61,6 +61,14 @@ import { OverviewService } from '@app/shared/overview'
61import { UserBanModalComponent } from '@app/shared/moderation' 61import { UserBanModalComponent } from '@app/shared/moderation'
62import { UserModerationDropdownComponent } from '@app/shared/moderation/user-moderation-dropdown.component' 62import { UserModerationDropdownComponent } from '@app/shared/moderation/user-moderation-dropdown.component'
63import { BlocklistService } from '@app/shared/blocklist' 63import { BlocklistService } from '@app/shared/blocklist'
64import { TopMenuDropdownComponent } from '@app/shared/menu/top-menu-dropdown.component'
65import { UserHistoryService } from '@app/shared/users/user-history.service'
66import { UserNotificationService } from '@app/shared/users/user-notification.service'
67import { UserNotificationsComponent } from '@app/shared/users/user-notifications.component'
68import { InstanceService } from '@app/shared/instance/instance.service'
69import { HtmlRendererService, LinkifierService, MarkdownService } from '@app/shared/renderer'
70import { ConfirmComponent } from '@app/shared/confirm/confirm.component'
71import { GlobalIconComponent } from '@app/shared/icons/global-icon.component'
64 72
65@NgModule({ 73@NgModule({
66 imports: [ 74 imports: [
@@ -102,7 +110,11 @@ import { BlocklistService } from '@app/shared/blocklist'
102 RemoteSubscribeComponent, 110 RemoteSubscribeComponent,
103 InstanceFeaturesTableComponent, 111 InstanceFeaturesTableComponent,
104 UserBanModalComponent, 112 UserBanModalComponent,
105 UserModerationDropdownComponent 113 UserModerationDropdownComponent,
114 TopMenuDropdownComponent,
115 UserNotificationsComponent,
116 ConfirmComponent,
117 GlobalIconComponent
106 ], 118 ],
107 119
108 exports: [ 120 exports: [
@@ -141,6 +153,10 @@ import { BlocklistService } from '@app/shared/blocklist'
141 InstanceFeaturesTableComponent, 153 InstanceFeaturesTableComponent,
142 UserBanModalComponent, 154 UserBanModalComponent,
143 UserModerationDropdownComponent, 155 UserModerationDropdownComponent,
156 TopMenuDropdownComponent,
157 UserNotificationsComponent,
158 ConfirmComponent,
159 GlobalIconComponent,
144 160
145 NumberFormatterPipe, 161 NumberFormatterPipe,
146 ObjectLengthPipe, 162 ObjectLengthPipe,
@@ -157,7 +173,6 @@ import { BlocklistService } from '@app/shared/blocklist'
157 UserService, 173 UserService,
158 VideoService, 174 VideoService,
159 AccountService, 175 AccountService,
160 MarkdownService,
161 VideoChannelService, 176 VideoChannelService,
162 VideoCaptionService, 177 VideoCaptionService,
163 VideoImportService, 178 VideoImportService,
@@ -177,11 +192,20 @@ import { BlocklistService } from '@app/shared/blocklist'
177 OverviewService, 192 OverviewService,
178 VideoChangeOwnershipValidatorsService, 193 VideoChangeOwnershipValidatorsService,
179 VideoAcceptOwnershipValidatorsService, 194 VideoAcceptOwnershipValidatorsService,
195 InstanceValidatorsService,
180 BlocklistService, 196 BlocklistService,
197 UserHistoryService,
198 InstanceService,
199
200 MarkdownService,
201 LinkifierService,
202 HtmlRendererService,
181 203
182 I18nPrimengCalendarService, 204 I18nPrimengCalendarService,
183 ScreenService, 205 ScreenService,
184 206
207 UserNotificationService,
208
185 I18n 209 I18n
186 ] 210 ]
187}) 211})
diff --git a/client/src/app/shared/user-subscription/remote-subscribe.component.ts b/client/src/app/shared/user-subscription/remote-subscribe.component.ts
index 7a81108cd..ba2a45df1 100644
--- a/client/src/app/shared/user-subscription/remote-subscribe.component.ts
+++ b/client/src/app/shared/user-subscription/remote-subscribe.component.ts
@@ -29,7 +29,7 @@ export class RemoteSubscribeComponent extends FormReactive implements OnInit {
29 } 29 }
30 30
31 onValidKey () { 31 onValidKey () {
32 this.onValueChanged() 32 this.check()
33 if (!this.form.valid) return 33 if (!this.form.valid) return
34 34
35 this.formValidated() 35 this.formValidated()
@@ -37,7 +37,24 @@ export class RemoteSubscribeComponent extends FormReactive implements OnInit {
37 37
38 formValidated () { 38 formValidated () {
39 const address = this.form.value['text'] 39 const address = this.form.value['text']
40 const [ , hostname ] = address.split('@') 40 const [ username, hostname ] = address.split('@')
41 window.open(`https://${hostname}/authorize_interaction?acct=${this.account}`) 41
42 fetch(`https://${hostname}/.well-known/webfinger?resource=acct:${username}@${hostname}`)
43 .then(response => response.json())
44 .then(data => new Promise((resolve, reject) => {
45 if (data && Array.isArray(data.links)) {
46 const link: {
47 template: string
48 } = data.links.find((link: any) =>
49 link && typeof link.template === 'string' && link.rel === 'http://ostatus.org/schema/1.0/subscribe')
50
51 if (link && link.template.includes('{uri}')) {
52 resolve(link.template.replace('{uri}', `acct:${this.account}`))
53 }
54 }
55 reject()
56 }))
57 .then(window.open)
58 .catch(() => window.open(`https://${hostname}/authorize_interaction?acct=${this.account}`))
42 } 59 }
43} 60}
diff --git a/client/src/app/shared/user-subscription/subscribe-button.component.ts b/client/src/app/shared/user-subscription/subscribe-button.component.ts
index 315ea5037..8f1754c7f 100644
--- a/client/src/app/shared/user-subscription/subscribe-button.component.ts
+++ b/client/src/app/shared/user-subscription/subscribe-button.component.ts
@@ -1,9 +1,8 @@
1import { Component, Input, OnInit } from '@angular/core' 1import { Component, Input, OnInit } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3import { AuthService } from '@app/core' 3import { AuthService, Notifier } from '@app/core'
4import { UserSubscriptionService } from '@app/shared/user-subscription/user-subscription.service' 4import { UserSubscriptionService } from '@app/shared/user-subscription/user-subscription.service'
5import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 5import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
6import { NotificationsService } from 'angular2-notifications'
7import { I18n } from '@ngx-translate/i18n-polyfill' 6import { I18n } from '@ngx-translate/i18n-polyfill'
8import { VideoService } from '@app/shared/video/video.service' 7import { VideoService } from '@app/shared/video/video.service'
9import { FeedFormat } from '../../../../../shared/models/feeds' 8import { FeedFormat } from '../../../../../shared/models/feeds'
@@ -23,7 +22,7 @@ export class SubscribeButtonComponent implements OnInit {
23 constructor ( 22 constructor (
24 private authService: AuthService, 23 private authService: AuthService,
25 private router: Router, 24 private router: Router,
26 private notificationsService: NotificationsService, 25 private notifier: Notifier,
27 private userSubscriptionService: UserSubscriptionService, 26 private userSubscriptionService: UserSubscriptionService,
28 private i18n: I18n, 27 private i18n: I18n,
29 private videoService: VideoService 28 private videoService: VideoService
@@ -43,18 +42,17 @@ export class SubscribeButtonComponent implements OnInit {
43 .subscribe( 42 .subscribe(
44 res => this.subscribed = res[this.uri], 43 res => this.subscribed = res[this.uri],
45 44
46 err => this.notificationsService.error(this.i18n('Error'), err.message) 45 err => this.notifier.error(err.message)
47 ) 46 )
48 } 47 }
49 } 48 }
50 49
51 subscribe () { 50 subscribe () {
52 if (this.isUserLoggedIn()) { 51 if (this.isUserLoggedIn()) {
53 this.localSubscribe() 52 return this.localSubscribe()
54 } else {
55 this.authService.redirectUrl = this.router.url
56 this.gotoLogin()
57 } 53 }
54
55 return this.gotoLogin()
58 } 56 }
59 57
60 localSubscribe () { 58 localSubscribe () {
@@ -63,13 +61,13 @@ export class SubscribeButtonComponent implements OnInit {
63 () => { 61 () => {
64 this.subscribed = true 62 this.subscribed = true
65 63
66 this.notificationsService.success( 64 this.notifier.success(
67 this.i18n('Subscribed'), 65 this.i18n('Subscribed to {{nameWithHost}}', { nameWithHost: this.videoChannel.displayName }),
68 this.i18n('Subscribed to {{nameWithHost}}', { nameWithHost: this.videoChannel.displayName }) 66 this.i18n('Subscribed')
69 ) 67 )
70 }, 68 },
71 69
72 err => this.notificationsService.error(this.i18n('Error'), err.message) 70 err => this.notifier.error(err.message)
73 ) 71 )
74 } 72 }
75 73
@@ -85,13 +83,13 @@ export class SubscribeButtonComponent implements OnInit {
85 () => { 83 () => {
86 this.subscribed = false 84 this.subscribed = false
87 85
88 this.notificationsService.success( 86 this.notifier.success(
89 this.i18n('Unsubscribed'), 87 this.i18n('Unsubscribed from {{nameWithHost}}', { nameWithHost: this.videoChannel.displayName }),
90 this.i18n('Unsubscribed from {{nameWithHost}}', { nameWithHost: this.videoChannel.displayName }) 88 this.i18n('Unsubscribed')
91 ) 89 )
92 }, 90 },
93 91
94 err => this.notificationsService.error(this.i18n('Error'), err.message) 92 err => this.notifier.error(err.message)
95 ) 93 )
96 } 94 }
97 95
diff --git a/client/src/app/shared/users/index.ts b/client/src/app/shared/users/index.ts
index 7b5a67bc7..ebd715fb1 100644
--- a/client/src/app/shared/users/index.ts
+++ b/client/src/app/shared/users/index.ts
@@ -1,2 +1,3 @@
1export * from './user.model' 1export * from './user.model'
2export * from './user.service' 2export * from './user.service'
3export * from './user-notifications.component'
diff --git a/client/src/app/shared/users/user-history.service.ts b/client/src/app/shared/users/user-history.service.ts
new file mode 100644
index 000000000..9ed25bfc7
--- /dev/null
+++ b/client/src/app/shared/users/user-history.service.ts
@@ -0,0 +1,45 @@
1import { HttpClient, HttpParams } from '@angular/common/http'
2import { Injectable } from '@angular/core'
3import { environment } from '../../../environments/environment'
4import { RestExtractor } from '../rest/rest-extractor.service'
5import { RestService } from '../rest/rest.service'
6import { Video } from '../video/video.model'
7import { catchError, map, switchMap } from 'rxjs/operators'
8import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
9import { VideoService } from '@app/shared/video/video.service'
10import { ResultList } from '../../../../../shared'
11
12@Injectable()
13export class UserHistoryService {
14 static BASE_USER_VIDEOS_HISTORY_URL = environment.apiUrl + '/api/v1/users/me/history/videos'
15
16 constructor (
17 private authHttp: HttpClient,
18 private restExtractor: RestExtractor,
19 private restService: RestService,
20 private videoService: VideoService
21 ) {}
22
23 getUserVideosHistory (historyPagination: ComponentPagination) {
24 const pagination = this.restService.componentPaginationToRestPagination(historyPagination)
25
26 let params = new HttpParams()
27 params = this.restService.addRestGetParams(params, pagination)
28
29 return this.authHttp
30 .get<ResultList<Video>>(UserHistoryService.BASE_USER_VIDEOS_HISTORY_URL, { params })
31 .pipe(
32 switchMap(res => this.videoService.extractVideos(res)),
33 catchError(err => this.restExtractor.handleError(err))
34 )
35 }
36
37 deleteUserVideosHistory () {
38 return this.authHttp
39 .post(UserHistoryService.BASE_USER_VIDEOS_HISTORY_URL + '/remove', {})
40 .pipe(
41 map(() => this.restExtractor.extractDataBool()),
42 catchError(err => this.restExtractor.handleError(err))
43 )
44 }
45}
diff --git a/client/src/app/shared/users/user-notification.model.ts b/client/src/app/shared/users/user-notification.model.ts
new file mode 100644
index 000000000..125d2120c
--- /dev/null
+++ b/client/src/app/shared/users/user-notification.model.ts
@@ -0,0 +1,155 @@
1import { UserNotification as UserNotificationServer, UserNotificationType, VideoInfo, ActorInfo } from '../../../../../shared'
2import { Actor } from '@app/shared/actor/actor.model'
3
4export class UserNotification implements UserNotificationServer {
5 id: number
6 type: UserNotificationType
7 read: boolean
8
9 video?: VideoInfo & {
10 channel: ActorInfo & { avatarUrl?: string }
11 }
12
13 videoImport?: {
14 id: number
15 video?: VideoInfo
16 torrentName?: string
17 magnetUri?: string
18 targetUrl?: string
19 }
20
21 comment?: {
22 id: number
23 threadId: number
24 account: ActorInfo & { avatarUrl?: string }
25 video: VideoInfo
26 }
27
28 videoAbuse?: {
29 id: number
30 video: VideoInfo
31 }
32
33 videoBlacklist?: {
34 id: number
35 video: VideoInfo
36 }
37
38 account?: ActorInfo & { avatarUrl?: string }
39
40 actorFollow?: {
41 id: number
42 follower: ActorInfo & { avatarUrl?: string }
43 following: {
44 type: 'account' | 'channel'
45 name: string
46 displayName: string
47 }
48 }
49
50 createdAt: string
51 updatedAt: string
52
53 // Additional fields
54 videoUrl?: string
55 commentUrl?: any[]
56 videoAbuseUrl?: string
57 accountUrl?: string
58 videoImportIdentifier?: string
59 videoImportUrl?: string
60
61 constructor (hash: UserNotificationServer) {
62 this.id = hash.id
63 this.type = hash.type
64 this.read = hash.read
65
66 this.video = hash.video
67 if (this.video) this.setAvatarUrl(this.video.channel)
68
69 this.videoImport = hash.videoImport
70
71 this.comment = hash.comment
72 if (this.comment) this.setAvatarUrl(this.comment.account)
73
74 this.videoAbuse = hash.videoAbuse
75
76 this.videoBlacklist = hash.videoBlacklist
77
78 this.account = hash.account
79 if (this.account) this.setAvatarUrl(this.account)
80
81 this.actorFollow = hash.actorFollow
82 if (this.actorFollow) this.setAvatarUrl(this.actorFollow.follower)
83
84 this.createdAt = hash.createdAt
85 this.updatedAt = hash.updatedAt
86
87 switch (this.type) {
88 case UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION:
89 this.videoUrl = this.buildVideoUrl(this.video)
90 break
91
92 case UserNotificationType.UNBLACKLIST_ON_MY_VIDEO:
93 this.videoUrl = this.buildVideoUrl(this.video)
94 break
95
96 case UserNotificationType.NEW_COMMENT_ON_MY_VIDEO:
97 case UserNotificationType.COMMENT_MENTION:
98 this.accountUrl = this.buildAccountUrl(this.comment.account)
99 this.commentUrl = [ this.buildVideoUrl(this.comment.video), { threadId: this.comment.threadId } ]
100 break
101
102 case UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS:
103 this.videoAbuseUrl = '/admin/moderation/video-abuses/list'
104 this.videoUrl = this.buildVideoUrl(this.videoAbuse.video)
105 break
106
107 case UserNotificationType.BLACKLIST_ON_MY_VIDEO:
108 this.videoUrl = this.buildVideoUrl(this.videoBlacklist.video)
109 break
110
111 case UserNotificationType.MY_VIDEO_PUBLISHED:
112 this.videoUrl = this.buildVideoUrl(this.video)
113 break
114
115 case UserNotificationType.MY_VIDEO_IMPORT_SUCCESS:
116 this.videoImportUrl = this.buildVideoImportUrl()
117 this.videoImportIdentifier = this.buildVideoImportIdentifier(this.videoImport)
118 this.videoUrl = this.buildVideoUrl(this.videoImport.video)
119 break
120
121 case UserNotificationType.MY_VIDEO_IMPORT_ERROR:
122 this.videoImportUrl = this.buildVideoImportUrl()
123 this.videoImportIdentifier = this.buildVideoImportIdentifier(this.videoImport)
124 break
125
126 case UserNotificationType.NEW_USER_REGISTRATION:
127 this.accountUrl = this.buildAccountUrl(this.account)
128 break
129
130 case UserNotificationType.NEW_FOLLOW:
131 this.accountUrl = this.buildAccountUrl(this.actorFollow.follower)
132 break
133 }
134 }
135
136 private buildVideoUrl (video: { uuid: string }) {
137 return '/videos/watch/' + video.uuid
138 }
139
140 private buildAccountUrl (account: { name: string, host: string }) {
141 return '/accounts/' + Actor.CREATE_BY_STRING(account.name, account.host)
142 }
143
144 private buildVideoImportUrl () {
145 return '/my-account/video-imports'
146 }
147
148 private buildVideoImportIdentifier (videoImport: { targetUrl?: string, magnetUri?: string, torrentName?: string }) {
149 return videoImport.targetUrl || videoImport.magnetUri || videoImport.torrentName
150 }
151
152 private setAvatarUrl (actor: { avatarUrl?: string, avatar?: { path: string } }) {
153 actor.avatarUrl = Actor.GET_ACTOR_AVATAR_URL(actor)
154 }
155}
diff --git a/client/src/app/shared/users/user-notification.service.ts b/client/src/app/shared/users/user-notification.service.ts
new file mode 100644
index 000000000..f8a30955d
--- /dev/null
+++ b/client/src/app/shared/users/user-notification.service.ts
@@ -0,0 +1,86 @@
1import { Injectable } from '@angular/core'
2import { HttpClient, HttpParams } from '@angular/common/http'
3import { RestExtractor, RestService } from '../rest'
4import { catchError, map, tap } from 'rxjs/operators'
5import { environment } from '../../../environments/environment'
6import { ResultList, UserNotification as UserNotificationServer, UserNotificationSetting } from '../../../../../shared'
7import { UserNotification } from './user-notification.model'
8import { AuthService } from '../../core'
9import { ComponentPagination } from '../rest/component-pagination.model'
10import { User } from '..'
11import { UserNotificationSocket } from '@app/core/notification/user-notification-socket.service'
12
13@Injectable()
14export class UserNotificationService {
15 static BASE_NOTIFICATIONS_URL = environment.apiUrl + '/api/v1/users/me/notifications'
16 static BASE_NOTIFICATION_SETTINGS = environment.apiUrl + '/api/v1/users/me/notification-settings'
17
18 constructor (
19 private auth: AuthService,
20 private authHttp: HttpClient,
21 private restExtractor: RestExtractor,
22 private restService: RestService,
23 private userNotificationSocket: UserNotificationSocket
24 ) {}
25
26 listMyNotifications (pagination: ComponentPagination, unread?: boolean, ignoreLoadingBar = false) {
27 let params = new HttpParams()
28 params = this.restService.addRestGetParams(params, this.restService.componentPaginationToRestPagination(pagination))
29
30 if (unread) params = params.append('unread', `${unread}`)
31
32 const headers = ignoreLoadingBar ? { ignoreLoadingBar: '' } : undefined
33
34 return this.authHttp.get<ResultList<UserNotification>>(UserNotificationService.BASE_NOTIFICATIONS_URL, { params, headers })
35 .pipe(
36 map(res => this.restExtractor.convertResultListDateToHuman(res)),
37 map(res => this.restExtractor.applyToResultListData(res, this.formatNotification.bind(this))),
38 catchError(err => this.restExtractor.handleError(err))
39 )
40 }
41
42 countUnreadNotifications () {
43 return this.listMyNotifications({ currentPage: 1, itemsPerPage: 0 }, true)
44 .pipe(map(n => n.total))
45 }
46
47 markAsRead (notification: UserNotification) {
48 const url = UserNotificationService.BASE_NOTIFICATIONS_URL + '/read'
49
50 const body = { ids: [ notification.id ] }
51 const headers = { ignoreLoadingBar: '' }
52
53 return this.authHttp.post(url, body, { headers })
54 .pipe(
55 map(this.restExtractor.extractDataBool),
56 tap(() => this.userNotificationSocket.dispatch('read')),
57 catchError(res => this.restExtractor.handleError(res))
58 )
59 }
60
61 markAllAsRead () {
62 const url = UserNotificationService.BASE_NOTIFICATIONS_URL + '/read-all'
63 const headers = { ignoreLoadingBar: '' }
64
65 return this.authHttp.post(url, {}, { headers })
66 .pipe(
67 map(this.restExtractor.extractDataBool),
68 tap(() => this.userNotificationSocket.dispatch('read-all')),
69 catchError(res => this.restExtractor.handleError(res))
70 )
71 }
72
73 updateNotificationSettings (user: User, settings: UserNotificationSetting) {
74 const url = UserNotificationService.BASE_NOTIFICATION_SETTINGS
75
76 return this.authHttp.put(url, settings)
77 .pipe(
78 map(this.restExtractor.extractDataBool),
79 catchError(res => this.restExtractor.handleError(res))
80 )
81 }
82
83 private formatNotification (notification: UserNotificationServer) {
84 return new UserNotification(notification)
85 }
86}
diff --git a/client/src/app/shared/users/user-notifications.component.html b/client/src/app/shared/users/user-notifications.component.html
new file mode 100644
index 000000000..0d69e0feb
--- /dev/null
+++ b/client/src/app/shared/users/user-notifications.component.html
@@ -0,0 +1,101 @@
1<div *ngIf="componentPagination.totalItems === 0" class="no-notification" i18n>You don't have notifications.</div>
2
3<div class="notifications" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()">
4 <div *ngFor="let notification of notifications" class="notification" [ngClass]="{ unread: !notification.read }" (click)="markAsRead(notification)">
5
6 <ng-container [ngSwitch]="notification.type">
7 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION">
8 <img alt="" aria-labelledby="avatar" class="avatar" [src]="notification.video.channel.avatarUrl" />
9
10 <div class="message">
11 {{ notification.video.channel.displayName }} published a <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">new video</a>
12 </div>
13 </ng-container>
14
15 <ng-container i18n *ngSwitchCase="UserNotificationType.UNBLACKLIST_ON_MY_VIDEO">
16 <my-global-icon iconName="undo"></my-global-icon>
17
18 <div class="message">
19 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.video.name }}</a> has been unblacklisted
20 </div>
21 </ng-container>
22
23 <ng-container i18n *ngSwitchCase="UserNotificationType.BLACKLIST_ON_MY_VIDEO">
24 <my-global-icon iconName="no"></my-global-icon>
25
26 <div class="message">
27 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoBlacklist.video.name }}</a> has been blacklisted
28 </div>
29 </ng-container>
30
31 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS">
32 <my-global-icon iconName="alert"></my-global-icon>
33
34 <div class="message">
35 <a (click)="markAsRead(notification)" [routerLink]="notification.videoAbuseUrl">A new video abuse</a> has been created on video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoAbuse.video.name }}</a>
36 </div>
37 </ng-container>
38
39 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_COMMENT_ON_MY_VIDEO">
40 <img alt="" aria-labelledby="avatar" class="avatar" [src]="notification.comment.account.avatarUrl" />
41
42 <div class="message">
43 <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.comment.account.displayName }}</a> commented your video <a (click)="markAsRead(notification)" [routerLink]="notification.commentUrl">{{ notification.comment.video.name }}</a>
44 </div>
45 </ng-container>
46
47 <ng-container i18n *ngSwitchCase="UserNotificationType.MY_VIDEO_PUBLISHED">
48 <my-global-icon iconName="sparkle"></my-global-icon>
49
50 <div class="message">
51 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.video.name }}</a> has been published
52 </div>
53 </ng-container>
54
55 <ng-container i18n *ngSwitchCase="UserNotificationType.MY_VIDEO_IMPORT_SUCCESS">
56 <my-global-icon iconName="cloud-download"></my-global-icon>
57
58 <div class="message">
59 <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">Your video import</a> {{ notification.videoImportIdentifier }} succeeded
60 </div>
61 </ng-container>
62
63 <ng-container i18n *ngSwitchCase="UserNotificationType.MY_VIDEO_IMPORT_ERROR">
64 <my-global-icon iconName="cloud-error"></my-global-icon>
65
66 <div class="message">
67 <a (click)="markAsRead(notification)" [routerLink]="notification.videoImportUrl">Your video import</a> {{ notification.videoImportIdentifier }} failed
68 </div>
69 </ng-container>
70
71 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_USER_REGISTRATION">
72 <my-global-icon iconName="user-add"></my-global-icon>
73
74 <div class="message">
75 User <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.account.name }} registered</a> on your instance
76 </div>
77 </ng-container>
78
79 <ng-container i18n *ngSwitchCase="UserNotificationType.NEW_FOLLOW">
80 <img alt="" aria-labelledby="avatar" class="avatar" [src]="notification.actorFollow.follower.avatarUrl" />
81
82 <div class="message">
83 <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.actorFollow.follower.displayName }}</a> is following
84
85 <ng-container *ngIf="notification.actorFollow.following.type === 'channel'">your channel {{ notification.actorFollow.following.displayName }}</ng-container>
86 <ng-container *ngIf="notification.actorFollow.following.type === 'account'">your account</ng-container>
87 </div>
88 </ng-container>
89
90 <ng-container i18n *ngSwitchCase="UserNotificationType.COMMENT_MENTION">
91 <img alt="" aria-labelledby="avatar" class="avatar" [src]="notification.comment.account.avatarUrl" />
92
93 <div class="message">
94 <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.comment.account.displayName }}</a> mentioned you on <a (click)="markAsRead(notification)" [routerLink]="notification.commentUrl">video {{ notification.comment.video.name }}</a>
95 </div>
96 </ng-container>
97 </ng-container>
98
99 <div class="from-date">{{ notification.createdAt | myFromNow }}</div>
100 </div>
101</div>
diff --git a/client/src/app/shared/users/user-notifications.component.scss b/client/src/app/shared/users/user-notifications.component.scss
new file mode 100644
index 000000000..315d504c9
--- /dev/null
+++ b/client/src/app/shared/users/user-notifications.component.scss
@@ -0,0 +1,51 @@
1@import '_variables';
2@import '_mixins';
3
4.no-notification {
5 display: flex;
6 justify-content: center;
7 align-items: center;
8 padding: 20px 0;
9}
10
11.notification {
12 display: flex;
13 align-items: center;
14 font-size: inherit;
15 padding: 15px 5px 15px 10px;
16 border-bottom: 1px solid rgba(0, 0, 0, 0.10);
17
18 &.unread {
19 background-color: rgba(0, 0, 0, 0.05);
20 }
21
22 my-global-icon {
23 width: 24px;
24 margin-right: 11px;
25 margin-left: 3px;
26
27 @include apply-svg-color(#333);
28 }
29
30 .avatar {
31 @include avatar(30px);
32
33 margin-right: 10px;
34 }
35
36 .message {
37 flex-grow: 1;
38
39 a {
40 font-weight: $font-semibold;
41 }
42 }
43
44 .from-date {
45 font-size: 0.85em;
46 color: $grey-foreground-color;
47 padding-left: 5px;
48 min-width: 70px;
49 text-align: right;
50 }
51}
diff --git a/client/src/app/shared/users/user-notifications.component.ts b/client/src/app/shared/users/user-notifications.component.ts
new file mode 100644
index 000000000..b5f9fd399
--- /dev/null
+++ b/client/src/app/shared/users/user-notifications.component.ts
@@ -0,0 +1,87 @@
1import { Component, Input, OnInit } from '@angular/core'
2import { UserNotificationService } from '@app/shared/users/user-notification.service'
3import { UserNotificationType } from '../../../../../shared'
4import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model'
5import { Notifier } from '@app/core'
6import { UserNotification } from '@app/shared/users/user-notification.model'
7
8@Component({
9 selector: 'my-user-notifications',
10 templateUrl: 'user-notifications.component.html',
11 styleUrls: [ 'user-notifications.component.scss' ]
12})
13export class UserNotificationsComponent implements OnInit {
14 @Input() ignoreLoadingBar = false
15 @Input() infiniteScroll = true
16 @Input() itemsPerPage = 20
17
18 notifications: UserNotification[] = []
19
20 // So we can access it in the template
21 UserNotificationType = UserNotificationType
22
23 componentPagination: ComponentPagination
24
25 constructor (
26 private userNotificationService: UserNotificationService,
27 private notifier: Notifier
28 ) { }
29
30 ngOnInit () {
31 this.componentPagination = {
32 currentPage: 1,
33 itemsPerPage: this.itemsPerPage, // Reset items per page, because of the @Input() variable
34 totalItems: null
35 }
36
37 this.loadMoreNotifications()
38 }
39
40 loadMoreNotifications () {
41 this.userNotificationService.listMyNotifications(this.componentPagination, undefined, this.ignoreLoadingBar)
42 .subscribe(
43 result => {
44 this.notifications = this.notifications.concat(result.data)
45 this.componentPagination.totalItems = result.total
46 },
47
48 err => this.notifier.error(err.message)
49 )
50 }
51
52 onNearOfBottom () {
53 if (this.infiniteScroll === false) return
54
55 this.componentPagination.currentPage++
56
57 if (hasMoreItems(this.componentPagination)) {
58 this.loadMoreNotifications()
59 }
60 }
61
62 markAsRead (notification: UserNotification) {
63 if (notification.read) return
64
65 this.userNotificationService.markAsRead(notification)
66 .subscribe(
67 () => {
68 notification.read = true
69 },
70
71 err => this.notifier.error(err.message)
72 )
73 }
74
75 markAllAsRead () {
76 this.userNotificationService.markAllAsRead()
77 .subscribe(
78 () => {
79 for (const notification of this.notifications) {
80 notification.read = true
81 }
82 },
83
84 err => this.notifier.error(err.message)
85 )
86 }
87}
diff --git a/client/src/app/shared/users/user.model.ts b/client/src/app/shared/users/user.model.ts
index 9819829fd..c15f1de8c 100644
--- a/client/src/app/shared/users/user.model.ts
+++ b/client/src/app/shared/users/user.model.ts
@@ -1,33 +1,8 @@
1import { 1import { hasUserRight, User as UserServerModel, UserNotificationSetting, UserRight, UserRole, VideoChannel } from '../../../../../shared'
2 Account as AccountServerModel,
3 hasUserRight,
4 User as UserServerModel,
5 UserRight,
6 UserRole,
7 VideoChannel
8} from '../../../../../shared'
9import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type' 2import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type'
10import { Account } from '@app/shared/account/account.model' 3import { Account } from '@app/shared/account/account.model'
11import { Avatar } from '../../../../../shared/models/avatars/avatar.model' 4import { Avatar } from '../../../../../shared/models/avatars/avatar.model'
12 5
13export type UserConstructorHash = {
14 id: number,
15 username: string,
16 email: string,
17 role: UserRole,
18 emailVerified?: boolean,
19 videoQuota?: number,
20 videoQuotaDaily?: number,
21 nsfwPolicy?: NSFWPolicyType,
22 webTorrentEnabled?: boolean,
23 autoPlayVideo?: boolean,
24 createdAt?: Date,
25 account?: AccountServerModel,
26 videoChannels?: VideoChannel[]
27
28 blocked?: boolean
29 blockedReason?: string
30}
31export class User implements UserServerModel { 6export class User implements UserServerModel {
32 id: number 7 id: number
33 username: string 8 username: string
@@ -35,8 +10,11 @@ export class User implements UserServerModel {
35 emailVerified: boolean 10 emailVerified: boolean
36 role: UserRole 11 role: UserRole
37 nsfwPolicy: NSFWPolicyType 12 nsfwPolicy: NSFWPolicyType
13
38 webTorrentEnabled: boolean 14 webTorrentEnabled: boolean
39 autoPlayVideo: boolean 15 autoPlayVideo: boolean
16 videosHistoryEnabled: boolean
17
40 videoQuota: number 18 videoQuota: number
41 videoQuotaDaily: number 19 videoQuotaDaily: number
42 account: Account 20 account: Account
@@ -46,7 +24,9 @@ export class User implements UserServerModel {
46 blocked: boolean 24 blocked: boolean
47 blockedReason?: string 25 blockedReason?: string
48 26
49 constructor (hash: UserConstructorHash) { 27 notificationSettings?: UserNotificationSetting
28
29 constructor (hash: Partial<UserServerModel>) {
50 this.id = hash.id 30 this.id = hash.id
51 this.username = hash.username 31 this.username = hash.username
52 this.email = hash.email 32 this.email = hash.email
@@ -57,11 +37,14 @@ export class User implements UserServerModel {
57 this.videoQuotaDaily = hash.videoQuotaDaily 37 this.videoQuotaDaily = hash.videoQuotaDaily
58 this.nsfwPolicy = hash.nsfwPolicy 38 this.nsfwPolicy = hash.nsfwPolicy
59 this.webTorrentEnabled = hash.webTorrentEnabled 39 this.webTorrentEnabled = hash.webTorrentEnabled
40 this.videosHistoryEnabled = hash.videosHistoryEnabled
60 this.autoPlayVideo = hash.autoPlayVideo 41 this.autoPlayVideo = hash.autoPlayVideo
61 this.createdAt = hash.createdAt 42 this.createdAt = hash.createdAt
62 this.blocked = hash.blocked 43 this.blocked = hash.blocked
63 this.blockedReason = hash.blockedReason 44 this.blockedReason = hash.blockedReason
64 45
46 this.notificationSettings = hash.notificationSettings
47
65 if (hash.account !== undefined) { 48 if (hash.account !== undefined) {
66 this.account = new Account(hash.account) 49 this.account = new Account(hash.account)
67 } 50 }
diff --git a/client/src/app/shared/video-abuse/video-abuse.service.ts b/client/src/app/shared/video-abuse/video-abuse.service.ts
index 61b7e1b98..b0b59ea0c 100644
--- a/client/src/app/shared/video-abuse/video-abuse.service.ts
+++ b/client/src/app/shared/video-abuse/video-abuse.service.ts
@@ -32,9 +32,7 @@ export class VideoAbuseService {
32 32
33 reportVideo (id: number, reason: string) { 33 reportVideo (id: number, reason: string) {
34 const url = VideoAbuseService.BASE_VIDEO_ABUSE_URL + id + '/abuse' 34 const url = VideoAbuseService.BASE_VIDEO_ABUSE_URL + id + '/abuse'
35 const body = { 35 const body = { reason }
36 reason
37 }
38 36
39 return this.authHttp.post(url, body) 37 return this.authHttp.post(url, body)
40 .pipe( 38 .pipe(
diff --git a/client/src/app/shared/video-blacklist/video-blacklist.service.ts b/client/src/app/shared/video-blacklist/video-blacklist.service.ts
index 7d39fd4f2..94e46d7c2 100644
--- a/client/src/app/shared/video-blacklist/video-blacklist.service.ts
+++ b/client/src/app/shared/video-blacklist/video-blacklist.service.ts
@@ -36,8 +36,11 @@ export class VideoBlacklistService {
36 ) 36 )
37 } 37 }
38 38
39 blacklistVideo (videoId: number, reason?: string) { 39 blacklistVideo (videoId: number, reason: string, unfederate: boolean) {
40 const body = reason ? { reason } : {} 40 const body = {
41 unfederate,
42 reason
43 }
41 44
42 return this.authHttp.post(VideoBlacklistService.BASE_VIDEOS_URL + videoId + '/blacklist', body) 45 return this.authHttp.post(VideoBlacklistService.BASE_VIDEOS_URL + videoId + '/blacklist', body)
43 .pipe( 46 .pipe(
diff --git a/client/src/app/shared/video/abstract-video-list.html b/client/src/app/shared/video/abstract-video-list.html
index 29492351b..1f97bc389 100644
--- a/client/src/app/shared/video/abstract-video-list.html
+++ b/client/src/app/shared/video/abstract-video-list.html
@@ -1,8 +1,11 @@
1<div [ngClass]="{ 'margin-content': marginContent }"> 1<div [ngClass]="{ 'margin-content': marginContent }">
2 <div class="videos-header"> 2 <div class="videos-header">
3 <div *ngIf="titlePage" class="title-page title-page-single"> 3 <div *ngIf="titlePage" class="title-page title-page-single">
4 {{ titlePage }} 4 <div placement="bottom" [ngbTooltip]="titleTooltip" container="body">
5 {{ titlePage }}
6 </div>
5 </div> 7 </div>
8
6 <my-feed [syndicationItems]="syndicationItems"></my-feed> 9 <my-feed [syndicationItems]="syndicationItems"></my-feed>
7 10
8 <div class="moderation-block" *ngIf="displayModerationBlock"> 11 <div class="moderation-block" *ngIf="displayModerationBlock">
diff --git a/client/src/app/shared/video/abstract-video-list.scss b/client/src/app/shared/video/abstract-video-list.scss
index 9fb3fd4d6..292ede698 100644
--- a/client/src/app/shared/video/abstract-video-list.scss
+++ b/client/src/app/shared/video/abstract-video-list.scss
@@ -19,8 +19,8 @@
19 19
20 my-feed { 20 my-feed {
21 display: inline-block; 21 display: inline-block;
22 position: relative;
23 top: 1px; 22 top: 1px;
23 min-width: 60px;
24 } 24 }
25 25
26 .moderation-block { 26 .moderation-block {
diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts
index 2d32dd6ad..b0633be4a 100644
--- a/client/src/app/shared/video/abstract-video-list.ts
+++ b/client/src/app/shared/video/abstract-video-list.ts
@@ -3,7 +3,6 @@ import { ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core'
3import { ActivatedRoute, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
4import { Location } from '@angular/common' 4import { Location } from '@angular/common'
5import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' 5import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive'
6import { NotificationsService } from 'angular2-notifications'
7import { fromEvent, Observable, Subscription } from 'rxjs' 6import { fromEvent, Observable, Subscription } from 'rxjs'
8import { AuthService } from '../../core/auth' 7import { AuthService } from '../../core/auth'
9import { ComponentPagination } from '../rest/component-pagination.model' 8import { ComponentPagination } from '../rest/component-pagination.model'
@@ -13,6 +12,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
13import { ScreenService } from '@app/shared/misc/screen.service' 12import { ScreenService } from '@app/shared/misc/screen.service'
14import { OwnerDisplayType } from '@app/shared/video/video-miniature.component' 13import { OwnerDisplayType } from '@app/shared/video/video-miniature.component'
15import { Syndication } from '@app/shared/video/syndication.model' 14import { Syndication } from '@app/shared/video/syndication.model'
15import { Notifier } from '@app/core'
16 16
17export abstract class AbstractVideoList implements OnInit, OnDestroy { 17export abstract class AbstractVideoList implements OnInit, OnDestroy {
18 private static LINES_PER_PAGE = 4 18 private static LINES_PER_PAGE = 4
@@ -39,11 +39,12 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
39 ownerDisplayType: OwnerDisplayType = 'account' 39 ownerDisplayType: OwnerDisplayType = 'account'
40 firstLoadedPage: number 40 firstLoadedPage: number
41 displayModerationBlock = false 41 displayModerationBlock = false
42 titleTooltip: string
42 43
43 protected baseVideoWidth = 215 44 protected baseVideoWidth = 215
44 protected baseVideoHeight = 205 45 protected baseVideoHeight = 205
45 46
46 protected abstract notificationsService: NotificationsService 47 protected abstract notifier: Notifier
47 protected abstract authService: AuthService 48 protected abstract authService: AuthService
48 protected abstract router: Router 49 protected abstract router: Router
49 protected abstract route: ActivatedRoute 50 protected abstract route: ActivatedRoute
@@ -157,7 +158,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
157 }, 158 },
158 error => { 159 error => {
159 this.loadingPage[page] = false 160 this.loadingPage[page] = false
160 this.notificationsService.error(this.i18n('Error'), error.message) 161 this.notifier.error(error.message)
161 } 162 }
162 ) 163 )
163 } 164 }
diff --git a/client/src/app/shared/video/feed.component.html b/client/src/app/shared/video/feed.component.html
index 16116ba88..f7624ec01 100644
--- a/client/src/app/shared/video/feed.component.html
+++ b/client/src/app/shared/video/feed.component.html
@@ -1,10 +1,11 @@
1<div class="video-feed"> 1<div class="video-feed">
2 <span 2 <my-global-icon
3 *ngIf="syndicationItems.length !== 0" [ngbPopover]="feedsList" [autoClose]="true" placement="bottom" 3 *ngIf="syndicationItems.length !== 0" [ngbPopover]="feedsList" [autoClose]="true" placement="bottom"
4 class="icon icon-syndication" role="button" 4 class="icon-syndication" role="button" iconName="syndication"
5 ></span> 5 >
6 </my-global-icon>
6 7
7 <ng-template #feedsList> 8 <ng-template #feedsList>
8 <a *ngFor="let item of syndicationItems" [href]="item.url" target="_blank" rel="noopener noreferrer">{{ item.label }}</a> 9 <a *ngFor="let item of syndicationItems" [href]="item.url" target="_blank" rel="noopener noreferrer">{{ item.label }}</a>
9 </ng-template> 10 </ng-template>
10</div> \ No newline at end of file 11</div>
diff --git a/client/src/app/shared/video/feed.component.scss b/client/src/app/shared/video/feed.component.scss
index 385764be0..ed1dc17d3 100644
--- a/client/src/app/shared/video/feed.component.scss
+++ b/client/src/app/shared/video/feed.component.scss
@@ -1,3 +1,4 @@
1@import '_variables';
1@import '_mixins'; 2@import '_mixins';
2 3
3.video-feed { 4.video-feed {
@@ -6,14 +7,12 @@
6 display: block; 7 display: block;
7 } 8 }
8 9
9 .icon { 10 my-global-icon {
10 @include icon(12px); 11 cursor: pointer;
12 width: 12px;
13 position: relative;
14 top: -2px;
11 15
12 &.icon-syndication { 16 @include apply-svg-color(var(--mainForegroundColor))
13 position: relative;
14 top: -2px;
15 background-color: var(--mainForegroundColor);
16 mask-image: url('../../../assets/images/global/syndication.svg');
17 }
18 } 17 }
19} \ No newline at end of file 18}
diff --git a/client/src/app/shared/video/video-miniature.component.scss b/client/src/app/shared/video/video-miniature.component.scss
index 895879adc..f44bdf9a9 100644
--- a/client/src/app/shared/video/video-miniature.component.scss
+++ b/client/src/app/shared/video/video-miniature.component.scss
@@ -50,10 +50,10 @@
50 text-overflow: ellipsis; 50 text-overflow: ellipsis;
51 white-space: nowrap; 51 white-space: nowrap;
52 font-size: 13px; 52 font-size: 13px;
53 color: #585858; 53 color: $grey-foreground-color;
54 54
55 &:hover { 55 &:hover {
56 color: #303030; 56 color: $grey-foreground-hover-color;
57 } 57 }
58 } 58 }
59 } 59 }
diff --git a/client/src/app/shared/video/video.model.ts b/client/src/app/shared/video/video.model.ts
index b92c96450..6ea83d13b 100644
--- a/client/src/app/shared/video/video.model.ts
+++ b/client/src/app/shared/video/video.model.ts
@@ -53,7 +53,7 @@ export class Video implements VideoServerModel {
53 displayName: string 53 displayName: string
54 url: string 54 url: string
55 host: string 55 host: string
56 avatar: Avatar 56 avatar?: Avatar
57 } 57 }
58 58
59 channel: { 59 channel: {
@@ -63,7 +63,7 @@ export class Video implements VideoServerModel {
63 displayName: string 63 displayName: string
64 url: string 64 url: string
65 host: string 65 host: string
66 avatar: Avatar 66 avatar?: Avatar
67 } 67 }
68 68
69 userHistory?: { 69 userHistory?: {
diff --git a/client/src/app/signup/signup.component.html b/client/src/app/signup/signup.component.html
index 0207a166e..07d24b381 100644
--- a/client/src/app/signup/signup.component.html
+++ b/client/src/app/signup/signup.component.html
@@ -64,7 +64,7 @@
64 </form> 64 </form>
65 65
66 <div> 66 <div>
67 <label for="email" i18n>Features found on this instance</label> 67 <label i18n>Features found on this instance</label>
68 <my-instance-features-table></my-instance-features-table> 68 <my-instance-features-table></my-instance-features-table>
69 </div> 69 </div>
70 </div> 70 </div>
diff --git a/client/src/app/signup/signup.component.ts b/client/src/app/signup/signup.component.ts
index 3341d4e09..13941ec79 100644
--- a/client/src/app/signup/signup.component.ts
+++ b/client/src/app/signup/signup.component.ts
@@ -1,8 +1,7 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { AuthService, Notifier, RedirectService, ServerService } from '@app/core'
3import { UserCreate } from '../../../../shared' 3import { UserCreate } from '../../../../shared'
4import { FormReactive, UserService, UserValidatorsService } from '../shared' 4import { FormReactive, UserService, UserValidatorsService } from '../shared'
5import { AuthService, RedirectService, ServerService } from '@app/core'
6import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
7import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
8 7
@@ -20,7 +19,7 @@ export class SignupComponent extends FormReactive implements OnInit {
20 protected formValidatorService: FormValidatorService, 19 protected formValidatorService: FormValidatorService,
21 private authService: AuthService, 20 private authService: AuthService,
22 private userValidatorsService: UserValidatorsService, 21 private userValidatorsService: UserValidatorsService,
23 private notificationsService: NotificationsService, 22 private notifier: Notifier,
24 private userService: UserService, 23 private userService: UserService,
25 private serverService: ServerService, 24 private serverService: ServerService,
26 private redirectService: RedirectService, 25 private redirectService: RedirectService,
@@ -64,10 +63,7 @@ export class SignupComponent extends FormReactive implements OnInit {
64 this.authService.login(userCreate.username, userCreate.password) 63 this.authService.login(userCreate.username, userCreate.password)
65 .subscribe( 64 .subscribe(
66 () => { 65 () => {
67 this.notificationsService.success( 66 this.notifier.success(this.i18n('You are now logged in as {{username}}!', { username: userCreate.username }))
68 this.i18n('Success'),
69 this.i18n('You are now logged in as {{username}}!', { username: userCreate.username })
70 )
71 67
72 this.redirectService.redirectToHomepage() 68 this.redirectService.redirectToHomepage()
73 }, 69 },
diff --git a/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.html b/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.html
index 30aefdbfc..19043eee6 100644
--- a/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.html
+++ b/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.html
@@ -3,7 +3,7 @@
3 3
4 <div class="modal-header"> 4 <div class="modal-header">
5 <h4 i18n class="modal-title">Add caption</h4> 5 <h4 i18n class="modal-title">Add caption</h4>
6 <span class="close" aria-label="Close" role="button" (click)="hide()"></span> 6 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
7 </div> 7 </div>
8 8
9 <div class="modal-body"> 9 <div class="modal-body">
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.html b/client/src/app/videos/+video-edit/shared/video-edit.component.html
index 33c766d87..092c0e862 100644
--- a/client/src/app/videos/+video-edit/shared/video-edit.component.html
+++ b/client/src/app/videos/+video-edit/shared/video-edit.component.html
@@ -126,6 +126,7 @@
126 ></my-peertube-checkbox> 126 ></my-peertube-checkbox>
127 127
128 <my-peertube-checkbox 128 <my-peertube-checkbox
129 *ngIf="waitTranscodingEnabled"
129 inputName="waitTranscoding" formControlName="waitTranscoding" 130 inputName="waitTranscoding" formControlName="waitTranscoding"
130 i18n-labelText labelText="Wait transcoding before publishing the video" 131 i18n-labelText labelText="Wait transcoding before publishing the video"
131 i18n-helpHtml helpHtml="If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends." 132 i18n-helpHtml helpHtml="If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends."
@@ -142,7 +143,7 @@
142 143
143 <div class="captions-header"> 144 <div class="captions-header">
144 <a (click)="openAddCaptionModal()" class="create-caption"> 145 <a (click)="openAddCaptionModal()" class="create-caption">
145 <span class="icon icon-add"></span> 146 <my-global-icon iconName="add"></my-global-icon>
146 <ng-container i18n>Add another caption</ng-container> 147 <ng-container i18n>Add another caption</ng-container>
147 </a> 148 </a>
148 </div> 149 </div>
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.scss b/client/src/app/videos/+video-edit/shared/video-edit.component.scss
index 25db8e8ed..bb775cb0a 100644
--- a/client/src/app/videos/+video-edit/shared/video-edit.component.scss
+++ b/client/src/app/videos/+video-edit/shared/video-edit.component.scss
@@ -23,10 +23,6 @@ my-peertube-checkbox {
23 display: block; 23 display: block;
24 } 24 }
25 25
26 input, select {
27 font-size: 15px
28 }
29
30 .label-tags + span { 26 .label-tags + span {
31 font-size: 15px; 27 font-size: 15px;
32 } 28 }
@@ -42,7 +38,7 @@ my-peertube-checkbox {
42 text-align: right; 38 text-align: right;
43 39
44 .create-caption { 40 .create-caption {
45 @include create-button('../../../../assets/images/global/add.svg'); 41 @include create-button;
46 } 42 }
47 } 43 }
48 44
@@ -100,13 +96,14 @@ my-peertube-checkbox {
100 display: inline-block; 96 display: inline-block;
101 margin-right: 25px; 97 margin-right: 25px;
102 98
103 color: #585858; 99 color: $grey-foreground-color;
104 font-size: 15px; 100 font-size: 15px;
105 } 101 }
106 102
107 .submit-button { 103 .submit-button {
108 @include peertube-button; 104 @include peertube-button;
109 @include orange-button; 105 @include orange-button;
106 @include button-with-icon(20px, 1px);
110 107
111 display: inline-block; 108 display: inline-block;
112 109
@@ -119,16 +116,6 @@ my-peertube-checkbox {
119 color: inherit; 116 color: inherit;
120 font-weight: $font-semibold; 117 font-weight: $font-semibold;
121 } 118 }
122
123 .icon.icon-validate {
124 @include icon(20px);
125
126 cursor: inherit;
127 position: relative;
128 top: -1px;
129 margin-right: 4px;
130 background-image: url('../../../../assets/images/global/validate.svg');
131 }
132 } 119 }
133} 120}
134 121
@@ -176,10 +163,10 @@ p-calendar {
176 } 163 }
177 164
178 tag { 165 tag {
179 background-color: var(--inputColor) !important; 166 background-color: $grey-background-color !important;
167 color: #000 !important;
180 border-radius: 3px !important; 168 border-radius: 3px !important;
181 font-size: 15px !important; 169 font-size: 15px !important;
182 color: var(--mainForegroundColor) !important;
183 height: 30px !important; 170 height: 30px !important;
184 line-height: 30px !important; 171 line-height: 30px !important;
185 margin: 0 5px 0 0 !important; 172 margin: 0 5px 0 0 !important;
@@ -202,7 +189,10 @@ p-calendar {
202 top: -1px; 189 top: -1px;
203 height: auto !important; 190 height: auto !important;
204 vertical-align: middle !important; 191 vertical-align: middle !important;
205 fill: #585858 !important; 192
193 path {
194 fill: $grey-foreground-color !important;
195 }
206 } 196 }
207 197
208 &:hover { 198 &:hover {
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.ts b/client/src/app/videos/+video-edit/shared/video-edit.component.ts
index a56733e57..85e015901 100644
--- a/client/src/app/videos/+video-edit/shared/video-edit.component.ts
+++ b/client/src/app/videos/+video-edit/shared/video-edit.component.ts
@@ -2,7 +2,7 @@ import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'
2import { FormArray, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms' 2import { FormArray, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'
3import { ActivatedRoute, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
4import { FormReactiveValidationMessages, VideoValidatorsService } from '@app/shared' 4import { FormReactiveValidationMessages, VideoValidatorsService } from '@app/shared'
5import { NotificationsService } from 'angular2-notifications' 5import { Notifier } from '@app/core'
6import { ServerService } from '../../../core/server' 6import { ServerService } from '../../../core/server'
7import { VideoEdit } from '../../../shared/video/video-edit.model' 7import { VideoEdit } from '../../../shared/video/video-edit.model'
8import { map } from 'rxjs/operators' 8import { map } from 'rxjs/operators'
@@ -27,6 +27,7 @@ export class VideoEditComponent implements OnInit, OnDestroy {
27 @Input() userVideoChannels: { id: number, label: string, support: string }[] = [] 27 @Input() userVideoChannels: { id: number, label: string, support: string }[] = []
28 @Input() schedulePublicationPossible = true 28 @Input() schedulePublicationPossible = true
29 @Input() videoCaptions: VideoCaptionEdit[] = [] 29 @Input() videoCaptions: VideoCaptionEdit[] = []
30 @Input() waitTranscodingEnabled = true
30 31
31 @ViewChild('videoCaptionAddModal') videoCaptionAddModal: VideoCaptionAddModalComponent 32 @ViewChild('videoCaptionAddModal') videoCaptionAddModal: VideoCaptionAddModalComponent
32 33
@@ -58,7 +59,7 @@ export class VideoEditComponent implements OnInit, OnDestroy {
58 private videoCaptionService: VideoCaptionService, 59 private videoCaptionService: VideoCaptionService,
59 private route: ActivatedRoute, 60 private route: ActivatedRoute,
60 private router: Router, 61 private router: Router,
61 private notificationsService: NotificationsService, 62 private notifier: Notifier,
62 private serverService: ServerService, 63 private serverService: ServerService,
63 private i18nPrimengCalendarService: I18nPrimengCalendarService 64 private i18nPrimengCalendarService: I18nPrimengCalendarService
64 ) { 65 ) {
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.html b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.html
index 11a81ad66..28eb143c9 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.html
+++ b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.html
@@ -1,6 +1,6 @@
1<div *ngIf="!hasImportedVideo" class="upload-video-container"> 1<div *ngIf="!hasImportedVideo" class="upload-video-container">
2 <div class="import-video-torrent"> 2 <div class="first-step-block">
3 <div class="icon icon-upload"></div> 3 <my-global-icon class="upload-icon" iconName="upload"></my-global-icon>
4 4
5 <div class="button-file"> 5 <div class="button-file">
6 <span i18n>Select the torrent to import</span> 6 <span i18n>Select the torrent to import</span>
@@ -66,7 +66,7 @@
66 (click)="updateSecondStep()" 66 (click)="updateSecondStep()"
67 [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }" 67 [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }"
68 > 68 >
69 <span class="icon icon-validate"></span> 69 <my-global-icon iconName="validate"></my-global-icon>
70 <input type="button" i18n-value value="Update" /> 70 <input type="button" i18n-value value="Update" />
71 </div> 71 </div>
72 </div> 72 </div>
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.scss b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.scss
index 00626cd7b..6d59ed834 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.scss
+++ b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.scss
@@ -1,45 +1,7 @@
1@import 'variables'; 1@import 'variables';
2@import 'mixins'; 2@import 'mixins';
3 3
4$width-size: 190px; 4.first-step-block {
5
6.peertube-select-container {
7 @include peertube-select-container($width-size);
8}
9
10.alert.alert-danger {
11 text-align: center;
12
13 & > div {
14 font-weight: $font-semibold;
15 }
16}
17
18.import-video-torrent {
19 display: flex;
20 flex-direction: column;
21 align-items: center;
22
23 .icon.icon-upload {
24 @include icon(90px);
25 margin-bottom: 25px;
26 cursor: default;
27
28 background-image: url('../../../../assets/images/video/upload.svg');
29 }
30
31 .button-file {
32 @include peertube-button-file(auto);
33
34 min-width: 190px;
35 }
36
37 .button-file-extension {
38 display: block;
39 font-size: 12px;
40 margin-top: 5px;
41 }
42
43 .torrent-or-magnet { 5 .torrent-or-magnet {
44 margin: 10px 0; 6 margin: 10px 0;
45 } 7 }
@@ -47,19 +9,6 @@ $width-size: 190px;
47 .form-group-magnet-uri { 9 .form-group-magnet-uri {
48 margin-bottom: 40px; 10 margin-bottom: 40px;
49 } 11 }
50
51 input[type=text] {
52 @include peertube-input-text($width-size);
53 display: block;
54 }
55
56 input[type=button] {
57 @include peertube-button;
58 @include orange-button;
59
60 width: $width-size;
61 margin-top: 30px;
62 }
63} 12}
64 13
65 14
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts
index 13776ae36..307806bb9 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts
+++ b/client/src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts
@@ -1,8 +1,7 @@
1import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild } from '@angular/core' 1import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications'
4import { VideoPrivacy, VideoUpdate } from '../../../../../../shared/models/videos' 3import { VideoPrivacy, VideoUpdate } from '../../../../../../shared/models/videos'
5import { AuthService, ServerService } from '../../../core' 4import { AuthService, Notifier, ServerService } from '../../../core'
6import { VideoService } from '../../../shared/video/video.service' 5import { VideoService } from '../../../shared/video/video.service'
7import { I18n } from '@ngx-translate/i18n-polyfill' 6import { I18n } from '@ngx-translate/i18n-polyfill'
8import { LoadingBarService } from '@ngx-loading-bar/core' 7import { LoadingBarService } from '@ngx-loading-bar/core'
@@ -19,7 +18,8 @@ import { scrollToTop } from '@app/shared/misc/utils'
19 templateUrl: './video-import-torrent.component.html', 18 templateUrl: './video-import-torrent.component.html',
20 styleUrls: [ 19 styleUrls: [
21 '../shared/video-edit.component.scss', 20 '../shared/video-edit.component.scss',
22 './video-import-torrent.component.scss' 21 './video-import-torrent.component.scss',
22 './video-send.scss'
23 ] 23 ]
24}) 24})
25export class VideoImportTorrentComponent extends VideoSend implements OnInit, CanComponentDeactivate { 25export class VideoImportTorrentComponent extends VideoSend implements OnInit, CanComponentDeactivate {
@@ -41,7 +41,7 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca
41 constructor ( 41 constructor (
42 protected formValidatorService: FormValidatorService, 42 protected formValidatorService: FormValidatorService,
43 protected loadingBar: LoadingBarService, 43 protected loadingBar: LoadingBarService,
44 protected notificationsService: NotificationsService, 44 protected notifier: Notifier,
45 protected authService: AuthService, 45 protected authService: AuthService,
46 protected serverService: ServerService, 46 protected serverService: ServerService,
47 protected videoService: VideoService, 47 protected videoService: VideoService,
@@ -107,7 +107,7 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca
107 this.loadingBar.complete() 107 this.loadingBar.complete()
108 this.isImportingVideo = false 108 this.isImportingVideo = false
109 this.firstStepError.emit() 109 this.firstStepError.emit()
110 this.notificationsService.error(this.i18n('Error'), err.message) 110 this.notifier.error(err.message)
111 } 111 }
112 ) 112 )
113 } 113 }
@@ -126,7 +126,7 @@ export class VideoImportTorrentComponent extends VideoSend implements OnInit, Ca
126 .subscribe( 126 .subscribe(
127 () => { 127 () => {
128 this.isUpdatingVideo = false 128 this.isUpdatingVideo = false
129 this.notificationsService.success(this.i18n('Success'), this.i18n('Video to import updated.')) 129 this.notifier.success(this.i18n('Video to import updated.'))
130 130
131 this.router.navigate([ '/my-account', 'video-imports' ]) 131 this.router.navigate([ '/my-account', 'video-imports' ])
132 }, 132 },
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html
index 533446672..3550c3585 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html
+++ b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.html
@@ -1,6 +1,6 @@
1<div *ngIf="!hasImportedVideo" class="upload-video-container"> 1<div *ngIf="!hasImportedVideo" class="upload-video-container">
2 <div class="import-video-url"> 2 <div class="first-step-block">
3 <div class="icon icon-upload"></div> 3 <my-global-icon class="upload-icon" iconName="upload"></my-global-icon>
4 4
5 <div class="form-group"> 5 <div class="form-group">
6 <label i18n for="targetUrl">URL</label> 6 <label i18n for="targetUrl">URL</label>
@@ -59,7 +59,7 @@
59 (click)="updateSecondStep()" 59 (click)="updateSecondStep()"
60 [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }" 60 [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }"
61 > 61 >
62 <span class="icon icon-validate"></span> 62 <my-global-icon iconName="validate"></my-global-icon>
63 <input type="button" i18n-value value="Update" /> 63 <input type="button" i18n-value value="Update" />
64 </div> 64 </div>
65 </div> 65 </div>
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts
index 9cdface75..257c6e5db 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts
+++ b/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.ts
@@ -1,8 +1,7 @@
1import { Component, EventEmitter, OnInit, Output } from '@angular/core' 1import { Component, EventEmitter, OnInit, Output } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications'
4import { VideoPrivacy, VideoUpdate } from '../../../../../../shared/models/videos' 3import { VideoPrivacy, VideoUpdate } from '../../../../../../shared/models/videos'
5import { AuthService, ServerService } from '../../../core' 4import { AuthService, Notifier, ServerService } from '../../../core'
6import { VideoService } from '../../../shared/video/video.service' 5import { VideoService } from '../../../shared/video/video.service'
7import { I18n } from '@ngx-translate/i18n-polyfill' 6import { I18n } from '@ngx-translate/i18n-polyfill'
8import { LoadingBarService } from '@ngx-loading-bar/core' 7import { LoadingBarService } from '@ngx-loading-bar/core'
@@ -19,7 +18,7 @@ import { scrollToTop } from '@app/shared/misc/utils'
19 templateUrl: './video-import-url.component.html', 18 templateUrl: './video-import-url.component.html',
20 styleUrls: [ 19 styleUrls: [
21 '../shared/video-edit.component.scss', 20 '../shared/video-edit.component.scss',
22 './video-import-url.component.scss' 21 './video-send.scss'
23 ] 22 ]
24}) 23})
25export class VideoImportUrlComponent extends VideoSend implements OnInit, CanComponentDeactivate { 24export class VideoImportUrlComponent extends VideoSend implements OnInit, CanComponentDeactivate {
@@ -40,7 +39,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom
40 constructor ( 39 constructor (
41 protected formValidatorService: FormValidatorService, 40 protected formValidatorService: FormValidatorService,
42 protected loadingBar: LoadingBarService, 41 protected loadingBar: LoadingBarService,
43 protected notificationsService: NotificationsService, 42 protected notifier: Notifier,
44 protected authService: AuthService, 43 protected authService: AuthService,
45 protected serverService: ServerService, 44 protected serverService: ServerService,
46 protected videoService: VideoService, 45 protected videoService: VideoService,
@@ -99,7 +98,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom
99 this.loadingBar.complete() 98 this.loadingBar.complete()
100 this.isImportingVideo = false 99 this.isImportingVideo = false
101 this.firstStepError.emit() 100 this.firstStepError.emit()
102 this.notificationsService.error(this.i18n('Error'), err.message) 101 this.notifier.error(err.message)
103 } 102 }
104 ) 103 )
105 } 104 }
@@ -118,7 +117,7 @@ export class VideoImportUrlComponent extends VideoSend implements OnInit, CanCom
118 .subscribe( 117 .subscribe(
119 () => { 118 () => {
120 this.isUpdatingVideo = false 119 this.isUpdatingVideo = false
121 this.notificationsService.success(this.i18n('Success'), this.i18n('Video to import updated.')) 120 this.notifier.success(this.i18n('Video to import updated.'))
122 121
123 this.router.navigate([ '/my-account', 'video-imports' ]) 122 this.router.navigate([ '/my-account', 'video-imports' ])
124 }, 123 },
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss b/client/src/app/videos/+video-edit/video-add-components/video-send.scss
index e907edc70..8769dd302 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss
+++ b/client/src/app/videos/+video-edit/video-add-components/video-send.scss
@@ -3,10 +3,6 @@
3 3
4$width-size: 190px; 4$width-size: 190px;
5 5
6.peertube-select-container {
7 @include peertube-select-container($width-size);
8}
9
10.alert.alert-danger { 6.alert.alert-danger {
11 text-align: center; 7 text-align: center;
12 8
@@ -15,17 +11,20 @@ $width-size: 190px;
15 } 11 }
16} 12}
17 13
18.import-video-url { 14.first-step-block {
19 display: flex; 15 display: flex;
20 flex-direction: column; 16 flex-direction: column;
21 align-items: center; 17 align-items: center;
22 18
23 .icon.icon-upload { 19 .upload-icon {
24 @include icon(90px); 20 width: 90px;
25 margin-bottom: 25px; 21 margin-bottom: 25px;
26 cursor: default;
27 22
28 background-image: url('../../../../assets/images/video/upload.svg'); 23 @include apply-svg-color(#C6C6C6);
24 }
25
26 .peertube-select-container {
27 @include peertube-select-container($width-size);
29 } 28 }
30 29
31 input[type=text] { 30 input[type=text] {
@@ -40,6 +39,16 @@ $width-size: 190px;
40 width: $width-size; 39 width: $width-size;
41 margin-top: 30px; 40 margin-top: 30px;
42 } 41 }
43}
44 42
43 .button-file {
44 @include peertube-button-file(auto);
45 45
46 min-width: 190px;
47 }
48
49 .button-file-extension {
50 display: block;
51 font-size: 12px;
52 margin-top: 5px;
53 }
54}
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-send.ts b/client/src/app/videos/+video-edit/video-add-components/video-send.ts
index 71d2544d8..580c123a0 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-send.ts
+++ b/client/src/app/videos/+video-edit/video-add-components/video-send.ts
@@ -1,10 +1,9 @@
1import { EventEmitter, OnInit } from '@angular/core' 1import { EventEmitter, OnInit } from '@angular/core'
2import { LoadingBarService } from '@ngx-loading-bar/core' 2import { LoadingBarService } from '@ngx-loading-bar/core'
3import { NotificationsService } from 'angular2-notifications' 3import { AuthService, Notifier, ServerService } from '@app/core'
4import { catchError, switchMap, tap } from 'rxjs/operators' 4import { catchError, switchMap, tap } from 'rxjs/operators'
5import { FormReactive } from '@app/shared' 5import { FormReactive } from '@app/shared'
6import { VideoConstant, VideoPrivacy } from '../../../../../../shared' 6import { VideoConstant, VideoPrivacy } from '../../../../../../shared'
7import { AuthService, ServerService } from '@app/core'
8import { VideoService } from '@app/shared/video/video.service' 7import { VideoService } from '@app/shared/video/video.service'
9import { VideoCaptionEdit } from '@app/shared/video-caption/video-caption-edit.model' 8import { VideoCaptionEdit } from '@app/shared/video-caption/video-caption-edit.model'
10import { VideoCaptionService } from '@app/shared/video-caption' 9import { VideoCaptionService } from '@app/shared/video-caption'
@@ -25,7 +24,7 @@ export abstract class VideoSend extends FormReactive implements OnInit {
25 protected abstract readonly DEFAULT_VIDEO_PRIVACY: VideoPrivacy 24 protected abstract readonly DEFAULT_VIDEO_PRIVACY: VideoPrivacy
26 25
27 protected loadingBar: LoadingBarService 26 protected loadingBar: LoadingBarService
28 protected notificationsService: NotificationsService 27 protected notifier: Notifier
29 protected authService: AuthService 28 protected authService: AuthService
30 protected serverService: ServerService 29 protected serverService: ServerService
31 protected videoService: VideoService 30 protected videoService: VideoService
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.html b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.html
index a09f54dfc..b252cd60a 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.html
+++ b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.html
@@ -1,12 +1,12 @@
1<div *ngIf="!isUploadingVideo" class="upload-video-container"> 1<div *ngIf="!isUploadingVideo" class="upload-video-container">
2 <div class="upload-video"> 2 <div class="first-step-block">
3 <div class="icon icon-upload"></div> 3 <my-global-icon class="upload-icon" iconName="upload"></my-global-icon>
4 4
5 <div class="button-file"> 5 <div class="button-file">
6 <span i18n>Select the file to upload</span> 6 <span i18n>Select the file to upload</span>
7 <input #videofileInput type="file" name="videofile" id="videofile" [accept]="videoExtensions" (change)="fileChange()" /> 7 <input #videofileInput type="file" name="videofile" id="videofile" [accept]="videoExtensions" (change)="fileChange()" />
8 </div> 8 </div>
9 <span class="button-file-extension">(.mp4, .webm, .ogv)</span> 9 <span class="button-file-extension">({{ videoExtensions }})</span>
10 10
11 <div class="form-group form-group-channel"> 11 <div class="form-group form-group-channel">
12 <label i18n for="first-step-channel">Channel</label> 12 <label i18n for="first-step-channel">Channel</label>
@@ -42,11 +42,16 @@
42 {{ error }} 42 {{ error }}
43</div> 43</div>
44 44
45<div *ngIf="videoUploaded && !error" class="alert alert-info" i18n>
46 Congratulations! Your video is now available in your private library.
47</div>
48
45<!-- Hidden because we want to load the component --> 49<!-- Hidden because we want to load the component -->
46<form [hidden]="!isUploadingVideo" novalidate [formGroup]="form"> 50<form [hidden]="!isUploadingVideo" novalidate [formGroup]="form">
47 <my-video-edit 51 <my-video-edit
48 [form]="form" [formErrors]="formErrors" [videoCaptions]="videoCaptions" 52 [form]="form" [formErrors]="formErrors" [videoCaptions]="videoCaptions"
49 [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" [userVideoChannels]="userVideoChannels" 53 [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" [userVideoChannels]="userVideoChannels"
54 [waitTranscodingEnabled]="waitTranscodingEnabled"
50 ></my-video-edit> 55 ></my-video-edit>
51 56
52 <div class="submit-container"> 57 <div class="submit-container">
@@ -56,7 +61,7 @@
56 (click)="updateSecondStep()" 61 (click)="updateSecondStep()"
57 [ngClass]="{ disabled: isPublishingButtonDisabled() }" 62 [ngClass]="{ disabled: isPublishingButtonDisabled() }"
58 > 63 >
59 <span class="icon icon-validate"></span> 64 <my-global-icon iconName="validate"></my-global-icon>
60 <input [disabled]="isPublishingButtonDisabled()" type="button" i18n-value value="Publish" /> 65 <input [disabled]="isPublishingButtonDisabled()" type="button" i18n-value value="Publish" />
61 </div> 66 </div>
62 </div> 67 </div>
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss
index cf1725ef9..8adf8f169 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss
+++ b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.scss
@@ -1,47 +1,9 @@
1@import 'variables'; 1@import 'variables';
2@import 'mixins'; 2@import 'mixins';
3 3
4.peertube-select-container { 4.first-step-block .form-group-channel {
5 @include peertube-select-container(190px); 5 margin-bottom: 20px;
6} 6 margin-top: 35px;
7
8.alert.alert-danger {
9 text-align: center;
10
11 & > div {
12 font-weight: $font-semibold;
13 }
14}
15
16.upload-video {
17 display: flex;
18 flex-direction: column;
19 align-items: center;
20
21 .form-group-channel {
22 margin-bottom: 20px;
23 margin-top: 35px;
24 }
25
26 .icon.icon-upload {
27 @include icon(90px);
28 margin-bottom: 25px;
29 cursor: default;
30
31 background-image: url('../../../../assets/images/video/upload.svg');
32 }
33
34 .button-file {
35 @include peertube-button-file(auto);
36
37 min-width: 190px;
38 }
39
40 .button-file-extension {
41 display: block;
42 font-size: 12px;
43 margin-top: 5px;
44 }
45} 7}
46 8
47.upload-progress-cancel { 9.upload-progress-cancel {
@@ -54,9 +16,7 @@
54 16
55 /deep/ .ui-progressbar { 17 /deep/ .ui-progressbar {
56 font-size: 15px !important; 18 font-size: 15px !important;
57 color: #fff !important;
58 height: 30px !important; 19 height: 30px !important;
59 line-height: 30px !important;
60 border-radius: 3px !important; 20 border-radius: 3px !important;
61 background-color: rgba(11, 204, 41, 0.16) !important; 21 background-color: rgba(11, 204, 41, 0.16) !important;
62 22
@@ -68,6 +28,8 @@
68 text-align: left; 28 text-align: left;
69 padding-left: 18px; 29 padding-left: 18px;
70 margin-top: 0 !important; 30 margin-top: 0 !important;
31 color: #fff !important;
32 line-height: 30px !important;
71 } 33 }
72 } 34 }
73 35
diff --git a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts
index 3fcb71ac3..e4d54b654 100644
--- a/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts
+++ b/client/src/app/videos/+video-edit/video-add-components/video-upload.component.ts
@@ -2,11 +2,10 @@ import { HttpEventType, HttpResponse } from '@angular/common/http'
2import { Component, ElementRef, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core' 2import { Component, ElementRef, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'
3import { Router } from '@angular/router' 3import { Router } from '@angular/router'
4import { LoadingBarService } from '@ngx-loading-bar/core' 4import { LoadingBarService } from '@ngx-loading-bar/core'
5import { NotificationsService } from 'angular2-notifications'
6import { BytesPipe } from 'ngx-pipes' 5import { BytesPipe } from 'ngx-pipes'
7import { Subscription } from 'rxjs' 6import { Subscription } from 'rxjs'
8import { VideoPrivacy } from '../../../../../../shared/models/videos' 7import { VideoPrivacy } from '../../../../../../shared/models/videos'
9import { AuthService, ServerService } from '../../../core' 8import { AuthService, Notifier, ServerService } from '../../../core'
10import { VideoEdit } from '../../../shared/video/video-edit.model' 9import { VideoEdit } from '../../../shared/video/video-edit.model'
11import { VideoService } from '../../../shared/video/video.service' 10import { VideoService } from '../../../shared/video/video.service'
12import { I18n } from '@ngx-translate/i18n-polyfill' 11import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -21,7 +20,8 @@ import { scrollToTop } from '@app/shared/misc/utils'
21 templateUrl: './video-upload.component.html', 20 templateUrl: './video-upload.component.html',
22 styleUrls: [ 21 styleUrls: [
23 '../shared/video-edit.component.scss', 22 '../shared/video-edit.component.scss',
24 './video-upload.component.scss' 23 './video-upload.component.scss',
24 './video-send.scss'
25 ] 25 ]
26}) 26})
27export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy, CanComponentDeactivate { 27export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy, CanComponentDeactivate {
@@ -44,6 +44,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
44 id: 0, 44 id: 0,
45 uuid: '' 45 uuid: ''
46 } 46 }
47 waitTranscodingEnabled = true
47 48
48 error: string 49 error: string
49 50
@@ -52,7 +53,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
52 constructor ( 53 constructor (
53 protected formValidatorService: FormValidatorService, 54 protected formValidatorService: FormValidatorService,
54 protected loadingBar: LoadingBarService, 55 protected loadingBar: LoadingBarService,
55 protected notificationsService: NotificationsService, 56 protected notifier: Notifier,
56 protected authService: AuthService, 57 protected authService: AuthService,
57 protected serverService: ServerService, 58 protected serverService: ServerService,
58 protected videoService: VideoService, 59 protected videoService: VideoService,
@@ -109,7 +110,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
109 this.isUploadingVideo = false 110 this.isUploadingVideo = false
110 this.videoUploadPercents = 0 111 this.videoUploadPercents = 0
111 this.videoUploadObservable = null 112 this.videoUploadObservable = null
112 this.notificationsService.info(this.i18n('Info'), this.i18n('Upload cancelled')) 113 this.notifier.info(this.i18n('Upload cancelled'))
113 } 114 }
114 } 115 }
115 116
@@ -117,12 +118,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
117 const videofile = this.videofileInput.nativeElement.files[0] 118 const videofile = this.videofileInput.nativeElement.files[0]
118 if (!videofile) return 119 if (!videofile) return
119 120
120 // Cannot upload videos > 8GB for now 121 // Check global user quota
121 if (videofile.size > 8 * 1024 * 1024 * 1024) {
122 this.notificationsService.error(this.i18n('Error'), this.i18n('We are sorry but PeerTube cannot handle videos > 8GB'))
123 return
124 }
125
126 const bytePipes = new BytesPipe() 122 const bytePipes = new BytesPipe()
127 const videoQuota = this.authService.getUser().videoQuota 123 const videoQuota = this.authService.getUser().videoQuota
128 if (videoQuota !== -1 && (this.userVideoQuotaUsed + videofile.size) > videoQuota) { 124 if (videoQuota !== -1 && (this.userVideoQuotaUsed + videofile.size) > videoQuota) {
@@ -134,10 +130,11 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
134 videoQuota: bytePipes.transform(videoQuota, 0) 130 videoQuota: bytePipes.transform(videoQuota, 0)
135 } 131 }
136 ) 132 )
137 this.notificationsService.error(this.i18n('Error'), msg) 133 this.notifier.error(msg)
138 return 134 return
139 } 135 }
140 136
137 // Check daily user quota
141 const videoQuotaDaily = this.authService.getUser().videoQuotaDaily 138 const videoQuotaDaily = this.authService.getUser().videoQuotaDaily
142 if (videoQuotaDaily !== -1 && (this.userVideoQuotaUsedDaily + videofile.size) > videoQuotaDaily) { 139 if (videoQuotaDaily !== -1 && (this.userVideoQuotaUsedDaily + videofile.size) > videoQuotaDaily) {
143 const msg = this.i18n( 140 const msg = this.i18n(
@@ -148,10 +145,11 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
148 quotaDaily: bytePipes.transform(videoQuotaDaily, 0) 145 quotaDaily: bytePipes.transform(videoQuotaDaily, 0)
149 } 146 }
150 ) 147 )
151 this.notificationsService.error(this.i18n('Error'), msg) 148 this.notifier.error(msg)
152 return 149 return
153 } 150 }
154 151
152 // Build name field
155 const nameWithoutExtension = videofile.name.replace(/\.[^/.]+$/, '') 153 const nameWithoutExtension = videofile.name.replace(/\.[^/.]+$/, '')
156 let name: string 154 let name: string
157 155
@@ -159,6 +157,11 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
159 if (nameWithoutExtension.length < 3) name = videofile.name 157 if (nameWithoutExtension.length < 3) name = videofile.name
160 else name = nameWithoutExtension 158 else name = nameWithoutExtension
161 159
160 // Force user to wait transcoding for unsupported video types in web browsers
161 if (!videofile.name.endsWith('.mp4') && !videofile.name.endsWith('.webm') && !videofile.name.endsWith('.ogv')) {
162 this.waitTranscodingEnabled = false
163 }
164
162 const privacy = this.firstStepPrivacyId.toString() 165 const privacy = this.firstStepPrivacyId.toString()
163 const nsfw = false 166 const nsfw = false
164 const waitTranscoding = true 167 const waitTranscoding = true
@@ -206,7 +209,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
206 this.videoUploadPercents = 0 209 this.videoUploadPercents = 0
207 this.videoUploadObservable = null 210 this.videoUploadObservable = null
208 this.firstStepError.emit() 211 this.firstStepError.emit()
209 this.notificationsService.error(this.i18n('Error'), err.message) 212 this.notifier.error(err.message)
210 } 213 }
211 ) 214 )
212 } 215 }
@@ -235,7 +238,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
235 this.isUpdatingVideo = false 238 this.isUpdatingVideo = false
236 this.isUploadingVideo = false 239 this.isUploadingVideo = false
237 240
238 this.notificationsService.success(this.i18n('Success'), this.i18n('Video published.')) 241 this.notifier.success(this.i18n('Video published.'))
239 this.router.navigate([ '/videos/watch', video.uuid ]) 242 this.router.navigate([ '/videos/watch', video.uuid ])
240 }, 243 },
241 244
diff --git a/client/src/app/videos/+video-edit/video-add.component.ts b/client/src/app/videos/+video-edit/video-add.component.ts
index 57a9d0ca7..01fdfcb66 100644
--- a/client/src/app/videos/+video-edit/video-add.component.ts
+++ b/client/src/app/videos/+video-edit/video-add.component.ts
@@ -1,4 +1,4 @@
1import { Component, ViewChild } from '@angular/core' 1import { Component, HostListener, ViewChild } from '@angular/core'
2import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service' 2import { CanComponentDeactivate } from '@app/shared/guards/can-deactivate-guard.service'
3import { VideoImportUrlComponent } from '@app/videos/+video-edit/video-add-components/video-import-url.component' 3import { VideoImportUrlComponent } from '@app/videos/+video-edit/video-add-components/video-import-url.component'
4import { VideoUploadComponent } from '@app/videos/+video-edit/video-add-components/video-upload.component' 4import { VideoUploadComponent } from '@app/videos/+video-edit/video-add-components/video-upload.component'
@@ -32,7 +32,17 @@ export class VideoAddComponent implements CanComponentDeactivate {
32 this.secondStepType = undefined 32 this.secondStepType = undefined
33 } 33 }
34 34
35 canDeactivate () { 35 @HostListener('window:beforeunload', [ '$event' ])
36 onUnload (event: any) {
37 const { text, canDeactivate } = this.canDeactivate()
38
39 if (canDeactivate) return
40
41 event.returnValue = text
42 return text
43 }
44
45 canDeactivate (): { canDeactivate: boolean, text?: string} {
36 if (this.secondStepType === 'upload') return this.videoUpload.canDeactivate() 46 if (this.secondStepType === 'upload') return this.videoUpload.canDeactivate()
37 if (this.secondStepType === 'import-url') return this.videoImportUrl.canDeactivate() 47 if (this.secondStepType === 'import-url') return this.videoImportUrl.canDeactivate()
38 if (this.secondStepType === 'import-torrent') return this.videoImportTorrent.canDeactivate() 48 if (this.secondStepType === 'import-torrent') return this.videoImportTorrent.canDeactivate()
diff --git a/client/src/app/videos/+video-edit/video-update.component.html b/client/src/app/videos/+video-edit/video-update.component.html
index 9242c30a0..4992bb369 100644
--- a/client/src/app/videos/+video-edit/video-update.component.html
+++ b/client/src/app/videos/+video-edit/video-update.component.html
@@ -8,12 +8,12 @@
8 <my-video-edit 8 <my-video-edit
9 [form]="form" [formErrors]="formErrors" [schedulePublicationPossible]="schedulePublicationPossible" 9 [form]="form" [formErrors]="formErrors" [schedulePublicationPossible]="schedulePublicationPossible"
10 [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" [userVideoChannels]="userVideoChannels" 10 [validationMessages]="validationMessages" [videoPrivacies]="videoPrivacies" [userVideoChannels]="userVideoChannels"
11 [videoCaptions]="videoCaptions" 11 [videoCaptions]="videoCaptions" [waitTranscodingEnabled]="waitTranscodingEnabled"
12 ></my-video-edit> 12 ></my-video-edit>
13 13
14 <div class="submit-container"> 14 <div class="submit-container">
15 <div class="submit-button" (click)="update()" [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }"> 15 <div class="submit-button" (click)="update()" [ngClass]="{ disabled: !form.valid || isUpdatingVideo === true }">
16 <span class="icon icon-validate"></span> 16 <my-global-icon iconName="validate"></my-global-icon>
17 <input type="button" i18n-value value="Update" /> 17 <input type="button" i18n-value value="Update" />
18 </div> 18 </div>
19 </div> 19 </div>
diff --git a/client/src/app/videos/+video-edit/video-update.component.ts b/client/src/app/videos/+video-edit/video-update.component.ts
index 3a0f3a39a..9e849014e 100644
--- a/client/src/app/videos/+video-edit/video-update.component.ts
+++ b/client/src/app/videos/+video-edit/video-update.component.ts
@@ -1,8 +1,8 @@
1import { map, switchMap } from 'rxjs/operators' 1import { map, switchMap } from 'rxjs/operators'
2import { Component, OnInit } from '@angular/core' 2import { Component, HostListener, OnInit } from '@angular/core'
3import { ActivatedRoute, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
4import { LoadingBarService } from '@ngx-loading-bar/core' 4import { LoadingBarService } from '@ngx-loading-bar/core'
5import { NotificationsService } from 'angular2-notifications' 5import { Notifier } from '@app/core'
6import { VideoConstant, VideoPrivacy } from '../../../../../shared/models/videos' 6import { VideoConstant, VideoPrivacy } from '../../../../../shared/models/videos'
7import { ServerService } from '../../core' 7import { ServerService } from '../../core'
8import { FormReactive } from '../../shared' 8import { FormReactive } from '../../shared'
@@ -12,6 +12,7 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
12import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 12import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
13import { VideoCaptionService } from '@app/shared/video-caption' 13import { VideoCaptionService } from '@app/shared/video-caption'
14import { VideoCaptionEdit } from '@app/shared/video-caption/video-caption-edit.model' 14import { VideoCaptionEdit } from '@app/shared/video-caption/video-caption-edit.model'
15import { VideoDetails } from '@app/shared/video/video-details.model'
15 16
16@Component({ 17@Component({
17 selector: 'my-videos-update', 18 selector: 'my-videos-update',
@@ -26,6 +27,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
26 userVideoChannels: { id: number, label: string, support: string }[] = [] 27 userVideoChannels: { id: number, label: string, support: string }[] = []
27 schedulePublicationPossible = false 28 schedulePublicationPossible = false
28 videoCaptions: VideoCaptionEdit[] = [] 29 videoCaptions: VideoCaptionEdit[] = []
30 waitTranscodingEnabled = true
29 31
30 private updateDone = false 32 private updateDone = false
31 33
@@ -33,7 +35,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
33 protected formValidatorService: FormValidatorService, 35 protected formValidatorService: FormValidatorService,
34 private route: ActivatedRoute, 36 private route: ActivatedRoute,
35 private router: Router, 37 private router: Router,
36 private notificationsService: NotificationsService, 38 private notifier: Notifier,
37 private serverService: ServerService, 39 private serverService: ServerService,
38 private videoService: VideoService, 40 private videoService: VideoService,
39 private loadingBar: LoadingBarService, 41 private loadingBar: LoadingBarService,
@@ -65,25 +67,42 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
65 67
66 this.videoPrivacies = this.videoService.explainedPrivacyLabels(this.videoPrivacies) 68 this.videoPrivacies = this.videoService.explainedPrivacyLabels(this.videoPrivacies)
67 69
70 const videoFiles = (video as VideoDetails).files
71 if (videoFiles.length > 1) { // Already transcoded
72 this.waitTranscodingEnabled = false
73 }
74
68 // FIXME: Angular does not detect the change inside this subscription, so use the patched setTimeout 75 // FIXME: Angular does not detect the change inside this subscription, so use the patched setTimeout
69 setTimeout(() => this.hydrateFormFromVideo()) 76 setTimeout(() => this.hydrateFormFromVideo())
70 }, 77 },
71 78
72 err => { 79 err => {
73 console.error(err) 80 console.error(err)
74 this.notificationsService.error(this.i18n('Error'), err.message) 81 this.notifier.error(err.message)
75 } 82 }
76 ) 83 )
77 } 84 }
78 85
79 canDeactivate () { 86 @HostListener('window:beforeunload', [ '$event' ])
87 onUnload (event: any) {
88 const { text, canDeactivate } = this.canDeactivate()
89
90 if (canDeactivate) return
91
92 event.returnValue = text
93 return text
94 }
95
96 canDeactivate (): { canDeactivate: boolean, text?: string } {
80 if (this.updateDone === true) return { canDeactivate: true } 97 if (this.updateDone === true) return { canDeactivate: true }
81 98
99 const text = this.i18n('You have unsaved changes! If you leave, your changes will be lost.')
100
82 for (const caption of this.videoCaptions) { 101 for (const caption of this.videoCaptions) {
83 if (caption.action) return { canDeactivate: false } 102 if (caption.action) return { canDeactivate: false, text }
84 } 103 }
85 104
86 return { canDeactivate: this.formChanged === false } 105 return { canDeactivate: this.formChanged === false, text }
87 } 106 }
88 107
89 checkForm () { 108 checkForm () {
@@ -114,14 +133,14 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
114 this.updateDone = true 133 this.updateDone = true
115 this.isUpdatingVideo = false 134 this.isUpdatingVideo = false
116 this.loadingBar.complete() 135 this.loadingBar.complete()
117 this.notificationsService.success(this.i18n('Success'), this.i18n('Video updated.')) 136 this.notifier.success(this.i18n('Video updated.'))
118 this.router.navigate([ '/videos/watch', this.video.uuid ]) 137 this.router.navigate([ '/videos/watch', this.video.uuid ])
119 }, 138 },
120 139
121 err => { 140 err => {
122 this.loadingBar.complete() 141 this.loadingBar.complete()
123 this.isUpdatingVideo = false 142 this.isUpdatingVideo = false
124 this.notificationsService.error(this.i18n('Error'), err.message) 143 this.notifier.error(err.message)
125 console.error(err) 144 console.error(err)
126 } 145 }
127 ) 146 )
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
index 6db0eb55d..fd85c28f2 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts
@@ -1,6 +1,6 @@
1import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' 1import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'
2import { Router } from '@angular/router' 2import { Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { Notifier } from '@app/core'
4import { Observable } from 'rxjs' 4import { Observable } from 'rxjs'
5import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model' 5import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model'
6import { FormReactive } from '../../../shared' 6import { FormReactive } from '../../../shared'
@@ -36,7 +36,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
36 constructor ( 36 constructor (
37 protected formValidatorService: FormValidatorService, 37 protected formValidatorService: FormValidatorService,
38 private videoCommentValidatorsService: VideoCommentValidatorsService, 38 private videoCommentValidatorsService: VideoCommentValidatorsService,
39 private notificationsService: NotificationsService, 39 private notifier: Notifier,
40 private videoCommentService: VideoCommentService, 40 private videoCommentService: VideoCommentService,
41 private authService: AuthService, 41 private authService: AuthService,
42 private modalService: NgbModal, 42 private modalService: NgbModal,
@@ -70,7 +70,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
70 } 70 }
71 71
72 onValidKey () { 72 onValidKey () {
73 this.onValueChanged() 73 this.check()
74 if (!this.form.valid) return 74 if (!this.form.valid) return
75 75
76 this.formValidated() 76 this.formValidated()
@@ -115,7 +115,7 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
115 err => { 115 err => {
116 this.addingComment = false 116 this.addingComment = false
117 117
118 this.notificationsService.error(this.i18n('Error'), err.text) 118 this.notifier.error(err.text)
119 } 119 }
120 ) 120 )
121 } 121 }
@@ -135,7 +135,6 @@ export class VideoCommentAddComponent extends FormReactive implements OnInit {
135 135
136 gotoLogin () { 136 gotoLogin () {
137 this.hideVisitorModal() 137 this.hideVisitorModal()
138 this.authService.redirectUrl = this.router.url
139 this.router.navigate([ '/login' ]) 138 this.router.navigate([ '/login' ])
140 } 139 }
141 140
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.component.scss b/client/src/app/videos/+video-watch/comment/video-comment.component.scss
index 84da5727e..731ecbf8f 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment.component.scss
+++ b/client/src/app/videos/+video-watch/comment/video-comment.component.scss
@@ -41,7 +41,7 @@
41 } 41 }
42 42
43 .comment-date { 43 .comment-date {
44 color: #585858; 44 color: $grey-foreground-color;
45 margin-left: 10px; 45 margin-left: 10px;
46 } 46 }
47 } 47 }
@@ -69,7 +69,7 @@
69 69
70 .comment-action-reply, 70 .comment-action-reply,
71 .comment-action-delete { 71 .comment-action-delete {
72 color: #585858; 72 color: $grey-foreground-color;
73 cursor: pointer; 73 cursor: pointer;
74 margin-right: 10px; 74 margin-right: 10px;
75 75
@@ -108,4 +108,4 @@
108 .root-comment { 108 .root-comment {
109 font-size: 14px; 109 font-size: 14px;
110 } 110 }
111} \ No newline at end of file 111}
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.component.ts b/client/src/app/videos/+video-watch/comment/video-comment.component.ts
index 00f0460a1..aba7f9d1c 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comment.component.ts
@@ -1,11 +1,10 @@
1import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core' 1import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core'
2import { LinkifierService } from '@app/videos/+video-watch/comment/linkifier.service'
3import * as sanitizeHtml from 'sanitize-html'
4import { UserRight } from '../../../../../../shared/models/users' 2import { UserRight } from '../../../../../../shared/models/users'
5import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' 3import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model'
6import { AuthService } from '../../../core/auth' 4import { AuthService } from '../../../core/auth'
7import { Video } from '../../../shared/video/video.model' 5import { Video } from '../../../shared/video/video.model'
8import { VideoComment } from './video-comment.model' 6import { VideoComment } from './video-comment.model'
7import { HtmlRendererService } from '@app/shared/renderer'
9 8
10@Component({ 9@Component({
11 selector: 'my-video-comment', 10 selector: 'my-video-comment',
@@ -29,7 +28,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
29 newParentComments: VideoComment[] = [] 28 newParentComments: VideoComment[] = []
30 29
31 constructor ( 30 constructor (
32 private linkifierService: LinkifierService, 31 private htmlRenderer: HtmlRendererService,
33 private authService: AuthService 32 private authService: AuthService
34 ) {} 33 ) {}
35 34
@@ -87,27 +86,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
87 } 86 }
88 87
89 private init () { 88 private init () {
90 // Convert possible markdown to html 89 this.sanitizedCommentHTML = this.htmlRenderer.toSafeHtml(this.comment.text)
91 const html = this.linkifierService.linkify(this.comment.text)
92
93 this.sanitizedCommentHTML = sanitizeHtml(html, {
94 allowedTags: [ 'a', 'p', 'span', 'br' ],
95 allowedSchemes: [ 'http', 'https' ],
96 allowedAttributes: {
97 'a': [ 'href', 'class', 'target' ]
98 },
99 transformTags: {
100 a: (tagName, attribs) => {
101 return {
102 tagName,
103 attribs: Object.assign(attribs, {
104 target: '_blank',
105 rel: 'noopener noreferrer'
106 })
107 }
108 }
109 }
110 })
111 90
112 this.newParentComments = this.parentComments.concat([ this.comment ]) 91 this.newParentComments = this.parentComments.concat([ this.comment ])
113 } 92 }
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.service.ts b/client/src/app/videos/+video-watch/comment/video-comment.service.ts
index 921447d5b..b8e5878c5 100644
--- a/client/src/app/videos/+video-watch/comment/video-comment.service.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comment.service.ts
@@ -1,7 +1,7 @@
1import { catchError, map } from 'rxjs/operators' 1import { catchError, map } from 'rxjs/operators'
2import { HttpClient, HttpParams } from '@angular/common/http' 2import { HttpClient, HttpParams } from '@angular/common/http'
3import { Injectable } from '@angular/core' 3import { Injectable } from '@angular/core'
4import { lineFeedToHtml } from '@app/shared/misc/utils' 4import { objectLineFeedToHtml } from '@app/shared/misc/utils'
5import { Observable } from 'rxjs' 5import { Observable } from 'rxjs'
6import { ResultList, FeedFormat } from '../../../../../../shared/models' 6import { ResultList, FeedFormat } from '../../../../../../shared/models'
7import { 7import {
@@ -28,7 +28,7 @@ export class VideoCommentService {
28 28
29 addCommentThread (videoId: number | string, comment: VideoCommentCreate) { 29 addCommentThread (videoId: number | string, comment: VideoCommentCreate) {
30 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads' 30 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads'
31 const normalizedComment = lineFeedToHtml(comment, 'text') 31 const normalizedComment = objectLineFeedToHtml(comment, 'text')
32 32
33 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment) 33 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment)
34 .pipe( 34 .pipe(
@@ -39,7 +39,7 @@ export class VideoCommentService {
39 39
40 addCommentReply (videoId: number | string, inReplyToCommentId: number, comment: VideoCommentCreate) { 40 addCommentReply (videoId: number | string, inReplyToCommentId: number, comment: VideoCommentCreate) {
41 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comments/' + inReplyToCommentId 41 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comments/' + inReplyToCommentId
42 const normalizedComment = lineFeedToHtml(comment, 'text') 42 const normalizedComment = objectLineFeedToHtml(comment, 'text')
43 43
44 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment) 44 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment)
45 .pipe( 45 .pipe(
diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.ts b/client/src/app/videos/+video-watch/comment/video-comments.component.ts
index 8850eccd8..2616820d2 100644
--- a/client/src/app/videos/+video-watch/comment/video-comments.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comments.component.ts
@@ -1,11 +1,10 @@
1import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild, ElementRef } from '@angular/core' 1import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core'
2import { ActivatedRoute } from '@angular/router' 2import { ActivatedRoute } from '@angular/router'
3import { ConfirmService } from '@app/core' 3import { ConfirmService, Notifier } from '@app/core'
4import { NotificationsService } from 'angular2-notifications'
5import { Subscription } from 'rxjs' 4import { Subscription } from 'rxjs'
6import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' 5import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model'
7import { AuthService } from '../../../core/auth' 6import { AuthService } from '../../../core/auth'
8import { ComponentPagination } from '../../../shared/rest/component-pagination.model' 7import { ComponentPagination, hasMoreItems } from '../../../shared/rest/component-pagination.model'
9import { User } from '../../../shared/users' 8import { User } from '../../../shared/users'
10import { VideoSortField } from '../../../shared/video/sort-field.type' 9import { VideoSortField } from '../../../shared/video/sort-field.type'
11import { VideoDetails } from '../../../shared/video/video-details.model' 10import { VideoDetails } from '../../../shared/video/video-details.model'
@@ -42,7 +41,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
42 41
43 constructor ( 42 constructor (
44 private authService: AuthService, 43 private authService: AuthService,
45 private notificationsService: NotificationsService, 44 private notifier: Notifier,
46 private confirmService: ConfirmService, 45 private confirmService: ConfirmService,
47 private videoCommentService: VideoCommentService, 46 private videoCommentService: VideoCommentService,
48 private activatedRoute: ActivatedRoute, 47 private activatedRoute: ActivatedRoute,
@@ -84,15 +83,11 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
84 this.highlightedThread = new VideoComment(res.comment) 83 this.highlightedThread = new VideoComment(res.comment)
85 84
86 // Scroll to the highlighted thread 85 // Scroll to the highlighted thread
87 setTimeout(() => { 86 setTimeout(() => this.commentHighlightBlock.nativeElement.scrollIntoView(), 0)
88 // -60 because of the fixed header
89 const scrollY = this.commentHighlightBlock.nativeElement.offsetTop - 60
90 window.scroll(0, scrollY)
91 }, 500)
92 } 87 }
93 }, 88 },
94 89
95 err => this.notificationsService.error(this.i18n('Error'), err.message) 90 err => this.notifier.error(err.message)
96 ) 91 )
97 } 92 }
98 93
@@ -104,7 +99,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
104 this.componentPagination.totalItems = res.totalComments 99 this.componentPagination.totalItems = res.totalComments
105 }, 100 },
106 101
107 err => this.notificationsService.error(this.i18n('Error'), err.message) 102 err => this.notifier.error(err.message)
108 ) 103 )
109 } 104 }
110 105
@@ -155,7 +150,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
155 if (this.highlightedThread.id === commentToDelete.id) this.highlightedThread = undefined 150 if (this.highlightedThread.id === commentToDelete.id) this.highlightedThread = undefined
156 }, 151 },
157 152
158 err => this.notificationsService.error(this.i18n('Error'), err.message) 153 err => this.notifier.error(err.message)
159 ) 154 )
160 } 155 }
161 156
@@ -166,22 +161,11 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
166 onNearOfBottom () { 161 onNearOfBottom () {
167 this.componentPagination.currentPage++ 162 this.componentPagination.currentPage++
168 163
169 if (this.hasMoreComments()) { 164 if (hasMoreItems(this.componentPagination)) {
170 this.loadMoreComments() 165 this.loadMoreComments()
171 } 166 }
172 } 167 }
173 168
174 private hasMoreComments () {
175 // No results
176 if (this.componentPagination.totalItems === 0) return false
177
178 // Not loaded yet
179 if (!this.componentPagination.totalItems) return true
180
181 const maxPage = this.componentPagination.totalItems / this.componentPagination.itemsPerPage
182 return maxPage > this.componentPagination.currentPage
183 }
184
185 private deleteLocalCommentThread (parentComment: VideoCommentThreadTree, commentToDelete: VideoComment) { 169 private deleteLocalCommentThread (parentComment: VideoCommentThreadTree, commentToDelete: VideoComment) {
186 for (const commentChild of parentComment.children) { 170 for (const commentChild of parentComment.children) {
187 if (commentChild.comment.id === commentToDelete.id) { 171 if (commentChild.comment.id === commentToDelete.id) {
diff --git a/client/src/app/videos/+video-watch/modal/video-blacklist.component.html b/client/src/app/videos/+video-watch/modal/video-blacklist.component.html
index c436501b4..1a87bdcd4 100644
--- a/client/src/app/videos/+video-watch/modal/video-blacklist.component.html
+++ b/client/src/app/videos/+video-watch/modal/video-blacklist.component.html
@@ -1,7 +1,7 @@
1<ng-template #modal> 1<ng-template #modal>
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Blacklist video</h4> 3 <h4 i18n class="modal-title">Blacklist video</h4>
4 <span class="close" aria-label="Close" role="button" (click)="hide()"></span> 4 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
5 </div> 5 </div>
6 6
7 <div class="modal-body"> 7 <div class="modal-body">
@@ -15,6 +15,13 @@
15 </div> 15 </div>
16 </div> 16 </div>
17 17
18 <div class="form-group" *ngIf="video.isLocal">
19 <my-peertube-checkbox
20 inputName="unfederate" formControlName="unfederate"
21 i18n-labelText labelText="Unfederate the video (ask for its deletion from the remote instances)"
22 ></my-peertube-checkbox>
23 </div>
24
18 <div class="form-group inputs"> 25 <div class="form-group inputs">
19 <span i18n class="action-button action-button-cancel" (click)="hide()"> 26 <span i18n class="action-button action-button-cancel" (click)="hide()">
20 Cancel 27 Cancel
diff --git a/client/src/app/videos/+video-watch/modal/video-blacklist.component.ts b/client/src/app/videos/+video-watch/modal/video-blacklist.component.ts
index 2c123ebed..50a7cadd1 100644
--- a/client/src/app/videos/+video-watch/modal/video-blacklist.component.ts
+++ b/client/src/app/videos/+video-watch/modal/video-blacklist.component.ts
@@ -1,12 +1,11 @@
1import { Component, Input, OnInit, ViewChild } from '@angular/core' 1import { Component, Input, OnInit, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier, RedirectService } from '@app/core'
3import { FormReactive, VideoBlacklistService, VideoBlacklistValidatorsService } from '../../../shared/index' 3import { FormReactive, VideoBlacklistService, VideoBlacklistValidatorsService } from '../../../shared/index'
4import { VideoDetails } from '../../../shared/video/video-details.model' 4import { VideoDetails } from '../../../shared/video/video-details.model'
5import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
7import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 7import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
8import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' 8import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
9import { RedirectService } from '@app/core'
10 9
11@Component({ 10@Component({
12 selector: 'my-video-blacklist', 11 selector: 'my-video-blacklist',
@@ -27,7 +26,7 @@ export class VideoBlacklistComponent extends FormReactive implements OnInit {
27 private modalService: NgbModal, 26 private modalService: NgbModal,
28 private videoBlacklistValidatorsService: VideoBlacklistValidatorsService, 27 private videoBlacklistValidatorsService: VideoBlacklistValidatorsService,
29 private videoBlacklistService: VideoBlacklistService, 28 private videoBlacklistService: VideoBlacklistService,
30 private notificationsService: NotificationsService, 29 private notifier: Notifier,
31 private redirectService: RedirectService, 30 private redirectService: RedirectService,
32 private i18n: I18n 31 private i18n: I18n
33 ) { 32 ) {
@@ -35,9 +34,12 @@ export class VideoBlacklistComponent extends FormReactive implements OnInit {
35 } 34 }
36 35
37 ngOnInit () { 36 ngOnInit () {
37 const defaultValues = { unfederate: 'true' }
38
38 this.buildForm({ 39 this.buildForm({
39 reason: this.videoBlacklistValidatorsService.VIDEO_BLACKLIST_REASON 40 reason: this.videoBlacklistValidatorsService.VIDEO_BLACKLIST_REASON,
40 }) 41 unfederate: null
42 }, defaultValues)
41 } 43 }
42 44
43 show () { 45 show () {
@@ -51,16 +53,17 @@ export class VideoBlacklistComponent extends FormReactive implements OnInit {
51 53
52 blacklist () { 54 blacklist () {
53 const reason = this.form.value[ 'reason' ] || undefined 55 const reason = this.form.value[ 'reason' ] || undefined
56 const unfederate = this.video.isLocal ? this.form.value[ 'unfederate' ] : undefined
54 57
55 this.videoBlacklistService.blacklistVideo(this.video.id, reason) 58 this.videoBlacklistService.blacklistVideo(this.video.id, reason, unfederate)
56 .subscribe( 59 .subscribe(
57 () => { 60 () => {
58 this.notificationsService.success(this.i18n('Success'), this.i18n('Video blacklisted.')) 61 this.notifier.success(this.i18n('Video blacklisted.'))
59 this.hide() 62 this.hide()
60 this.redirectService.redirectToHomepage() 63 this.redirectService.redirectToHomepage()
61 }, 64 },
62 65
63 err => this.notificationsService.error(this.i18n('Error'), err.message) 66 err => this.notifier.error(err.message)
64 ) 67 )
65 } 68 }
66} 69}
diff --git a/client/src/app/videos/+video-watch/modal/video-download.component.html b/client/src/app/videos/+video-watch/modal/video-download.component.html
index f46f92a17..2bb5d6d37 100644
--- a/client/src/app/videos/+video-watch/modal/video-download.component.html
+++ b/client/src/app/videos/+video-watch/modal/video-download.component.html
@@ -1,7 +1,7 @@
1<ng-template #modal let-hide="close"> 1<ng-template #modal let-hide="close">
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Download video</h4> 3 <h4 i18n class="modal-title">Download video</h4>
4 <span class="close" aria-hidden="true" (click)="hide()"></span> 4 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
5 </div> 5 </div>
6 6
7 <div class="modal-body"> 7 <div class="modal-body">
diff --git a/client/src/app/videos/+video-watch/modal/video-download.component.ts b/client/src/app/videos/+video-watch/modal/video-download.component.ts
index b1b2c0623..834385771 100644
--- a/client/src/app/videos/+video-watch/modal/video-download.component.ts
+++ b/client/src/app/videos/+video-watch/modal/video-download.component.ts
@@ -2,7 +2,7 @@ import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'
2import { VideoDetails } from '../../../shared/video/video-details.model' 2import { VideoDetails } from '../../../shared/video/video-details.model'
3import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 3import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { NotificationsService } from 'angular2-notifications' 5import { Notifier } from '@app/core'
6 6
7@Component({ 7@Component({
8 selector: 'my-video-download', 8 selector: 'my-video-download',
@@ -18,7 +18,7 @@ export class VideoDownloadComponent implements OnInit {
18 resolutionId: number | string = -1 18 resolutionId: number | string = -1
19 19
20 constructor ( 20 constructor (
21 private notificationsService: NotificationsService, 21 private notifier: Notifier,
22 private modalService: NgbModal, 22 private modalService: NgbModal,
23 private i18n: I18n 23 private i18n: I18n
24 ) { } 24 ) { }
@@ -63,6 +63,6 @@ export class VideoDownloadComponent implements OnInit {
63 } 63 }
64 64
65 activateCopiedMessage () { 65 activateCopiedMessage () {
66 this.notificationsService.success(this.i18n('Success'), this.i18n('Copied')) 66 this.notifier.success(this.i18n('Copied'))
67 } 67 }
68} 68}
diff --git a/client/src/app/videos/+video-watch/modal/video-report.component.html b/client/src/app/videos/+video-watch/modal/video-report.component.html
index 8d9a49276..b9434da26 100644
--- a/client/src/app/videos/+video-watch/modal/video-report.component.html
+++ b/client/src/app/videos/+video-watch/modal/video-report.component.html
@@ -1,11 +1,16 @@
1<ng-template #modal> 1<ng-template #modal>
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Report video</h4> 3 <h4 i18n class="modal-title">Report video</h4>
4 <span class="close" aria-label="Close" role="button" (click)="hide()"></span> 4 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
5 </div> 5 </div>
6 6
7 <div class="modal-body"> 7 <div class="modal-body">
8 8
9 <div i18n class="information">
10 Your report will be sent to moderators of {{ currentHost }}.
11 <ng-container *ngIf="isRemoteVideo()"> It will be forwarded to origin instance {{ originHost }} too.</ng-container>
12 </div>
13
9 <form novalidate [formGroup]="form" (ngSubmit)="report()"> 14 <form novalidate [formGroup]="form" (ngSubmit)="report()">
10 <div class="form-group"> 15 <div class="form-group">
11 <textarea i18n-placeholder placeholder="Reason..." formControlName="reason" [ngClass]="{ 'input-error': formErrors['reason'] }"> 16 <textarea i18n-placeholder placeholder="Reason..." formControlName="reason" [ngClass]="{ 'input-error': formErrors['reason'] }">
diff --git a/client/src/app/videos/+video-watch/modal/video-report.component.scss b/client/src/app/videos/+video-watch/modal/video-report.component.scss
index afcdb9a16..4713660a2 100644
--- a/client/src/app/videos/+video-watch/modal/video-report.component.scss
+++ b/client/src/app/videos/+video-watch/modal/video-report.component.scss
@@ -1,6 +1,10 @@
1@import 'variables'; 1@import 'variables';
2@import 'mixins'; 2@import 'mixins';
3 3
4.information {
5 margin-bottom: 20px;
6}
7
4textarea { 8textarea {
5 @include peertube-textarea(100%, 100px); 9 @include peertube-textarea(100%, 100px);
6} 10}
diff --git a/client/src/app/videos/+video-watch/modal/video-report.component.ts b/client/src/app/videos/+video-watch/modal/video-report.component.ts
index 297afb19f..911f3b447 100644
--- a/client/src/app/videos/+video-watch/modal/video-report.component.ts
+++ b/client/src/app/videos/+video-watch/modal/video-report.component.ts
@@ -1,5 +1,5 @@
1import { Component, Input, OnInit, ViewChild } from '@angular/core' 1import { Component, Input, OnInit, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { FormReactive, VideoAbuseService } from '../../../shared/index' 3import { FormReactive, VideoAbuseService } from '../../../shared/index'
4import { VideoDetails } from '../../../shared/video/video-details.model' 4import { VideoDetails } from '../../../shared/video/video-details.model'
5import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -27,12 +27,24 @@ export class VideoReportComponent extends FormReactive implements OnInit {
27 private modalService: NgbModal, 27 private modalService: NgbModal,
28 private videoAbuseValidatorsService: VideoAbuseValidatorsService, 28 private videoAbuseValidatorsService: VideoAbuseValidatorsService,
29 private videoAbuseService: VideoAbuseService, 29 private videoAbuseService: VideoAbuseService,
30 private notificationsService: NotificationsService, 30 private notifier: Notifier,
31 private i18n: I18n 31 private i18n: I18n
32 ) { 32 ) {
33 super() 33 super()
34 } 34 }
35 35
36 get currentHost () {
37 return window.location.host
38 }
39
40 get originHost () {
41 if (this.isRemoteVideo()) {
42 return this.video.account.host
43 }
44
45 return ''
46 }
47
36 ngOnInit () { 48 ngOnInit () {
37 this.buildForm({ 49 this.buildForm({
38 reason: this.videoAbuseValidatorsService.VIDEO_ABUSE_REASON 50 reason: this.videoAbuseValidatorsService.VIDEO_ABUSE_REASON
@@ -54,11 +66,15 @@ export class VideoReportComponent extends FormReactive implements OnInit {
54 this.videoAbuseService.reportVideo(this.video.id, reason) 66 this.videoAbuseService.reportVideo(this.video.id, reason)
55 .subscribe( 67 .subscribe(
56 () => { 68 () => {
57 this.notificationsService.success(this.i18n('Success'), this.i18n('Video reported.')) 69 this.notifier.success(this.i18n('Video reported.'))
58 this.hide() 70 this.hide()
59 }, 71 },
60 72
61 err => this.notificationsService.error(this.i18n('Error'), err.message) 73 err => this.notifier.error(err.message)
62 ) 74 )
63 } 75 }
76
77 isRemoteVideo () {
78 return !this.video.isLocal
79 }
64} 80}
diff --git a/client/src/app/videos/+video-watch/modal/video-share.component.html b/client/src/app/videos/+video-watch/modal/video-share.component.html
index 301f67f2d..9f3c37fe8 100644
--- a/client/src/app/videos/+video-watch/modal/video-share.component.html
+++ b/client/src/app/videos/+video-watch/modal/video-share.component.html
@@ -1,7 +1,7 @@
1<ng-template #modal let-hide="close"> 1<ng-template #modal let-hide="close">
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Share</h4> 3 <h4 i18n class="modal-title">Share</h4>
4 <span class="close" aria-hidden="true" (click)="hide()"></span> 4 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
5 </div> 5 </div>
6 6
7 <div class="modal-body"> 7 <div class="modal-body">
diff --git a/client/src/app/videos/+video-watch/modal/video-share.component.ts b/client/src/app/videos/+video-watch/modal/video-share.component.ts
index 17e2b31e1..c6205e355 100644
--- a/client/src/app/videos/+video-watch/modal/video-share.component.ts
+++ b/client/src/app/videos/+video-watch/modal/video-share.component.ts
@@ -1,5 +1,5 @@
1import { Component, ElementRef, Input, ViewChild } from '@angular/core' 1import { Component, ElementRef, Input, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications' 2import { Notifier } from '@app/core'
3import { VideoDetails } from '../../../shared/video/video-details.model' 3import { VideoDetails } from '../../../shared/video/video-details.model'
4import { buildVideoEmbed, buildVideoLink } from '../../../../assets/player/utils' 4import { buildVideoEmbed, buildVideoLink } from '../../../../assets/player/utils'
5import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -23,7 +23,7 @@ export class VideoShareComponent {
23 23
24 constructor ( 24 constructor (
25 private modalService: NgbModal, 25 private modalService: NgbModal,
26 private notificationsService: NotificationsService, 26 private notifier: Notifier,
27 private i18n: I18n 27 private i18n: I18n
28 ) { } 28 ) { }
29 29
@@ -49,7 +49,7 @@ export class VideoShareComponent {
49 } 49 }
50 50
51 activateCopiedMessage () { 51 activateCopiedMessage () {
52 this.notificationsService.success(this.i18n('Success'), this.i18n('Copied')) 52 this.notifier.success(this.i18n('Copied'))
53 } 53 }
54 54
55 getStartCheckboxLabel () { 55 getStartCheckboxLabel () {
diff --git a/client/src/app/videos/+video-watch/modal/video-support.component.html b/client/src/app/videos/+video-watch/modal/video-support.component.html
index 00c304709..2a05224a8 100644
--- a/client/src/app/videos/+video-watch/modal/video-support.component.html
+++ b/client/src/app/videos/+video-watch/modal/video-support.component.html
@@ -1,7 +1,7 @@
1<ng-template #modal let-hide="close"> 1<ng-template #modal let-hide="close">
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Support</h4> 3 <h4 i18n class="modal-title">Support</h4>
4 <span class="close" aria-label="Close" role="button" (click)="hide()"></span> 4 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
5 </div> 5 </div>
6 6
7 <div class="modal-body" [innerHTML]="videoHTMLSupport"></div> 7 <div class="modal-body" [innerHTML]="videoHTMLSupport"></div>
diff --git a/client/src/app/videos/+video-watch/modal/video-support.component.ts b/client/src/app/videos/+video-watch/modal/video-support.component.ts
index 154002120..deb8fbc67 100644
--- a/client/src/app/videos/+video-watch/modal/video-support.component.ts
+++ b/client/src/app/videos/+video-watch/modal/video-support.component.ts
@@ -1,8 +1,7 @@
1import { Component, Input, ViewChild } from '@angular/core' 1import { Component, Input, ViewChild } from '@angular/core'
2import { MarkdownService } from '@app/videos/shared'
3
4import { VideoDetails } from '../../../shared/video/video-details.model' 2import { VideoDetails } from '../../../shared/video/video-details.model'
5import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 3import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
4import { MarkdownService } from '@app/shared/renderer'
6 5
7@Component({ 6@Component({
8 selector: 'my-video-support', 7 selector: 'my-video-support',
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html
index 770785d02..709eb91a8 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.html
+++ b/client/src/app/videos/+video-watch/video-watch.component.html
@@ -53,55 +53,57 @@
53 <div 53 <div
54 *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'like' }" (click)="setLike()" 54 *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'like' }" (click)="setLike()"
55 class="action-button action-button-like" role="button" [attr.aria-pressed]="userRating === 'like'" 55 class="action-button action-button-like" role="button" [attr.aria-pressed]="userRating === 'like'"
56 i18n-title title="Like this video"
56 > 57 >
57 <span class="icon icon-like" i18n-title title="Like this video" ></span> 58 <my-global-icon iconName="like"></my-global-icon>
58 </div> 59 </div>
59 60
60 <div 61 <div
61 *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'dislike' }" (click)="setDislike()" 62 *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'dislike' }" (click)="setDislike()"
62 class="action-button action-button-dislike" role="button" [attr.aria-pressed]="userRating === 'dislike'" 63 class="action-button action-button-dislike" role="button" [attr.aria-pressed]="userRating === 'dislike'"
64 i18n-title title="Dislike this video"
63 > 65 >
64 <span class="icon icon-dislike" i18n-title title="Dislike this video"></span> 66 <my-global-icon iconName="dislike"></my-global-icon>
65 </div> 67 </div>
66 68
67 <div *ngIf="video.support" (click)="showSupportModal()" class="action-button action-button-support"> 69 <div *ngIf="video.support" (click)="showSupportModal()" class="action-button action-button-support">
68 <span class="icon icon-support"></span> 70 <my-global-icon iconName="heart"></my-global-icon>
69 <span class="icon-text" i18n>Support</span> 71 <span class="icon-text" i18n>Support</span>
70 </div> 72 </div>
71 73
72 <div (click)="showShareModal()" class="action-button action-button-share" role="button"> 74 <div (click)="showShareModal()" class="action-button action-button-share" role="button">
73 <span class="icon icon-share"></span> 75 <my-global-icon iconName="share"></my-global-icon>
74 <span class="icon-text" i18n>Share</span> 76 <span class="icon-text" i18n>Share</span>
75 </div> 77 </div>
76 78
77 <div class="action-more" ngbDropdown placement="top" role="button"> 79 <div class="action-more" ngbDropdown placement="top" role="button">
78 <div class="action-button" ngbDropdownToggle role="button"> 80 <div class="action-button" ngbDropdownToggle role="button">
79 <span class="icon icon-more"></span> 81 <my-global-icon class="more-icon" iconName="more"></my-global-icon>
80 </div> 82 </div>
81 83
82 <div ngbDropdownMenu> 84 <div ngbDropdownMenu>
83 <a class="dropdown-item" i18n-title title="Download the video" href="#" (click)="showDownloadModal($event)"> 85 <a class="dropdown-item" i18n-title title="Download the video" href="#" (click)="showDownloadModal($event)">
84 <span class="icon icon-download"></span> <ng-container i18n>Download</ng-container> 86 <my-global-icon iconName="download"></my-global-icon> <ng-container i18n>Download</ng-container>
85 </a> 87 </a>
86 88
87 <a *ngIf="isUserLoggedIn()" class="dropdown-item" i18n-title title="Report this video" href="#" (click)="showReportModal($event)"> 89 <a *ngIf="isUserLoggedIn()" class="dropdown-item" i18n-title title="Report this video" href="#" (click)="showReportModal($event)">
88 <span class="icon icon-alert"></span> <ng-container i18n>Report</ng-container> 90 <my-global-icon iconName="alert"></my-global-icon> <ng-container i18n>Report</ng-container>
89 </a> 91 </a>
90 92
91 <a *ngIf="isVideoUpdatable()" class="dropdown-item" i18n-title title="Update this video" href="#" [routerLink]="[ '/videos/update', video.uuid ]"> 93 <a *ngIf="isVideoUpdatable()" class="dropdown-item" i18n-title title="Update this video" href="#" [routerLink]="[ '/videos/update', video.uuid ]">
92 <span class="icon icon-edit"></span> <ng-container i18n>Update</ng-container> 94 <my-global-icon iconName="edit"></my-global-icon> <ng-container i18n>Update</ng-container>
93 </a> 95 </a>
94 96
95 <a *ngIf="isVideoBlacklistable()" class="dropdown-item" i18n-title title="Blacklist this video" href="#" (click)="showBlacklistModal($event)"> 97 <a *ngIf="isVideoBlacklistable()" class="dropdown-item" i18n-title title="Blacklist this video" href="#" (click)="showBlacklistModal($event)">
96 <span class="icon icon-blacklist"></span> <ng-container i18n>Blacklist</ng-container> 98 <my-global-icon iconName="no"></my-global-icon> <ng-container i18n>Blacklist</ng-container>
97 </a> 99 </a>
98 100
99 <a *ngIf="isVideoUnblacklistable()" class="dropdown-item" i18n-title title="Unblacklist this video" href="#" (click)="unblacklistVideo($event)"> 101 <a *ngIf="isVideoUnblacklistable()" class="dropdown-item" i18n-title title="Unblacklist this video" href="#" (click)="unblacklistVideo($event)">
100 <span class="icon icon-unblacklist"></span> <ng-container i18n>Unblacklist</ng-container> 102 <my-global-icon iconName="undo"></my-global-icon> <ng-container i18n>Unblacklist</ng-container>
101 </a> 103 </a>
102 104
103 <a *ngIf="isVideoRemovable()" class="dropdown-item" i18n-title title="Delete this video" href="#" (click)="removeVideo($event)"> 105 <a *ngIf="isVideoRemovable()" class="dropdown-item" i18n-title title="Delete this video" href="#" (click)="removeVideo($event)">
104 <span class="icon icon-delete"></span> <ng-container i18n>Delete</ng-container> 106 <my-global-icon iconName="delete"></my-global-icon> <ng-container i18n>Delete</ng-container>
105 </a> 107 </a>
106 </div> 108 </div>
107 </div> 109 </div>
diff --git a/client/src/app/videos/+video-watch/video-watch.component.scss b/client/src/app/videos/+video-watch/video-watch.component.scss
index 2586a2204..b03ed197d 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.scss
+++ b/client/src/app/videos/+video-watch/video-watch.component.scss
@@ -183,6 +183,8 @@ $other-videos-width: 260px;
183 .action-button { 183 .action-button {
184 @include peertube-button; 184 @include peertube-button;
185 @include grey-button; 185 @include grey-button;
186 @include button-with-icon(21px, 0, -1px);
187 @include apply-svg-color($grey-foreground-color);
186 188
187 font-size: 15px; 189 font-size: 15px;
188 font-weight: $font-semibold; 190 font-weight: $font-semibold;
@@ -194,53 +196,25 @@ $other-videos-width: 260px;
194 display: none; 196 display: none;
195 } 197 }
196 198
197 .icon {
198 @include icon(21px);
199
200 position: relative;
201 top: -2px;
202
203 &.icon-like {
204 background-image: url('../../../assets/images/video/like-grey.svg');
205 }
206
207 &.icon-dislike {
208 background-image: url('../../../assets/images/video/dislike-grey.svg');
209 }
210
211 &.icon-support {
212 background-image: url('../../../assets/images/video/heart.svg');
213 }
214
215 &.icon-share {
216 background-image: url('../../../assets/images/video/share.svg');
217 }
218
219 &.icon-more {
220 background-image: url('../../../assets/images/video/more.svg');
221 top: -1px;
222 }
223 }
224
225 .icon-text {
226 margin-left: 3px;
227 }
228
229 &.action-button-like.activated { 199 &.action-button-like.activated {
230 background-color: $green; 200 background-color: $green;
231 201
232 .icon-like { 202 my-global-icon {
233 background-image: url('../../../assets/images/video/like-white.svg'); 203 @include apply-svg-color(#fff);
234 } 204 }
235 } 205 }
236 206
237 &.action-button-dislike.activated { 207 &.action-button-dislike.activated {
238 background-color: $red; 208 background-color: $red;
239 209
240 .icon-dislike { 210 my-global-icon {
241 background-image: url('../../../assets/images/video/dislike-white.svg'); 211 @include apply-svg-color(#fff);
242 } 212 }
243 } 213 }
214
215 .icon-text {
216 margin-left: 3px;
217 }
244 } 218 }
245 219
246 .action-more { 220 .action-more {
@@ -249,36 +223,12 @@ $other-videos-width: 260px;
249 .dropdown-menu .dropdown-item { 223 .dropdown-menu .dropdown-item {
250 padding: 6px 24px; 224 padding: 6px 24px;
251 225
252 .icon { 226 my-global-icon {
253 @include icon(24px); 227 width: 24px;
254 228
255 margin-right: 10px; 229 margin-right: 10px;
256 position: relative; 230 position: relative;
257 top: -1px; 231 top: -2px;
258
259 &.icon-download {
260 background-image: url('../../../assets/images/video/download-black.svg');
261 }
262
263 &.icon-edit {
264 background-image: url('../../../assets/images/global/edit-black.svg');
265 }
266
267 &.icon-alert {
268 background-image: url('../../../assets/images/video/alert.svg');
269 }
270
271 &.icon-blacklist {
272 background-image: url('../../../assets/images/video/blacklist.svg');
273 }
274
275 &.icon-unblacklist {
276 background-image: url('../../../assets/images/global/undo.svg');
277 }
278
279 &.icon-delete {
280 background-image: url('../../../assets/images/global/delete-black.svg');
281 }
282 } 232 }
283 } 233 }
284 } 234 }
@@ -320,7 +270,7 @@ $other-videos-width: 260px;
320 .video-info-description-more { 270 .video-info-description-more {
321 cursor: pointer; 271 cursor: pointer;
322 font-weight: $font-semibold; 272 font-weight: $font-semibold;
323 color: #585858; 273 color: $grey-foreground-color;
324 font-size: 14px; 274 font-size: 14px;
325 275
326 .glyphicon { 276 .glyphicon {
@@ -339,7 +289,7 @@ $other-videos-width: 260px;
339 min-width: 91px; 289 min-width: 91px;
340 padding-right: 5px; 290 padding-right: 5px;
341 display: inline-block; 291 display: inline-block;
342 color: #585858; 292 color: $grey-foreground-color;
343 font-weight: $font-bold; 293 font-weight: $font-bold;
344 } 294 }
345 295
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts
index 09ee96bdc..ee504bc58 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -5,7 +5,7 @@ import { RedirectService } from '@app/core/routing/redirect.service'
5import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' 5import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
6import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' 6import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component'
7import { MetaService } from '@ngx-meta/core' 7import { MetaService } from '@ngx-meta/core'
8import { NotificationsService } from 'angular2-notifications' 8import { Notifier, ServerService } from '@app/core'
9import { forkJoin, Subscription } from 'rxjs' 9import { forkJoin, Subscription } from 'rxjs'
10// FIXME: something weird with our path definition in tsconfig and typings 10// FIXME: something weird with our path definition in tsconfig and typings
11// @ts-ignore 11// @ts-ignore
@@ -13,24 +13,23 @@ import videojs from 'video.js'
13import 'videojs-hotkeys' 13import 'videojs-hotkeys'
14import { Hotkey, HotkeysService } from 'angular2-hotkeys' 14import { Hotkey, HotkeysService } from 'angular2-hotkeys'
15import * as WebTorrent from 'webtorrent' 15import * as WebTorrent from 'webtorrent'
16import { UserVideoRateType, VideoCaption, VideoPrivacy, VideoRateType, VideoState } from '../../../../../shared' 16import { UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '../../../../../shared'
17import '../../../assets/player/peertube-videojs-plugin' 17import '../../../assets/player/peertube-videojs-plugin'
18import { AuthService, ConfirmService } from '../../core' 18import { AuthService, ConfirmService } from '../../core'
19import { RestExtractor, VideoBlacklistService } from '../../shared' 19import { RestExtractor, VideoBlacklistService } from '../../shared'
20import { VideoDetails } from '../../shared/video/video-details.model' 20import { VideoDetails } from '../../shared/video/video-details.model'
21import { VideoService } from '../../shared/video/video.service' 21import { VideoService } from '../../shared/video/video.service'
22import { MarkdownService } from '../shared'
23import { VideoDownloadComponent } from './modal/video-download.component' 22import { VideoDownloadComponent } from './modal/video-download.component'
24import { VideoReportComponent } from './modal/video-report.component' 23import { VideoReportComponent } from './modal/video-report.component'
25import { VideoShareComponent } from './modal/video-share.component' 24import { VideoShareComponent } from './modal/video-share.component'
26import { VideoBlacklistComponent } from './modal/video-blacklist.component' 25import { VideoBlacklistComponent } from './modal/video-blacklist.component'
27import { SubscribeButtonComponent } from '@app/shared/user-subscription/subscribe-button.component' 26import { SubscribeButtonComponent } from '@app/shared/user-subscription/subscribe-button.component'
28import { addContextMenu, getVideojsOptions, loadLocaleInVideoJS } from '../../../assets/player/peertube-player' 27import { addContextMenu, getVideojsOptions, loadLocaleInVideoJS } from '../../../assets/player/peertube-player'
29import { ServerService } from '@app/core'
30import { I18n } from '@ngx-translate/i18n-polyfill' 28import { I18n } from '@ngx-translate/i18n-polyfill'
31import { environment } from '../../../environments/environment' 29import { environment } from '../../../environments/environment'
32import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils' 30import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils'
33import { VideoCaptionService } from '@app/shared/video-caption' 31import { VideoCaptionService } from '@app/shared/video-caption'
32import { MarkdownService } from '@app/shared/renderer'
34 33
35@Component({ 34@Component({
36 selector: 'my-video-watch', 35 selector: 'my-video-watch',
@@ -77,7 +76,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
77 private authService: AuthService, 76 private authService: AuthService,
78 private serverService: ServerService, 77 private serverService: ServerService,
79 private restExtractor: RestExtractor, 78 private restExtractor: RestExtractor,
80 private notificationsService: NotificationsService, 79 private notifier: Notifier,
81 private markdownService: MarkdownService, 80 private markdownService: MarkdownService,
82 private zone: NgZone, 81 private zone: NgZone,
83 private redirectService: RedirectService, 82 private redirectService: RedirectService,
@@ -118,7 +117,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
118 ) 117 )
119 .subscribe(([ video, captionsResult ]) => { 118 .subscribe(([ video, captionsResult ]) => {
120 const startTime = this.route.snapshot.queryParams.start 119 const startTime = this.route.snapshot.queryParams.start
121 this.onVideoFetched(video, captionsResult.data, startTime) 120 const subtitle = this.route.snapshot.queryParams.subtitle
121
122 this.onVideoFetched(video, captionsResult.data, { startTime, subtitle })
122 .catch(err => this.handleError(err)) 123 .catch(err => this.handleError(err))
123 }) 124 })
124 }) 125 })
@@ -203,7 +204,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
203 204
204 error => { 205 error => {
205 this.descriptionLoading = false 206 this.descriptionLoading = false
206 this.notificationsService.error(this.i18n('Error'), error.message) 207 this.notifier.error(error.message)
207 } 208 }
208 ) 209 )
209 } 210 }
@@ -245,16 +246,13 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
245 246
246 this.videoBlacklistService.removeVideoFromBlacklist(this.video.id).subscribe( 247 this.videoBlacklistService.removeVideoFromBlacklist(this.video.id).subscribe(
247 () => { 248 () => {
248 this.notificationsService.success( 249 this.notifier.success(this.i18n('Video {{name}} removed from the blacklist.', { name: this.video.name }))
249 this.i18n('Success'),
250 this.i18n('Video {{name}} removed from the blacklist.', { name: this.video.name })
251 )
252 250
253 this.video.blacklisted = false 251 this.video.blacklisted = false
254 this.video.blacklistedReason = null 252 this.video.blacklistedReason = null
255 }, 253 },
256 254
257 err => this.notificationsService.error(this.i18n('Error'), err.message) 255 err => this.notifier.error(err.message)
258 ) 256 )
259 } 257 }
260 258
@@ -292,17 +290,14 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
292 290
293 this.videoService.removeVideo(this.video.id) 291 this.videoService.removeVideo(this.video.id)
294 .subscribe( 292 .subscribe(
295 status => { 293 () => {
296 this.notificationsService.success( 294 this.notifier.success(this.i18n('Video {{videoName}} deleted.', { videoName: this.video.name }))
297 this.i18n('Success'),
298 this.i18n('Video {{videoName}} deleted.', { videoName: this.video.name })
299 )
300 295
301 // Go back to the video-list. 296 // Go back to the video-list.
302 this.redirectService.redirectToHomepage() 297 this.redirectService.redirectToHomepage()
303 }, 298 },
304 299
305 error => this.notificationsService.error(this.i18n('Error'), error.message) 300 error => this.notifier.error(error.message)
306 ) 301 )
307 } 302 }
308 303
@@ -352,7 +347,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
352 return 347 return
353 } 348 }
354 349
355 this.notificationsService.error(this.i18n('Error'), errorMessage) 350 this.notifier.error(errorMessage)
356 } 351 }
357 352
358 private checkUserRating () { 353 private checkUserRating () {
@@ -367,11 +362,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
367 } 362 }
368 }, 363 },
369 364
370 err => this.notificationsService.error(this.i18n('Error'), err.message) 365 err => this.notifier.error(err.message)
371 ) 366 )
372 } 367 }
373 368
374 private async onVideoFetched (video: VideoDetails, videoCaptions: VideoCaption[], startTimeFromUrl: number) { 369 private async onVideoFetched (video: VideoDetails, videoCaptions: VideoCaption[], urlOptions: { startTime: number, subtitle: string }) {
375 this.video = video 370 this.video = video
376 371
377 // Re init attributes 372 // Re init attributes
@@ -379,8 +374,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
379 this.completeDescriptionShown = false 374 this.completeDescriptionShown = false
380 this.remoteServerDown = false 375 this.remoteServerDown = false
381 376
382 let startTime = startTimeFromUrl || (this.video.userHistory ? this.video.userHistory.currentTime : 0) 377 let startTime = urlOptions.startTime || (this.video.userHistory ? this.video.userHistory.currentTime : 0)
383 // Don't start the video if we are at the end 378 // If we are at the end of the video, reset the timer
384 if (this.video.duration - startTime <= 1) startTime = 0 379 if (this.video.duration - startTime <= 1) startTime = 0
385 380
386 if (this.video.isVideoNSFWForUser(this.user, this.serverService.getConfig())) { 381 if (this.video.isVideoNSFWForUser(this.user, this.serverService.getConfig())) {
@@ -419,10 +414,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
419 peertubeLink: false, 414 peertubeLink: false,
420 poster: this.video.previewUrl, 415 poster: this.video.previewUrl,
421 startTime, 416 startTime,
417 subtitle: urlOptions.subtitle,
422 theaterMode: true, 418 theaterMode: true,
423 language: this.localeId, 419 language: this.localeId,
424 420
425 userWatching: this.user ? { 421 userWatching: this.user && this.user.videosHistoryEnabled === true ? {
426 url: this.videoService.getUserWatchingVideoUrl(this.video.uuid), 422 url: this.videoService.getUserWatchingVideoUrl(this.video.uuid),
427 authorizationHeader: this.authService.getRequestHeaderValue() 423 authorizationHeader: this.authService.getRequestHeaderValue()
428 } : undefined 424 } : undefined
@@ -472,7 +468,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
472 this.userRating = nextRating 468 this.userRating = nextRating
473 }, 469 },
474 470
475 (err: { message: string }) => this.notificationsService.error(this.i18n('Error'), err.message) 471 (err: { message: string }) => this.notifier.error(err.message)
476 ) 472 )
477 } 473 }
478 474
diff --git a/client/src/app/videos/+video-watch/video-watch.module.ts b/client/src/app/videos/+video-watch/video-watch.module.ts
index 54a12c126..2f448db78 100644
--- a/client/src/app/videos/+video-watch/video-watch.module.ts
+++ b/client/src/app/videos/+video-watch/video-watch.module.ts
@@ -1,9 +1,7 @@
1import { NgModule } from '@angular/core' 1import { NgModule } from '@angular/core'
2import { LinkifierService } from '@app/videos/+video-watch/comment/linkifier.service'
3import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' 2import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component'
4import { ClipboardModule } from 'ngx-clipboard' 3import { ClipboardModule } from 'ngx-clipboard'
5import { SharedModule } from '../../shared' 4import { SharedModule } from '../../shared'
6import { MarkdownService } from '../shared'
7import { VideoCommentAddComponent } from './comment/video-comment-add.component' 5import { VideoCommentAddComponent } from './comment/video-comment-add.component'
8import { VideoCommentComponent } from './comment/video-comment.component' 6import { VideoCommentComponent } from './comment/video-comment.component'
9import { VideoCommentService } from './comment/video-comment.service' 7import { VideoCommentService } from './comment/video-comment.service'
@@ -46,8 +44,6 @@ import { RecommendationsModule } from '@app/videos/recommendations/recommendatio
46 ], 44 ],
47 45
48 providers: [ 46 providers: [
49 MarkdownService,
50 LinkifierService,
51 VideoCommentService 47 VideoCommentService
52 ] 48 ]
53}) 49})
diff --git a/client/src/app/videos/shared/index.ts b/client/src/app/videos/shared/index.ts
deleted file mode 100644
index 7a66944b9..000000000
--- a/client/src/app/videos/shared/index.ts
+++ /dev/null
@@ -1 +0,0 @@
1export * from './markdown.service'
diff --git a/client/src/app/videos/video-list/video-local.component.ts b/client/src/app/videos/video-list/video-local.component.ts
index 9d000cf2e..c0be4b885 100644
--- a/client/src/app/videos/video-list/video-local.component.ts
+++ b/client/src/app/videos/video-list/video-local.component.ts
@@ -2,7 +2,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { immutableAssign } from '@app/shared/misc/utils' 3import { immutableAssign } from '@app/shared/misc/utils'
4import { Location } from '@angular/common' 4import { Location } from '@angular/common'
5import { NotificationsService } from 'angular2-notifications'
6import { AuthService } from '../../core/auth' 5import { AuthService } from '../../core/auth'
7import { AbstractVideoList } from '../../shared/video/abstract-video-list' 6import { AbstractVideoList } from '../../shared/video/abstract-video-list'
8import { VideoSortField } from '../../shared/video/sort-field.type' 7import { VideoSortField } from '../../shared/video/sort-field.type'
@@ -11,6 +10,7 @@ import { VideoFilter } from '../../../../../shared/models/videos/video-query.typ
11import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
12import { ScreenService } from '@app/shared/misc/screen.service' 11import { ScreenService } from '@app/shared/misc/screen.service'
13import { UserRight } from '../../../../../shared/models/users' 12import { UserRight } from '../../../../../shared/models/users'
13import { Notifier } from '@app/core'
14 14
15@Component({ 15@Component({
16 selector: 'my-videos-local', 16 selector: 'my-videos-local',
@@ -26,7 +26,7 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On
26 constructor ( 26 constructor (
27 protected router: Router, 27 protected router: Router,
28 protected route: ActivatedRoute, 28 protected route: ActivatedRoute,
29 protected notificationsService: NotificationsService, 29 protected notifier: Notifier,
30 protected authService: AuthService, 30 protected authService: AuthService,
31 protected location: Location, 31 protected location: Location,
32 protected i18n: I18n, 32 protected i18n: I18n,
diff --git a/client/src/app/videos/video-list/video-overview.component.ts b/client/src/app/videos/video-list/video-overview.component.ts
index 2c6054721..7ff52b259 100644
--- a/client/src/app/videos/video-list/video-overview.component.ts
+++ b/client/src/app/videos/video-list/video-overview.component.ts
@@ -1,6 +1,5 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { AuthService } from '@app/core' 2import { AuthService, Notifier } from '@app/core'
3import { NotificationsService } from 'angular2-notifications'
4import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
5import { VideosOverview } from '@app/shared/overview/videos-overview.model' 4import { VideosOverview } from '@app/shared/overview/videos-overview.model'
6import { OverviewService } from '@app/shared/overview' 5import { OverviewService } from '@app/shared/overview'
@@ -21,7 +20,7 @@ export class VideoOverviewComponent implements OnInit {
21 20
22 constructor ( 21 constructor (
23 private i18n: I18n, 22 private i18n: I18n,
24 private notificationsService: NotificationsService, 23 private notifier: Notifier,
25 private authService: AuthService, 24 private authService: AuthService,
26 private overviewService: OverviewService 25 private overviewService: OverviewService
27 ) { } 26 ) { }
@@ -43,10 +42,7 @@ export class VideoOverviewComponent implements OnInit {
43 ) this.notResults = true 42 ) this.notResults = true
44 }, 43 },
45 44
46 err => { 45 err => this.notifier.error(err.message)
47 console.log(err)
48 this.notificationsService.error('Error', err.text)
49 }
50 ) 46 )
51 } 47 }
52 48
diff --git a/client/src/app/videos/video-list/video-recently-added.component.ts b/client/src/app/videos/video-list/video-recently-added.component.ts
index ac1fcfff3..f99c8abb6 100644
--- a/client/src/app/videos/video-list/video-recently-added.component.ts
+++ b/client/src/app/videos/video-list/video-recently-added.component.ts
@@ -2,13 +2,13 @@ import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { Location } from '@angular/common' 3import { Location } from '@angular/common'
4import { immutableAssign } from '@app/shared/misc/utils' 4import { immutableAssign } from '@app/shared/misc/utils'
5import { NotificationsService } from 'angular2-notifications'
6import { AuthService } from '../../core/auth' 5import { AuthService } from '../../core/auth'
7import { AbstractVideoList } from '../../shared/video/abstract-video-list' 6import { AbstractVideoList } from '../../shared/video/abstract-video-list'
8import { VideoSortField } from '../../shared/video/sort-field.type' 7import { VideoSortField } from '../../shared/video/sort-field.type'
9import { VideoService } from '../../shared/video/video.service' 8import { VideoService } from '../../shared/video/video.service'
10import { I18n } from '@ngx-translate/i18n-polyfill' 9import { I18n } from '@ngx-translate/i18n-polyfill'
11import { ScreenService } from '@app/shared/misc/screen.service' 10import { ScreenService } from '@app/shared/misc/screen.service'
11import { Notifier } from '@app/core'
12 12
13@Component({ 13@Component({
14 selector: 'my-videos-recently-added', 14 selector: 'my-videos-recently-added',
@@ -24,7 +24,7 @@ export class VideoRecentlyAddedComponent extends AbstractVideoList implements On
24 protected router: Router, 24 protected router: Router,
25 protected route: ActivatedRoute, 25 protected route: ActivatedRoute,
26 protected location: Location, 26 protected location: Location,
27 protected notificationsService: NotificationsService, 27 protected notifier: Notifier,
28 protected authService: AuthService, 28 protected authService: AuthService,
29 protected i18n: I18n, 29 protected i18n: I18n,
30 protected screenService: ScreenService, 30 protected screenService: ScreenService,
diff --git a/client/src/app/videos/video-list/video-trending.component.ts b/client/src/app/videos/video-list/video-trending.component.ts
index 8f3d3842b..6fd74e67a 100644
--- a/client/src/app/videos/video-list/video-trending.component.ts
+++ b/client/src/app/videos/video-list/video-trending.component.ts
@@ -2,13 +2,13 @@ import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { Location } from '@angular/common' 3import { Location } from '@angular/common'
4import { immutableAssign } from '@app/shared/misc/utils' 4import { immutableAssign } from '@app/shared/misc/utils'
5import { NotificationsService } from 'angular2-notifications'
6import { AuthService } from '../../core/auth' 5import { AuthService } from '../../core/auth'
7import { AbstractVideoList } from '../../shared/video/abstract-video-list' 6import { AbstractVideoList } from '../../shared/video/abstract-video-list'
8import { VideoSortField } from '../../shared/video/sort-field.type' 7import { VideoSortField } from '../../shared/video/sort-field.type'
9import { VideoService } from '../../shared/video/video.service' 8import { VideoService } from '../../shared/video/video.service'
10import { I18n } from '@ngx-translate/i18n-polyfill' 9import { I18n } from '@ngx-translate/i18n-polyfill'
11import { ScreenService } from '@app/shared/misc/screen.service' 10import { ScreenService } from '@app/shared/misc/screen.service'
11import { Notifier, ServerService } from '@app/core'
12 12
13@Component({ 13@Component({
14 selector: 'my-videos-trending', 14 selector: 'my-videos-trending',
@@ -23,22 +23,37 @@ export class VideoTrendingComponent extends AbstractVideoList implements OnInit,
23 constructor ( 23 constructor (
24 protected router: Router, 24 protected router: Router,
25 protected route: ActivatedRoute, 25 protected route: ActivatedRoute,
26 protected notificationsService: NotificationsService, 26 protected notifier: Notifier,
27 protected authService: AuthService, 27 protected authService: AuthService,
28 protected location: Location, 28 protected location: Location,
29 protected screenService: ScreenService, 29 protected screenService: ScreenService,
30 private serverService: ServerService,
30 protected i18n: I18n, 31 protected i18n: I18n,
31 private videoService: VideoService 32 private videoService: VideoService
32 ) { 33 ) {
33 super() 34 super()
34
35 this.titlePage = i18n('Trending')
36 } 35 }
37 36
38 ngOnInit () { 37 ngOnInit () {
39 super.ngOnInit() 38 super.ngOnInit()
40 39
41 this.generateSyndicationList() 40 this.generateSyndicationList()
41
42 this.serverService.configLoaded.subscribe(
43 () => {
44 const trendingDays = this.serverService.getConfig().trending.videos.intervalDays
45
46 if (trendingDays === 1) {
47 this.titlePage = this.i18n('Trending for the last 24 hours')
48 this.titleTooltip = this.i18n('Trending videos are those totalizing the greatest number of views during the last 24 hours.')
49 } else {
50 this.titlePage = this.i18n('Trending for the last {{days}} days', { days: trendingDays })
51 this.titleTooltip = this.i18n(
52 'Trending videos are those totalizing the greatest number of views during the last {{days}} days.',
53 { days: trendingDays }
54 )
55 }
56 })
42 } 57 }
43 58
44 ngOnDestroy () { 59 ngOnDestroy () {
diff --git a/client/src/app/videos/video-list/video-user-subscriptions.component.ts b/client/src/app/videos/video-list/video-user-subscriptions.component.ts
index 6e8959c54..bee828e12 100644
--- a/client/src/app/videos/video-list/video-user-subscriptions.component.ts
+++ b/client/src/app/videos/video-list/video-user-subscriptions.component.ts
@@ -2,7 +2,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { immutableAssign } from '@app/shared/misc/utils' 3import { immutableAssign } from '@app/shared/misc/utils'
4import { Location } from '@angular/common' 4import { Location } from '@angular/common'
5import { NotificationsService } from 'angular2-notifications'
6import { AuthService } from '../../core/auth' 5import { AuthService } from '../../core/auth'
7import { AbstractVideoList } from '../../shared/video/abstract-video-list' 6import { AbstractVideoList } from '../../shared/video/abstract-video-list'
8import { VideoSortField } from '../../shared/video/sort-field.type' 7import { VideoSortField } from '../../shared/video/sort-field.type'
@@ -10,6 +9,7 @@ import { VideoService } from '../../shared/video/video.service'
10import { I18n } from '@ngx-translate/i18n-polyfill' 9import { I18n } from '@ngx-translate/i18n-polyfill'
11import { ScreenService } from '@app/shared/misc/screen.service' 10import { ScreenService } from '@app/shared/misc/screen.service'
12import { OwnerDisplayType } from '@app/shared/video/video-miniature.component' 11import { OwnerDisplayType } from '@app/shared/video/video-miniature.component'
12import { Notifier } from '@app/core'
13 13
14@Component({ 14@Component({
15 selector: 'my-videos-user-subscriptions', 15 selector: 'my-videos-user-subscriptions',
@@ -25,7 +25,7 @@ export class VideoUserSubscriptionsComponent extends AbstractVideoList implement
25 constructor ( 25 constructor (
26 protected router: Router, 26 protected router: Router,
27 protected route: ActivatedRoute, 27 protected route: ActivatedRoute,
28 protected notificationsService: NotificationsService, 28 protected notifier: Notifier,
29 protected authService: AuthService, 29 protected authService: AuthService,
30 protected location: Location, 30 protected location: Location,
31 protected i18n: I18n, 31 protected i18n: I18n,
diff --git a/client/src/assets/images/global/add.svg b/client/src/assets/images/global/add.html
index 42b269c43..bfb0a52bc 100644
--- a/client/src/assets/images/global/add.svg
+++ b/client/src/assets/images/global/add.html
@@ -1,8 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 3 <g transform="translate(-92.000000, -115.000000)">
5 <g id="Artboard-4" transform="translate(-92.000000, -115.000000)">
6 <g id="2" transform="translate(92.000000, 115.000000)"> 4 <g id="2" transform="translate(92.000000, 115.000000)">
7 <circle id="Oval-1" stroke="#ffffff" stroke-width="2" cx="12" cy="12" r="10"></circle> 5 <circle id="Oval-1" stroke="#ffffff" stroke-width="2" cx="12" cy="12" r="10"></circle>
8 <rect id="Rectangle-1" fill="#ffffff" x="11" y="7" width="2" height="10" rx="1"></rect> 6 <rect id="Rectangle-1" fill="#ffffff" x="11" y="7" width="2" height="10" rx="1"></rect>
diff --git a/client/src/assets/images/video/alert.svg b/client/src/assets/images/global/alert.html
index 5b43534ad..7c8c02074 100644
--- a/client/src/assets/images/video/alert.svg
+++ b/client/src/assets/images/global/alert.html
@@ -1,11 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch --> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4 <title>alert</title> 3 <g transform="translate(-48.000000, -467.000000)">
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8 <g id="Artboard-4" transform="translate(-48.000000, -467.000000)">
9 <g id="161" transform="translate(48.000000, 467.000000)"> 4 <g id="161" transform="translate(48.000000, 467.000000)">
10 <path d="M12.8715755,3.50973876 L12,1.96027114 L11.1284245,3.50973876 L2.12842446,19.5097388 L1.29015252,21 L3,21 L21,21 L22.7098475,21 L21.8715755,19.5097388 L12.8715755,3.50973876 Z" id="Triangle-2" stroke="#000000" stroke-width="2" stroke-linejoin="round"></path> 5 <path d="M12.8715755,3.50973876 L12,1.96027114 L11.1284245,3.50973876 L2.12842446,19.5097388 L1.29015252,21 L3,21 L21,21 L22.7098475,21 L21.8715755,19.5097388 L12.8715755,3.50973876 Z" id="Triangle-2" stroke="#000000" stroke-width="2" stroke-linejoin="round"></path>
11 <path d="M12,17.75 C12.6903559,17.75 13.25,17.1903559 13.25,16.5 C13.25,15.8096441 12.6903559,15.25 12,15.25 C11.3096441,15.25 10.75,15.8096441 10.75,16.5 C10.75,17.1903559 11.3096441,17.75 12,17.75 Z" id="Oval-8" fill="#000000"></path> 6 <path d="M12,17.75 C12.6903559,17.75 13.25,17.1903559 13.25,16.5 C13.25,15.8096441 12.6903559,15.25 12,15.25 C11.3096441,15.25 10.75,15.8096441 10.75,16.5 C10.75,17.1903559 11.3096441,17.75 12,17.75 Z" id="Oval-8" fill="#000000"></path>
diff --git a/client/src/assets/images/global/circle-tick.html b/client/src/assets/images/global/circle-tick.html
new file mode 100644
index 000000000..2327de6be
--- /dev/null
+++ b/client/src/assets/images/global/circle-tick.html
@@ -0,0 +1,12 @@
1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
3 <g transform="translate(-400.000000, -1134.000000)" stroke="#000000" stroke-width="2">
4 <g id="Extras" transform="translate(48.000000, 1046.000000)">
5 <g id="yes" transform="translate(352.000000, 88.000000)">
6 <circle id="Oval-1" cx="12" cy="12" r="10"/>
7 <polyline id="Path-288" stroke-linecap="round" stroke-linejoin="round" points="8.5 12.5 10.5 14.5 15.5 9.5"/>
8 </g>
9 </g>
10 </g>
11 </g>
12</svg>
diff --git a/client/src/assets/images/global/cloud-download.html b/client/src/assets/images/global/cloud-download.html
new file mode 100644
index 000000000..b2634fd1f
--- /dev/null
+++ b/client/src/assets/images/global/cloud-download.html
@@ -0,0 +1,11 @@
1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
3 <g transform="translate(-356.000000, -775.000000)" stroke="#000000" stroke-width="2">
4 <g id="308" transform="translate(356.000000, 775.000000)">
5 <path d="M8,17 L5,17 L5,17 C2.790861,17 1,15.209139 1,13 C1,10.790861 2.790861,9 5,9 C5.35840468,9 5.70579988,9.04713713 6.03632437,9.13555013 C6.01233106,8.92702603 6,8.71495305 6,8.5 C6,5.46243388 8.46243388,3 11.5,3 C14.0673313,3 16.2238156,4.7590449 16.8299648,7.1376465 C17.2052921,7.04765874 17.5970804,7 18,7 C20.7614237,7 23,9.23857625 23,12 C23,14.7614237 20.7614237,17 18,17 L16,17" id="Combined-Shape" stroke-linejoin="round"></path>
6 <path d="M12,13 L12,21" id="Path-58"></path>
7 <polyline id="Path-59" stroke-linejoin="round" points="15 20 12 23 9 20"></polyline>
8 </g>
9 </g>
10 </g>
11</svg>
diff --git a/client/src/assets/images/global/cloud-error.html b/client/src/assets/images/global/cloud-error.html
new file mode 100644
index 000000000..1a3483805
--- /dev/null
+++ b/client/src/assets/images/global/cloud-error.html
@@ -0,0 +1,11 @@
1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
3 <g transform="translate(-400.000000, -775.000000)" stroke="#000000" stroke-width="2">
4 <g id="309" transform="translate(400.000000, 775.000000)">
5 <path d="M7,18 L5,18 C2.790861,18 1,16.209139 1,14 C1,11.790861 2.790861,10 5,10 C5.35840468,10 5.70579988,10.0471371 6.03632437,10.1355501 C6.01233106,9.92702603 6,9.71495305 6,9.5 C6,6.46243388 8.46243388,4 11.5,4 C14.0673313,4 16.2238156,5.7590449 16.8299648,8.1376465 C17.2052921,8.04765874 17.5970804,8 18,8 C20.7614237,8 23,10.2385763 23,13 C23,15.7614237 20.7614237,18 18,18 L17,18" id="Combined-Shape"></path>
6 <path d="M9,21 L15,15" id="Path-238"></path>
7 <path d="M9,21 L15,15" id="Path-238" transform="translate(12.000000, 18.000000) scale(-1, 1) translate(-12.000000, -18.000000) "></path>
8 </g>
9 </g>
10 </g>
11</svg>
diff --git a/client/src/assets/images/global/cog.html b/client/src/assets/images/global/cog.html
new file mode 100644
index 000000000..b74a180e7
--- /dev/null
+++ b/client/src/assets/images/global/cog.html
@@ -0,0 +1,9 @@
1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linejoin="round">
3 <g transform="translate(-796.000000, -159.000000)" stroke="#000000" stroke-width="2">
4 <g id="38" transform="translate(796.000000, 159.000000)">
5 <path d="M7.20852293,4.3800958 C8.05442158,3.84706631 8.99528987,3.45099725 10,3.22301642 L10,1.99980749 C10,1.44762906 10.4433532,1 11.0093689,1 L12.9906311,1 C13.5480902,1 14,1.44371665 14,1.99980749 L14,3.22301642 C15.0047101,3.45099725 15.9455784,3.84706631 16.7914771,4.3800958 L17.6569904,3.5145825 C18.0474395,3.12413339 18.6774591,3.12110988 19.0776926,3.52134344 L20.4786566,4.92230738 C20.8728396,5.31649045 20.8786331,5.94979402 20.4854175,6.34300963 L19.6199042,7.20852293 C20.1529337,8.05442158 20.5490027,8.99528987 20.7769836,10 L22.0001925,10 C22.5523709,10 23,10.4433532 23,11.0093689 L23,12.9906311 C23,13.5480902 22.5562834,14 22.0001925,14 L20.7769836,14 C20.5490027,15.0047101 20.1529337,15.9455784 19.6199042,16.7914771 L20.4854175,17.6569904 C20.8758666,18.0474395 20.8788901,18.6774591 20.4786566,19.0776926 L19.0776926,20.4786566 C18.6835095,20.8728396 18.050206,20.8786331 17.6569904,20.4854175 L16.7914771,19.6199042 C15.9455784,20.1529337 15.0047101,20.5490027 14,20.7769836 L14,22.0001925 C14,22.5523709 13.5566468,23 12.9906311,23 L11.0093689,23 C10.4519098,23 10,22.5562834 10,22.0001925 L10,20.7769836 C8.99528987,20.5490027 8.05442158,20.1529337 7.20852293,19.6199042 L6.34300963,20.4854175 C5.95256051,20.8758666 5.32254093,20.8788901 4.92230738,20.4786566 L3.52134344,19.0776926 C3.12716036,18.6835095 3.12136689,18.050206 3.5145825,17.6569904 L4.3800958,16.7914771 C3.84706631,15.9455784 3.45099725,15.0047101 3.22301642,14 L1.99980749,14 C1.44762906,14 1,13.5566468 1,12.9906311 L1,11.0093689 C1,10.4519098 1.44371665,10 1.99980749,10 L3.22301642,10 C3.45099725,8.99528987 3.84706631,8.05442158 4.3800958,7.20852293 L3.5145825,6.34300963 C3.12413339,5.95256051 3.12110988,5.32254093 3.52134344,4.92230738 L4.92230738,3.52134344 C5.31649045,3.12716036 5.94979402,3.12136689 6.34300963,3.5145825 L7.20852293,4.3800958 Z M12,16 C14.209139,16 16,14.209139 16,12 C16,9.790861 14.209139,8 12,8 C9.790861,8 8,9.790861 8,12 C8,14.209139 9.790861,16 12,16 Z" id="Combined-Shape"/>
6 </g>
7 </g>
8 </g>
9</svg>
diff --git a/client/src/assets/images/global/cross.svg b/client/src/assets/images/global/cross.html
index d47a75996..962578487 100644
--- a/client/src/assets/images/global/cross.svg
+++ b/client/src/assets/images/global/cross.html
@@ -1,8 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round"> 3 <g transform="translate(-312.000000, -115.000000)" stroke="#000000" stroke-width="2">
5 <g id="Artboard-4" transform="translate(-312.000000, -115.000000)" stroke="#585858" stroke-width="2">
6 <g id="7" transform="translate(312.000000, 115.000000)"> 4 <g id="7" transform="translate(312.000000, 115.000000)">
7 <path d="M19,5 L5,19" id="Path-14"></path> 5 <path d="M19,5 L5,19" id="Path-14"></path>
8 <path d="M19,5 L5,19" id="Path-14" transform="translate(12.000000, 12.000000) scale(-1, 1) translate(-12.000000, -12.000000) "></path> 6 <path d="M19,5 L5,19" id="Path-14" transform="translate(12.000000, 12.000000) scale(-1, 1) translate(-12.000000, -12.000000) "></path>
diff --git a/client/src/assets/images/global/delete-black.svg b/client/src/assets/images/global/delete-black.svg
deleted file mode 100644
index 04ddc23aa..000000000
--- a/client/src/assets/images/global/delete-black.svg
+++ /dev/null
@@ -1,14 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs>
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5 <g id="Artboard-4" transform="translate(-224.000000, -159.000000)">
6 <g id="25" transform="translate(224.000000, 159.000000)">
7 <path d="M5,7 L5,20.0081158 C5,21.1082031 5.89706013,22 7.00585866,22 L16.9941413,22 C18.1019465,22 19,21.1066027 19,20.0081158 L19,7" id="Path-296" stroke="#000" stroke-width="2"></path>
8 <rect id="Rectangle-424" fill="#000" x="2" y="4" width="20" height="2" rx="1"></rect>
9 <path d="M9,10.9970301 C9,10.4463856 9.44386482,10 10,10 C10.5522847,10 11,10.4530363 11,10.9970301 L11,17.0029699 C11,17.5536144 10.5561352,18 10,18 C9.44771525,18 9,17.5469637 9,17.0029699 L9,10.9970301 Z M13,10.9970301 C13,10.4463856 13.4438648,10 14,10 C14.5522847,10 15,10.4530363 15,10.9970301 L15,17.0029699 C15,17.5536144 14.5561352,18 14,18 C13.4477153,18 13,17.5469637 13,17.0029699 L13,10.9970301 Z" id="Combined-Shape" fill="#000"></path>
10 <path d="M9,5 L9,2.99895656 C9,2.44724809 9.45097518,2 9.99077797,2 L14.009222,2 C14.5564136,2 15,2.44266033 15,2.99895656 L15,5" id="Path-33" stroke="#000" stroke-width="2" stroke-linejoin="round"></path>
11 </g>
12 </g>
13 </g>
14</svg>
diff --git a/client/src/assets/images/global/delete-grey.svg b/client/src/assets/images/global/delete-grey.svg
deleted file mode 100644
index 67e9e2ce7..000000000
--- a/client/src/assets/images/global/delete-grey.svg
+++ /dev/null
@@ -1,14 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs>
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5 <g id="Artboard-4" transform="translate(-224.000000, -159.000000)">
6 <g id="25" transform="translate(224.000000, 159.000000)">
7 <path d="M5,7 L5,20.0081158 C5,21.1082031 5.89706013,22 7.00585866,22 L16.9941413,22 C18.1019465,22 19,21.1066027 19,20.0081158 L19,7" id="Path-296" stroke="#585858" stroke-width="2"></path>
8 <rect id="Rectangle-424" fill="#585858" x="2" y="4" width="20" height="2" rx="1"></rect>
9 <path d="M9,10.9970301 C9,10.4463856 9.44386482,10 10,10 C10.5522847,10 11,10.4530363 11,10.9970301 L11,17.0029699 C11,17.5536144 10.5561352,18 10,18 C9.44771525,18 9,17.5469637 9,17.0029699 L9,10.9970301 Z M13,10.9970301 C13,10.4463856 13.4438648,10 14,10 C14.5522847,10 15,10.4530363 15,10.9970301 L15,17.0029699 C15,17.5536144 14.5561352,18 14,18 C13.4477153,18 13,17.5469637 13,17.0029699 L13,10.9970301 Z" id="Combined-Shape" fill="#585858"></path>
10 <path d="M9,5 L9,2.99895656 C9,2.44724809 9.45097518,2 9.99077797,2 L14.009222,2 C14.5564136,2 15,2.44266033 15,2.99895656 L15,5" id="Path-33" stroke="#585858" stroke-width="2" stroke-linejoin="round"></path>
11 </g>
12 </g>
13 </g>
14</svg>
diff --git a/client/src/assets/images/global/delete-white.svg b/client/src/assets/images/global/delete.html
index 9c52de557..a0d9a0cac 100644
--- a/client/src/assets/images/global/delete-white.svg
+++ b/client/src/assets/images/global/delete.html
@@ -1,13 +1,11 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 3 <g transform="translate(-224.000000, -159.000000)">
5 <g id="Artboard-4" transform="translate(-224.000000, -159.000000)">
6 <g id="25" transform="translate(224.000000, 159.000000)"> 4 <g id="25" transform="translate(224.000000, 159.000000)">
7 <path d="M5,7 L5,20.0081158 C5,21.1082031 5.89706013,22 7.00585866,22 L16.9941413,22 C18.1019465,22 19,21.1066027 19,20.0081158 L19,7" id="Path-296" stroke="#ffffff" stroke-width="2"></path> 5 <path d="M5,7 L5,20.0081158 C5,21.1082031 5.89706013,22 7.00585866,22 L16.9941413,22 C18.1019465,22 19,21.1066027 19,20.0081158 L19,7" id="Path-296" stroke="#000000" stroke-width="2"></path>
8 <rect id="Rectangle-424" fill="#ffffff" x="2" y="4" width="20" height="2" rx="1"></rect> 6 <rect id="Rectangle-424" fill="#000000" x="2" y="4" width="20" height="2" rx="1"></rect>
9 <path d="M9,10.9970301 C9,10.4463856 9.44386482,10 10,10 C10.5522847,10 11,10.4530363 11,10.9970301 L11,17.0029699 C11,17.5536144 10.5561352,18 10,18 C9.44771525,18 9,17.5469637 9,17.0029699 L9,10.9970301 Z M13,10.9970301 C13,10.4463856 13.4438648,10 14,10 C14.5522847,10 15,10.4530363 15,10.9970301 L15,17.0029699 C15,17.5536144 14.5561352,18 14,18 C13.4477153,18 13,17.5469637 13,17.0029699 L13,10.9970301 Z" id="Combined-Shape" fill="#ffffff"></path> 7 <path d="M9,10.9970301 C9,10.4463856 9.44386482,10 10,10 C10.5522847,10 11,10.4530363 11,10.9970301 L11,17.0029699 C11,17.5536144 10.5561352,18 10,18 C9.44771525,18 9,17.5469637 9,17.0029699 L9,10.9970301 Z M13,10.9970301 C13,10.4463856 13.4438648,10 14,10 C14.5522847,10 15,10.4530363 15,10.9970301 L15,17.0029699 C15,17.5536144 14.5561352,18 14,18 C13.4477153,18 13,17.5469637 13,17.0029699 L13,10.9970301 Z" id="Combined-Shape" fill="#000000"></path>
10 <path d="M9,5 L9,2.99895656 C9,2.44724809 9.45097518,2 9.99077797,2 L14.009222,2 C14.5564136,2 15,2.44266033 15,2.99895656 L15,5" id="Path-33" stroke="#ffffff" stroke-width="2" stroke-linejoin="round"></path> 8 <path d="M9,5 L9,2.99895656 C9,2.44724809 9.45097518,2 9.99077797,2 L14.009222,2 C14.5564136,2 15,2.44266033 15,2.99895656 L15,5" id="Path-33" stroke="#000000" stroke-width="2" stroke-linejoin="round"></path>
11 </g> 9 </g>
12 </g> 10 </g>
13 </g> 11 </g>
diff --git a/client/src/assets/images/video/download-black.svg b/client/src/assets/images/global/download.html
index 501836746..259506f31 100644
--- a/client/src/assets/images/video/download-black.svg
+++ b/client/src/assets/images/global/download.html
@@ -1,11 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch --> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
4 <title>download</title> 3 <g transform="translate(-180.000000, -291.000000)" stroke="#000000" stroke-width="2">
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
8 <g id="Artboard-4" transform="translate(-180.000000, -291.000000)" stroke="#000000" stroke-width="2">
9 <g id="84" transform="translate(180.000000, 291.000000)"> 4 <g id="84" transform="translate(180.000000, 291.000000)">
10 <path d="M12,3 L12,15" id="Path-58"></path> 5 <path d="M12,3 L12,15" id="Path-58"></path>
11 <polyline id="Path-59" stroke-linejoin="round" transform="translate(12.000000, 14.000000) rotate(-270.000000) translate(-12.000000, -14.000000) " points="9 8 15 14 9 20"></polyline> 6 <polyline id="Path-59" stroke-linejoin="round" transform="translate(12.000000, 14.000000) rotate(-270.000000) translate(-12.000000, -14.000000) " points="9 8 15 14 9 20"></polyline>
diff --git a/client/src/assets/images/global/edit-black.svg b/client/src/assets/images/global/edit-black.svg
deleted file mode 100644
index 0176b0f37..000000000
--- a/client/src/assets/images/global/edit-black.svg
+++ /dev/null
@@ -1,15 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4 <title>edit</title>
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8 <g id="Artboard-4" transform="translate(-48.000000, -203.000000)" stroke="#000000" stroke-width="2">
9 <g id="41" transform="translate(48.000000, 203.000000)">
10 <path d="M3,21.0000003 L3,17 L15.8898356,4.11016442 C17.0598483,2.9401517 18.9638992,2.94723715 20.1306896,4.11402752 L19.9181432,3.90148112 C21.0902894,5.07362738 21.0882407,6.97202708 19.9174652,8.1377941 L7,21.0000003 L3,21.0000003 Z" id="Path-74" stroke-linecap="round" stroke-linejoin="round"></path>
11 <path d="M14.5,5.5 L18.5,9.5" id="Path-75"></path>
12 </g>
13 </g>
14 </g>
15</svg>
diff --git a/client/src/assets/images/global/edit-grey.svg b/client/src/assets/images/global/edit.html
index 23ece68f1..f04183c2d 100644
--- a/client/src/assets/images/global/edit-grey.svg
+++ b/client/src/assets/images/global/edit.html
@@ -1,11 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch --> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4 <title>edit</title> 3 <g transform="translate(-48.000000, -203.000000)" stroke="#000000" stroke-width="2">
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8 <g id="Artboard-4" transform="translate(-48.000000, -203.000000)" stroke="#585858" stroke-width="2">
9 <g id="41" transform="translate(48.000000, 203.000000)"> 4 <g id="41" transform="translate(48.000000, 203.000000)">
10 <path d="M3,21.0000003 L3,17 L15.8898356,4.11016442 C17.0598483,2.9401517 18.9638992,2.94723715 20.1306896,4.11402752 L19.9181432,3.90148112 C21.0902894,5.07362738 21.0882407,6.97202708 19.9174652,8.1377941 L7,21.0000003 L3,21.0000003 Z" id="Path-74" stroke-linecap="round" stroke-linejoin="round"></path> 5 <path d="M3,21.0000003 L3,17 L15.8898356,4.11016442 C17.0598483,2.9401517 18.9638992,2.94723715 20.1306896,4.11402752 L19.9181432,3.90148112 C21.0902894,5.07362738 21.0882407,6.97202708 19.9174652,8.1377941 L7,21.0000003 L3,21.0000003 Z" id="Path-74" stroke-linecap="round" stroke-linejoin="round"></path>
11 <path d="M14.5,5.5 L18.5,9.5" id="Path-75"></path> 6 <path d="M14.5,5.5 L18.5,9.5" id="Path-75"></path>
diff --git a/client/src/assets/images/global/help.svg b/client/src/assets/images/global/help.html
index 48252febe..80cd40321 100644
--- a/client/src/assets/images/global/help.svg
+++ b/client/src/assets/images/global/help.html
@@ -1,12 +1,10 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 3 <g transform="translate(-400.000000, -247.000000)">
5 <g id="Artboard-4" transform="translate(-400.000000, -247.000000)">
6 <g id="69" transform="translate(400.000000, 247.000000)"> 4 <g id="69" transform="translate(400.000000, 247.000000)">
7 <circle id="Oval-7" stroke="#333333" stroke-width="2" cx="12" cy="12" r="10"></circle> 5 <circle id="Oval-7" stroke="#000000" stroke-width="2" cx="12" cy="12" r="10"></circle>
8 <path d="M12.016,14.544 C12.384,14.544 12.64,14.256 12.704,13.904 L12.768,13.168 C14.544,12.864 16,11.952 16,9.936 L16,9.904 C16,7.904 14.48,6.656 12.24,6.656 C10.768,6.656 9.696,7.184 8.848,7.984 C8.624,8.176 8.528,8.432 8.528,8.672 C8.528,9.152 8.928,9.552 9.424,9.552 C9.648,9.552 9.856,9.456 10.016,9.328 C10.656,8.752 11.344,8.448 12.192,8.448 C13.344,8.448 14.032,9.072 14.032,9.968 L14.032,10 C14.032,11.008 13.2,11.584 11.696,11.728 C11.264,11.776 11.008,12.096 11.072,12.528 L11.232,13.904 C11.28,14.272 11.552,14.544 11.92,14.544 L12.016,14.544 Z M10.784,16.816 L10.784,16.976 C10.784,17.6 11.264,18.08 11.92,18.08 C12.576,18.08 13.056,17.6 13.056,16.976 L13.056,16.816 C13.056,16.192 12.576,15.712 11.92,15.712 C11.264,15.712 10.784,16.192 10.784,16.816 Z" id="?" fill="#333333"></path> 6 <path d="M12.016,14.544 C12.384,14.544 12.64,14.256 12.704,13.904 L12.768,13.168 C14.544,12.864 16,11.952 16,9.936 L16,9.904 C16,7.904 14.48,6.656 12.24,6.656 C10.768,6.656 9.696,7.184 8.848,7.984 C8.624,8.176 8.528,8.432 8.528,8.672 C8.528,9.152 8.928,9.552 9.424,9.552 C9.648,9.552 9.856,9.456 10.016,9.328 C10.656,8.752 11.344,8.448 12.192,8.448 C13.344,8.448 14.032,9.072 14.032,9.968 L14.032,10 C14.032,11.008 13.2,11.584 11.696,11.728 C11.264,11.776 11.008,12.096 11.072,12.528 L11.232,13.904 C11.28,14.272 11.552,14.544 11.92,14.544 L12.016,14.544 Z M10.784,16.816 L10.784,16.976 C10.784,17.6 11.264,18.08 11.92,18.08 C12.576,18.08 13.056,17.6 13.056,16.976 L13.056,16.816 C13.056,16.192 12.576,15.712 11.92,15.712 C11.264,15.712 10.784,16.192 10.784,16.816 Z" id="?" fill="#000000"></path>
9 </g> 7 </g>
10 </g> 8 </g>
11 </g> 9 </g>
12</svg> \ No newline at end of file 10</svg>
diff --git a/client/src/assets/images/global/im-with-her.svg b/client/src/assets/images/global/im-with-her.html
index 31d4754fd..de2c62e96 100644
--- a/client/src/assets/images/global/im-with-her.svg
+++ b/client/src/assets/images/global/im-with-her.html
@@ -1,15 +1,10 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch --> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4 <title>im-with-her</title> 3 <g transform="translate(-708.000000, -467.000000)">
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8 <g id="Artboard-4" transform="translate(-708.000000, -467.000000)">
9 <g id="176" transform="translate(708.000000, 467.000000)"> 4 <g id="176" transform="translate(708.000000, 467.000000)">
10 <path d="M8,9 L8,3.99339768 C8,3.44494629 7.55641359,3 7.00922203,3 L2.99077797,3 C2.45097518,3 2,3.44475929 2,3.99339768 L2,20.0066023 C2,20.5550537 2.44358641,21 2.99077797,21 L7.00922203,21 C7.54902482,21 8,20.5552407 8,20.0066023 L8,15 L14,15 L14,20.0066023 C14,20.5550537 14.4435864,21 14.990778,21 L19.009222,21 C19.5490248,21 20,20.5564587 20,20.0093228 L20,15.0006104 L23,12 L20,8.99267578 L20,4.00303919 C20,3.45042467 19.5564136,3 19.009222,3 L14.990778,3 C14.4509752,3 14,3.44475929 14,3.99339768 L14,9 L8,9 Z" id="Combined-Shape" fill="#333333" opacity="0.5"></path> 5 <path d="M8,9 L8,3.99339768 C8,3.44494629 7.55641359,3 7.00922203,3 L2.99077797,3 C2.45097518,3 2,3.44475929 2,3.99339768 L2,20.0066023 C2,20.5550537 2.44358641,21 2.99077797,21 L7.00922203,21 C7.54902482,21 8,20.5552407 8,20.0066023 L8,15 L14,15 L14,20.0066023 C14,20.5550537 14.4435864,21 14.990778,21 L19.009222,21 C19.5490248,21 20,20.5564587 20,20.0093228 L20,15.0006104 L23,12 L20,8.99267578 L20,4.00303919 C20,3.45042467 19.5564136,3 19.009222,3 L14.990778,3 C14.4509752,3 14,3.44475929 14,3.99339768 L14,9 L8,9 Z" id="Combined-Shape" fill="#000000" opacity="0.5"></path>
11 <path d="M2,9 L14,9 L14,3.99077797 C14,3.44358641 14.3203148,3.32031476 14.7062149,3.7062149 L23,12 L14.7062149,20.2937851 C14.3161832,20.6838168 14,20.5490248 14,20.009222 L14,15 L2,15 L2,9 Z" id="Rectangle-121" fill-opacity="0.5" fill="#000000"></path> 6 <path d="M2,9 L14,9 L14,3.99077797 C14,3.44358641 14.3203148,3.32031476 14.7062149,3.7062149 L23,12 L14.7062149,20.2937851 C14.3161832,20.6838168 14,20.5490248 14,20.009222 L14,15 L2,15 L2,9 Z" id="Rectangle-121" fill-opacity="0.5" fill="#000000"></path>
12 </g> 7 </g>
13 </g> 8 </g>
14 </g> 9 </g>
15</svg> \ No newline at end of file 10</svg>
diff --git a/client/src/assets/images/global/no.html b/client/src/assets/images/global/no.html
new file mode 100644
index 000000000..bb7b28514
--- /dev/null
+++ b/client/src/assets/images/global/no.html
@@ -0,0 +1,10 @@
1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
3 <g transform="translate(-312.000000, -863.000000)" stroke="#000000" stroke-width="2">
4 <g id="347" transform="translate(312.000000, 863.000000)">
5 <circle id="Oval-196" cx="12" cy="12" r="9"></circle>
6 <path d="M18,18 L6,6" id="Path-275"></path>
7 </g>
8 </g>
9 </g>
10</svg>
diff --git a/client/src/assets/images/global/sparkle.html b/client/src/assets/images/global/sparkle.html
new file mode 100644
index 000000000..3b29fefb9
--- /dev/null
+++ b/client/src/assets/images/global/sparkle.html
@@ -0,0 +1,11 @@
1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
3 <g transform="translate(-488.000000, -731.000000)" stroke="#000000" stroke-width="2">
4 <g id="291" transform="translate(488.000000, 731.000000)">
5 <path d="M10,9 C8.5,7.5 8,3 8,3 C8,3 7.5,7.5 6,9 C4.5,10.5 2,11 2,11 C2,11 4.5,11.5 6,13 C7.5,14.5 8,19 8,19 C8,19 8.5,14.5 10,13 C11.5,11.5 14,11 14,11 C14,11 11.5,10.5 10,9 Z" id="Combined-Shape"></path>
6 <path d="M19.6666667,4.75 C18.7916667,3.8125 18.5,1 18.5,1 C18.5,1 18.2083333,3.8125 17.3333333,4.75 C16.4583333,5.6875 15,6 15,6 C15,6 16.4583333,6.3125 17.3333333,7.25 C18.2083333,8.1875 18.5,11 18.5,11 C18.5,11 18.7916667,8.1875 19.6666667,7.25 C20.5416667,6.3125 22,6 22,6 C22,6 20.5416667,5.6875 19.6666667,4.75 Z" id="Combined-Shape"></path>
7 <path d="M17,17 C16.25,16.25 16,14 16,14 C16,14 15.75,16.25 15,17 C14.25,17.75 13,18 13,18 C13,18 14.25,18.25 15,19 C15.75,19.75 16,22 16,22 C16,22 16.25,19.75 17,19 C17.75,18.25 19,18 19,18 C19,18 17.75,17.75 17,17 Z" id="Combined-Shape"></path>
8 </g>
9 </g>
10 </g>
11</svg>
diff --git a/client/src/assets/images/global/syndication.svg b/client/src/assets/images/global/syndication.html
index cb74cf81b..e6c88a4db 100644
--- a/client/src/assets/images/global/syndication.svg
+++ b/client/src/assets/images/global/syndication.html
@@ -1,10 +1,8 @@
1<?xml version="1.0" encoding="iso-8859-1"?>
2<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 1<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4 viewBox="0 0 559.372 559.372" style="enable-background:new 0 0 559.372 559.372;" xml:space="preserve"> 2 viewBox="0 0 559.372 559.372" style="enable-background:new 0 0 559.372 559.372;" xml:space="preserve">
5<g> 3<g>
6 <g> 4 <g>
7 <path style="fill:#010002;" d="M53.244,0.002c46.512,0,91.29,6.018,134.334,18.054s83.334,29.07,120.869,51.102 5 <path fill="#000000" d="M53.244,0.002c46.512,0,91.29,6.018,134.334,18.054s83.334,29.07,120.869,51.102
8 c37.537,22.032,71.707,48.45,102.514,79.254c30.803,30.804,57.221,64.974,79.254,102.51 6 c37.537,22.032,71.707,48.45,102.514,79.254c30.803,30.804,57.221,64.974,79.254,102.51
9 c22.029,37.539,39.063,77.828,51.102,120.873c12.037,43.043,18.055,87.818,18.055,134.334c0,14.688-5.201,27.23-15.605,37.637 7 c22.029,37.539,39.063,77.828,51.102,120.873c12.037,43.043,18.055,87.818,18.055,134.334c0,14.688-5.201,27.23-15.605,37.637
10 c-10.404,10.407-22.949,15.604-37.637,15.604c-14.689,0-27.234-5.199-37.641-15.604c-10.402-10.404-15.604-22.949-15.604-37.637 8 c-10.404,10.407-22.949,15.604-37.637,15.604c-14.689,0-27.234-5.199-37.641-15.604c-10.402-10.404-15.604-22.949-15.604-37.637
diff --git a/client/src/assets/images/global/tick.svg b/client/src/assets/images/global/tick.html
index 230caa111..4784b4807 100644
--- a/client/src/assets/images/global/tick.svg
+++ b/client/src/assets/images/global/tick.html
@@ -1,8 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round"> 3 <g transform="translate(-356.000000, -115.000000)" stroke="#000000" stroke-width="2">
5 <g id="Artboard-4" transform="translate(-356.000000, -115.000000)" stroke="#585858" stroke-width="2">
6 <g id="8" transform="translate(356.000000, 115.000000)"> 4 <g id="8" transform="translate(356.000000, 115.000000)">
7 <path d="M21,6 L9,18" id="Path-14"></path> 5 <path d="M21,6 L9,18" id="Path-14"></path>
8 <path d="M9,13 L4,18" id="Path-14" transform="translate(6.500000, 15.500000) scale(-1, 1) translate(-6.500000, -15.500000) "></path> 6 <path d="M9,13 L4,18" id="Path-14" transform="translate(6.500000, 15.500000) scale(-1, 1) translate(-6.500000, -15.500000) "></path>
diff --git a/client/src/assets/images/global/undo.html b/client/src/assets/images/global/undo.html
new file mode 100644
index 000000000..228245c86
--- /dev/null
+++ b/client/src/assets/images/global/undo.html
@@ -0,0 +1,9 @@
1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
3 <g transform="translate(-180.000000, -115.000000)" fill="#000000">
4 <g id="4" transform="translate(180.000000, 115.000000)">
5 <path d="M10,19 C10.5522847,19 11,19.4477153 11,20 C11,20.5522847 10.5522847,21 10,21 C9.99404288,21 9.98809793,20.9999479 9.98216558,20.9998442 C5.01980239,20.990358 1,16.9646166 1,12 C1,7.02943725 5.02943725,3 10,3 C14.9705627,3 19,7.02943725 19,12 L17,12 C17,8.13400675 13.8659932,5 10,5 C6.13400675,5 3,8.13400675 3,12 C3,15.8659932 6.13400675,19 10,19 Z M14,12 L22,12 L18,16 L14,12 Z" id="Combined-Shape" transform="translate(11.500000, 12.000000) scale(-1, 1) translate(-11.500000, -12.000000) "/>
6 </g>
7 </g>
8 </g>
9</svg>
diff --git a/client/src/assets/images/global/undo.svg b/client/src/assets/images/global/undo.svg
deleted file mode 100644
index f1cca03f7..000000000
--- a/client/src/assets/images/global/undo.svg
+++ /dev/null
@@ -1,11 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs>
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
5 <g id="Artboard-4" transform="translate(-180.000000, -115.000000)" fill="#000">
6 <g id="4" transform="translate(180.000000, 115.000000)">
7 <path d="M10,19 C10.5522847,19 11,19.4477153 11,20 C11,20.5522847 10.5522847,21 10,21 C9.99404288,21 9.98809793,20.9999479 9.98216558,20.9998442 C5.01980239,20.990358 1,16.9646166 1,12 C1,7.02943725 5.02943725,3 10,3 C14.9705627,3 19,7.02943725 19,12 L17,12 C17,8.13400675 13.8659932,5 10,5 C6.13400675,5 3,8.13400675 3,12 C3,15.8659932 6.13400675,19 10,19 Z M14,12 L22,12 L18,16 L14,12 Z" id="Combined-Shape" transform="translate(11.500000, 12.000000) scale(-1, 1) translate(-11.500000, -12.000000) "></path>
8 </g>
9 </g>
10 </g>
11</svg>
diff --git a/client/src/assets/images/global/user-add.html b/client/src/assets/images/global/user-add.html
new file mode 100644
index 000000000..57df23c74
--- /dev/null
+++ b/client/src/assets/images/global/user-add.html
@@ -0,0 +1,11 @@
1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
3 <g transform="translate(-136.000000, -863.000000)">
4 <g id="343" transform="translate(136.000000, 863.000000)">
5 <path d="M14.2571621,15 L7,15 C4.20063223,15 2.390348,16.1679253 1.5255785,18.0896353 C1.07423388,19.0926234 0.949016905,20.1108713 0.995546634,20.9698816 C0.998604759,21.0263393 1.0014872,21.0632937 1.00496281,21.0995037 C1.0599172,21.6490476 1.54995985,22.0499916 2.09950372,21.9950372 C2.64904758,21.9400828 3.04999158,21.4500401 2.99503719,20.9004963 C2.99555422,20.9071205 2.99399879,20.8871791 2.99261905,20.8617069 C2.96185588,20.2937714 3.05021139,19.575276 3.34942151,18.9103647 C3.890902,17.7070747 4.98686778,17 7,17 L12.0070975,17 L13.2070325,17 C13.4170071,16.2576107 13.7789623,15.5790321 14.2571621,15 Z" id="Path-41" fill="#000000" fill-rule="nonzero"></path>
6 <path d="M19,18 L19,16.4976988 C19,16.2228273 18.7680664,16 18.5,16 C18.2238576,16 18,16.2148438 18,16.4976988 L18,18 L16.4976988,18 C16.2148438,18 16,18.2238576 16,18.5 C16,18.7680664 16.2228273,19 16.4976988,19 L18,19 L18,20.5023012 C18,20.7771727 18.2319336,21 18.5,21 C18.7761424,21 19,20.7851562 19,20.5023012 L19,19 L20.5023012,19 C20.7851562,19 21,18.7761424 21,18.5 C21,18.2319336 20.7771727,18 20.5023012,18 L19,18 Z M18.5,23 C16.0147186,23 14,20.9852814 14,18.5 C14,16.0147186 16.0147186,14 18.5,14 C20.9852814,14 23,16.0147186 23,18.5 C23,20.9852814 20.9852814,23 18.5,23 Z" id="Combined-Shape" fill="#000000"></path>
7 <circle id="Oval-40" stroke="#000000" stroke-width="2" cx="12" cy="8" r="5"></circle>
8 </g>
9 </g>
10 </g>
11</svg>
diff --git a/client/src/assets/images/global/validate.svg b/client/src/assets/images/global/validate.html
index 5c7ee9d14..520624ff6 100644
--- a/client/src/assets/images/global/validate.svg
+++ b/client/src/assets/images/global/validate.html
@@ -1,8 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 3 <g transform="translate(-400.000000, -1134.000000)" stroke="#000000" stroke-width="2">
5 <g id="Artboard-4" transform="translate(-400.000000, -1134.000000)" stroke="#ffffff" stroke-width="2">
6 <g id="Extras" transform="translate(48.000000, 1046.000000)"> 4 <g id="Extras" transform="translate(48.000000, 1046.000000)">
7 <g id="yes" transform="translate(352.000000, 88.000000)"> 5 <g id="yes" transform="translate(352.000000, 88.000000)">
8 <circle id="Oval-1" cx="12" cy="12" r="10"></circle> 6 <circle id="Oval-1" cx="12" cy="12" r="10"></circle>
diff --git a/client/src/assets/images/video/blacklist.svg b/client/src/assets/images/video/blacklist.svg
deleted file mode 100644
index 431c73816..000000000
--- a/client/src/assets/images/video/blacklist.svg
+++ /dev/null
@@ -1,15 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4 <title>no</title>
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8 <g id="Artboard-4" transform="translate(-312.000000, -863.000000)" stroke="#000000" stroke-width="2">
9 <g id="347" transform="translate(312.000000, 863.000000)">
10 <circle id="Oval-196" cx="12" cy="12" r="9"></circle>
11 <path d="M18,18 L6,6" id="Path-275"></path>
12 </g>
13 </g>
14 </g>
15</svg>
diff --git a/client/src/assets/images/video/dislike-white.svg b/client/src/assets/images/video/dislike-white.svg
deleted file mode 100644
index cfc6eaa1f..000000000
--- a/client/src/assets/images/video/dislike-white.svg
+++ /dev/null
@@ -1,14 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs>
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
5 <g id="Artboard-4" transform="translate(-752.000000, -1090.000000)" stroke="#ffffff" stroke-width="2">
6 <g id="Extras" transform="translate(48.000000, 1046.000000)">
7 <g id="thumbs-down" transform="translate(704.000000, 44.000000)">
8 <path d="M6,16 C6,18.5 6.5,21 8,21 L16.9938335,21 C17.5495239,21 18.1819788,20.5956028 18.4072817,20.0949295 L20.8562951,14.6526776 C21.7640882,12.6353595 20.7154925,11 18.5092545,11 L15.5,11 C15.5,11 18.5,5 15,5 C12.5,5 11.5,11 8,11 C6.5,11 6,13.5 6,16 Z" id="Path-188" stroke-linejoin="round" transform="translate(13.591488, 13.000000) scale(1, -1) translate(-13.591488, -13.000000) "></path>
9 <path d="M4,4.5 C4,4.5 3,7 3,10 C3,13 4,15.5 4,15.5" id="Path-189" transform="translate(3.500000, 10.000000) scale(1, -1) translate(-3.500000, -10.000000) "></path>
10 </g>
11 </g>
12 </g>
13 </g>
14</svg>
diff --git a/client/src/assets/images/video/dislike-grey.svg b/client/src/assets/images/video/dislike.html
index 56a7908fb..acde951e2 100644
--- a/client/src/assets/images/video/dislike-grey.svg
+++ b/client/src/assets/images/video/dislike.html
@@ -1,8 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round"> 3 <g transform="translate(-752.000000, -1090.000000)" stroke="#000000" stroke-width="2">
5 <g id="Artboard-4" transform="translate(-752.000000, -1090.000000)" stroke="#585858" stroke-width="2">
6 <g id="Extras" transform="translate(48.000000, 1046.000000)"> 4 <g id="Extras" transform="translate(48.000000, 1046.000000)">
7 <g id="thumbs-down" transform="translate(704.000000, 44.000000)"> 5 <g id="thumbs-down" transform="translate(704.000000, 44.000000)">
8 <path d="M6,16 C6,18.5 6.5,21 8,21 L16.9938335,21 C17.5495239,21 18.1819788,20.5956028 18.4072817,20.0949295 L20.8562951,14.6526776 C21.7640882,12.6353595 20.7154925,11 18.5092545,11 L15.5,11 C15.5,11 18.5,5 15,5 C12.5,5 11.5,11 8,11 C6.5,11 6,13.5 6,16 Z" id="Path-188" stroke-linejoin="round" transform="translate(13.591488, 13.000000) scale(1, -1) translate(-13.591488, -13.000000) "></path> 6 <path d="M6,16 C6,18.5 6.5,21 8,21 L16.9938335,21 C17.5495239,21 18.1819788,20.5956028 18.4072817,20.0949295 L20.8562951,14.6526776 C21.7640882,12.6353595 20.7154925,11 18.5092545,11 L15.5,11 C15.5,11 18.5,5 15,5 C12.5,5 11.5,11 8,11 C6.5,11 6,13.5 6,16 Z" id="Path-188" stroke-linejoin="round" transform="translate(13.591488, 13.000000) scale(1, -1) translate(-13.591488, -13.000000) "></path>
diff --git a/client/src/assets/images/video/download-grey.svg b/client/src/assets/images/video/download-grey.svg
deleted file mode 100644
index 5b0cca5ef..000000000
--- a/client/src/assets/images/video/download-grey.svg
+++ /dev/null
@@ -1,16 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4 <title>download</title>
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
8 <g id="Artboard-4" transform="translate(-180.000000, -291.000000)" stroke="#585858" stroke-width="2">
9 <g id="84" transform="translate(180.000000, 291.000000)">
10 <path d="M12,3 L12,15" id="Path-58"></path>
11 <polyline id="Path-59" stroke-linejoin="round" transform="translate(12.000000, 14.000000) rotate(-270.000000) translate(-12.000000, -14.000000) " points="9 8 15 14 9 20"></polyline>
12 <path d="M3,18 L3,20.0590859 C3,20.6127331 3.44494889,21.0615528 3.99340349,21.0615528 L20.0067018,21.0615528 C20.5553434,21.0615528 21.0001052,20.6098102 21.0001051,20.0590859 L21.0001049,18" id="Path-12" stroke-linejoin="round"></path>
13 </g>
14 </g>
15 </g>
16</svg>
diff --git a/client/src/assets/images/video/download-white.svg b/client/src/assets/images/video/download-white.svg
deleted file mode 100644
index 0e66e06e8..000000000
--- a/client/src/assets/images/video/download-white.svg
+++ /dev/null
@@ -1,16 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4 <title>download</title>
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
8 <g id="Artboard-4" transform="translate(-180.000000, -291.000000)" stroke="#ffffff" stroke-width="2">
9 <g id="84" transform="translate(180.000000, 291.000000)">
10 <path d="M12,3 L12,15" id="Path-58"></path>
11 <polyline id="Path-59" stroke-linejoin="round" transform="translate(12.000000, 14.000000) rotate(-270.000000) translate(-12.000000, -14.000000) " points="9 8 15 14 9 20"></polyline>
12 <path d="M3,18 L3,20.0590859 C3,20.6127331 3.44494889,21.0615528 3.99340349,21.0615528 L20.0067018,21.0615528 C20.5553434,21.0615528 21.0001052,20.6098102 21.0001051,20.0590859 L21.0001049,18" id="Path-12" stroke-linejoin="round"></path>
13 </g>
14 </g>
15 </g>
16</svg>
diff --git a/client/src/assets/images/video/heart.svg b/client/src/assets/images/video/heart.html
index 5d64aee0f..618f64f10 100644
--- a/client/src/assets/images/video/heart.svg
+++ b/client/src/assets/images/video/heart.html
@@ -1,9 +1,7 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 3 <g transform="translate(-48.000000, -1046.000000)" fill-rule="nonzero" fill="#000000">
5 <g id="Artboard-4" transform="translate(-48.000000, -1046.000000)" fill-rule="nonzero" fill="#585858"> 4 <g transform="translate(48.000000, 1046.000000)">
6 <g id="Extras" transform="translate(48.000000, 1046.000000)">
7 <g id="heart"> 5 <g id="heart">
8 <path d="M12.0174466,21 L20.9041801,11.3556763 C22.6291961,9.13778099 22.2795957,5.90145416 20.1233257,4.12713796 C17.9670557,2.35282175 14.8206518,2.71241362 13.0956358,4.93030888 L12.0174465,6.5 L10.9043642,4.93030888 C9.17934824,2.71241362 6.0329443,2.35282175 3.87667432,4.12713796 C1.72040435,5.90145416 1.37080391,9.13778099 3.09581989,11.3556763 L12.0174466,21 Z"></path> 6 <path d="M12.0174466,21 L20.9041801,11.3556763 C22.6291961,9.13778099 22.2795957,5.90145416 20.1233257,4.12713796 C17.9670557,2.35282175 14.8206518,2.71241362 13.0956358,4.93030888 L12.0174465,6.5 L10.9043642,4.93030888 C9.17934824,2.71241362 6.0329443,2.35282175 3.87667432,4.12713796 C1.72040435,5.90145416 1.37080391,9.13778099 3.09581989,11.3556763 L12.0174466,21 Z"></path>
9 </g> 7 </g>
diff --git a/client/src/assets/images/video/like-white.svg b/client/src/assets/images/video/like-white.svg
deleted file mode 100644
index 88e5f6a9a..000000000
--- a/client/src/assets/images/video/like-white.svg
+++ /dev/null
@@ -1,15 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4 <title>thumbs-up</title>
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
8 <g id="Artboard-4" transform="translate(-708.000000, -643.000000)" stroke="#ffffff" stroke-width="2">
9 <g id="256" transform="translate(708.000000, 643.000000)">
10 <path d="M6,14 C6,16.5 6.5,19 8,19 L16.9938335,19 C17.5495239,19 18.1819788,18.5956028 18.4072817,18.0949295 L20.8562951,12.6526776 C21.7640882,10.6353595 20.7154925,9 18.5092545,9 L15.5,9 C15.5,9 18.5,3 15,3 C12.5,3 11.5,9 8,9 C6.5,9 6,11.5 6,14 Z" id="Path-188" stroke-linejoin="round"></path>
11 <path d="M4,8.5 C4,8.5 3,11 3,14 C3,17 4,19.5 4,19.5" id="Path-189"></path>
12 </g>
13 </g>
14 </g>
15</svg>
diff --git a/client/src/assets/images/video/like-grey.svg b/client/src/assets/images/video/like.html
index 5ef6c7b31..d0e71763b 100644
--- a/client/src/assets/images/video/like-grey.svg
+++ b/client/src/assets/images/video/like.html
@@ -1,11 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch --> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
4 <title>thumbs-up</title> 3 <g transform="translate(-708.000000, -643.000000)" stroke="#000000" stroke-width="2">
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
8 <g id="Artboard-4" transform="translate(-708.000000, -643.000000)" stroke="#585858" stroke-width="2">
9 <g id="256" transform="translate(708.000000, 643.000000)"> 4 <g id="256" transform="translate(708.000000, 643.000000)">
10 <path d="M6,14 C6,16.5 6.5,19 8,19 L16.9938335,19 C17.5495239,19 18.1819788,18.5956028 18.4072817,18.0949295 L20.8562951,12.6526776 C21.7640882,10.6353595 20.7154925,9 18.5092545,9 L15.5,9 C15.5,9 18.5,3 15,3 C12.5,3 11.5,9 8,9 C6.5,9 6,11.5 6,14 Z" id="Path-188" stroke-linejoin="round"></path> 5 <path d="M6,14 C6,16.5 6.5,19 8,19 L16.9938335,19 C17.5495239,19 18.1819788,18.5956028 18.4072817,18.0949295 L20.8562951,12.6526776 C21.7640882,10.6353595 20.7154925,9 18.5092545,9 L15.5,9 C15.5,9 18.5,3 15,3 C12.5,3 11.5,9 8,9 C6.5,9 6,11.5 6,14 Z" id="Path-188" stroke-linejoin="round"></path>
11 <path d="M4,8.5 C4,8.5 3,11 3,14 C3,17 4,19.5 4,19.5" id="Path-189"></path> 6 <path d="M4,8.5 C4,8.5 3,11 3,14 C3,17 4,19.5 4,19.5" id="Path-189"></path>
diff --git a/client/src/assets/images/video/more.svg b/client/src/assets/images/video/more.html
index dea392136..39dcad10e 100644
--- a/client/src/assets/images/video/more.svg
+++ b/client/src/assets/images/video/more.html
@@ -1,8 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <defs></defs> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
4 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 3 <g transform="translate(-444.000000, -115.000000)" fill="#000000">
5 <g id="Artboard-4" transform="translate(-444.000000, -115.000000)" fill="#585858">
6 <g id="10" transform="translate(444.000000, 115.000000)"> 4 <g id="10" transform="translate(444.000000, 115.000000)">
7 <path d="M10,12 C10,10.8954305 10.8877296,10 12,10 C13.1045695,10 14,10.8877296 14,12 C14,13.1045695 13.1122704,14 12,14 C10.8954305,14 10,13.1122704 10,12 Z M17,12 C17,10.8954305 17.8877296,10 19,10 C20.1045695,10 21,10.8877296 21,12 C21,13.1045695 20.1122704,14 19,14 C17.8954305,14 17,13.1122704 17,12 Z M3,12 C3,10.8954305 3.88772964,10 5,10 C6.1045695,10 7,10.8877296 7,12 C7,13.1045695 6.11227036,14 5,14 C3.8954305,14 3,13.1122704 3,12 Z" id="Combined-Shape"></path> 5 <path d="M10,12 C10,10.8954305 10.8877296,10 12,10 C13.1045695,10 14,10.8877296 14,12 C14,13.1045695 13.1122704,14 12,14 C10.8954305,14 10,13.1122704 10,12 Z M17,12 C17,10.8954305 17.8877296,10 19,10 C20.1045695,10 21,10.8877296 21,12 C21,13.1045695 20.1122704,14 19,14 C17.8954305,14 17,13.1122704 17,12 Z M3,12 C3,10.8954305 3.88772964,10 5,10 C6.1045695,10 7,10.8877296 7,12 C7,13.1045695 6.11227036,14 5,14 C3.8954305,14 3,13.1122704 3,12 Z" id="Combined-Shape"></path>
8 </g> 6 </g>
diff --git a/client/src/assets/images/video/share.svg b/client/src/assets/images/video/share.html
index da0f43e81..7759b37af 100644
--- a/client/src/assets/images/video/share.svg
+++ b/client/src/assets/images/video/share.html
@@ -1,11 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch --> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
4 <title>share</title> 3 <g transform="translate(-312.000000, -203.000000)" stroke="#000000" stroke-width="2">
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
8 <g id="Artboard-4" transform="translate(-312.000000, -203.000000)" stroke="#585858" stroke-width="2">
9 <g id="47" transform="translate(312.000000, 203.000000)"> 4 <g id="47" transform="translate(312.000000, 203.000000)">
10 <path d="M20,15 L20,18.0026083 C20,19.1057373 19.1073772,20 18.0049107,20 L5.99508929,20 C4.8932319,20 4,19.1073772 4,18.0049107 L4,5.99508929 C4,4.8932319 4.89585781,4 5.9973917,4 L9,4" id="Rectangle-460"></path> 5 <path d="M20,15 L20,18.0026083 C20,19.1057373 19.1073772,20 18.0049107,20 L5.99508929,20 C4.8932319,20 4,19.1073772 4,18.0049107 L4,5.99508929 C4,4.8932319 4.89585781,4 5.9973917,4 L9,4" id="Rectangle-460"></path>
11 <polyline id="Path-93" stroke-linejoin="round" points="13 4 20.0207973 4 20.0207973 11.0191059"></polyline> 6 <polyline id="Path-93" stroke-linejoin="round" points="13 4 20.0207973 4 20.0207973 11.0191059"></polyline>
diff --git a/client/src/assets/images/header/upload-white.svg b/client/src/assets/images/video/upload.html
index 2b07caf76..3bc0d3a8a 100644
--- a/client/src/assets/images/header/upload-white.svg
+++ b/client/src/assets/images/video/upload.html
@@ -1,11 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 1<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch --> 2 <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
4 <title>cloud-upload</title> 3 <g transform="translate(-312.000000, -775.000000)" stroke="#000000" stroke-width="2">
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
8 <g id="Artboard-4" transform="translate(-312.000000, -775.000000)" stroke="#fff" stroke-width="2">
9 <g id="307" transform="translate(312.000000, 775.000000)"> 4 <g id="307" transform="translate(312.000000, 775.000000)">
10 <path d="M8,18 L5,18 L5,18 C2.790861,18 1,16.209139 1,14 C1,11.790861 2.790861,10 5,10 C5.35840468,10 5.70579988,10.0471371 6.03632437,10.1355501 C6.01233106,9.92702603 6,9.71495305 6,9.5 C6,6.46243388 8.46243388,4 11.5,4 C14.0673313,4 16.2238156,5.7590449 16.8299648,8.1376465 C17.2052921,8.04765874 17.5970804,8 18,8 C20.7614237,8 23,10.2385763 23,13 C23,15.7614237 20.7614237,18 18,18 L16,18" id="Combined-Shape" stroke-linejoin="round"></path> 5 <path d="M8,18 L5,18 L5,18 C2.790861,18 1,16.209139 1,14 C1,11.790861 2.790861,10 5,10 C5.35840468,10 5.70579988,10.0471371 6.03632437,10.1355501 C6.01233106,9.92702603 6,9.71495305 6,9.5 C6,6.46243388 8.46243388,4 11.5,4 C14.0673313,4 16.2238156,5.7590449 16.8299648,8.1376465 C17.2052921,8.04765874 17.5970804,8 18,8 C20.7614237,8 23,10.2385763 23,13 C23,15.7614237 20.7614237,18 18,18 L16,18" id="Combined-Shape" stroke-linejoin="round"></path>
11 <path d="M12,13 L12,21" id="Path-58"></path> 6 <path d="M12,13 L12,21" id="Path-58"></path>
diff --git a/client/src/assets/images/video/upload.svg b/client/src/assets/images/video/upload.svg
deleted file mode 100644
index c5b7cb443..000000000
--- a/client/src/assets/images/video/upload.svg
+++ /dev/null
@@ -1,16 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3 <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4 <title>cloud-upload</title>
5 <desc>Created with Sketch.</desc>
6 <defs></defs>
7 <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
8 <g id="Artboard-4" transform="translate(-312.000000, -775.000000)" stroke="#C6C6C6" stroke-width="2">
9 <g id="307" transform="translate(312.000000, 775.000000)">
10 <path d="M8,18 L5,18 L5,18 C2.790861,18 1,16.209139 1,14 C1,11.790861 2.790861,10 5,10 C5.35840468,10 5.70579988,10.0471371 6.03632437,10.1355501 C6.01233106,9.92702603 6,9.71495305 6,9.5 C6,6.46243388 8.46243388,4 11.5,4 C14.0673313,4 16.2238156,5.7590449 16.8299648,8.1376465 C17.2052921,8.04765874 17.5970804,8 18,8 C20.7614237,8 23,10.2385763 23,13 C23,15.7614237 20.7614237,18 18,18 L16,18" id="Combined-Shape" stroke-linejoin="round"></path>
11 <path d="M12,13 L12,21" id="Path-58"></path>
12 <polyline id="Path-59" stroke-linejoin="round" transform="translate(12.000000, 12.500000) scale(1, -1) translate(-12.000000, -12.500000) " points="15 11 12 14 9 11"></polyline>
13 </g>
14 </g>
15 </g>
16</svg>
diff --git a/client/src/assets/player/peertube-player-local-storage.ts b/client/src/assets/player/peertube-player-local-storage.ts
index 7e3813570..059fca308 100644
--- a/client/src/assets/player/peertube-player-local-storage.ts
+++ b/client/src/assets/player/peertube-player-local-storage.ts
@@ -60,6 +60,14 @@ function getAverageBandwidthInStore () {
60 return undefined 60 return undefined
61} 61}
62 62
63function saveLastSubtitle (language: string) {
64 return setLocalStorage('last-subtitle', language)
65}
66
67function getStoredLastSubtitle () {
68 return getLocalStorage('last-subtitle')
69}
70
63// --------------------------------------------------------------------------- 71// ---------------------------------------------------------------------------
64 72
65export { 73export {
@@ -71,7 +79,9 @@ export {
71 saveMuteInStore, 79 saveMuteInStore,
72 saveTheaterInStore, 80 saveTheaterInStore,
73 saveAverageBandwidth, 81 saveAverageBandwidth,
74 getAverageBandwidthInStore 82 getAverageBandwidthInStore,
83 saveLastSubtitle,
84 getStoredLastSubtitle
75} 85}
76 86
77// --------------------------------------------------------------------------- 87// ---------------------------------------------------------------------------
diff --git a/client/src/assets/player/peertube-player.ts b/client/src/assets/player/peertube-player.ts
index aaa1170b6..2de6d7fef 100644
--- a/client/src/assets/player/peertube-player.ts
+++ b/client/src/assets/player/peertube-player.ts
@@ -26,23 +26,24 @@ videojsUntyped.getComponent('CaptionsButton').prototype.controlText_ = 'Subtitle
26videojsUntyped.getComponent('CaptionsButton').prototype.label_ = ' ' 26videojsUntyped.getComponent('CaptionsButton').prototype.label_ = ' '
27 27
28function getVideojsOptions (options: { 28function getVideojsOptions (options: {
29 autoplay: boolean, 29 autoplay: boolean
30 playerElement: HTMLVideoElement, 30 playerElement: HTMLVideoElement
31 videoViewUrl: string, 31 videoViewUrl: string
32 videoDuration: number, 32 videoDuration: number
33 videoFiles: VideoFile[], 33 videoFiles: VideoFile[]
34 enableHotkeys: boolean, 34 enableHotkeys: boolean
35 inactivityTimeout: number, 35 inactivityTimeout: number
36 peertubeLink: boolean, 36 peertubeLink: boolean
37 poster: string, 37 poster: string
38 startTime: number | string 38 startTime: number | string
39 theaterMode: boolean, 39 theaterMode: boolean
40 videoCaptions: VideoJSCaption[], 40 videoCaptions: VideoJSCaption[]
41 41
42 language?: string, 42 language?: string
43 controls?: boolean, 43 controls?: boolean
44 muted?: boolean, 44 muted?: boolean
45 loop?: boolean 45 loop?: boolean
46 subtitle?: string
46 47
47 userWatching?: UserWatching 48 userWatching?: UserWatching
48}) { 49}) {
@@ -50,8 +51,10 @@ function getVideojsOptions (options: {
50 // We don't use text track settings for now 51 // We don't use text track settings for now
51 textTrackSettings: false, 52 textTrackSettings: false,
52 controls: options.controls !== undefined ? options.controls : true, 53 controls: options.controls !== undefined ? options.controls : true,
53 muted: options.controls !== undefined ? options.muted : false,
54 loop: options.loop !== undefined ? options.loop : false, 54 loop: options.loop !== undefined ? options.loop : false,
55
56 muted: options.muted !== undefined ? options.muted : undefined, // Undefined so the player knows it has to check the local storage
57
55 poster: options.poster, 58 poster: options.poster,
56 autoplay: false, 59 autoplay: false,
57 inactivityTimeout: options.inactivityTimeout, 60 inactivityTimeout: options.inactivityTimeout,
@@ -65,7 +68,8 @@ function getVideojsOptions (options: {
65 videoViewUrl: options.videoViewUrl, 68 videoViewUrl: options.videoViewUrl,
66 videoDuration: options.videoDuration, 69 videoDuration: options.videoDuration,
67 startTime: options.startTime, 70 startTime: options.startTime,
68 userWatching: options.userWatching 71 userWatching: options.userWatching,
72 subtitle: options.subtitle
69 } 73 }
70 }, 74 },
71 controlBar: { 75 controlBar: {
@@ -250,6 +254,10 @@ function loadLocaleInVideoJS (serverUrl: string, videojs: any, locale: string) {
250 loadLocaleInVideoJS.cache[path] = json 254 loadLocaleInVideoJS.cache[path] = json
251 return json 255 return json
252 }) 256 })
257 .catch(err => {
258 console.error('Cannot get player translations', err)
259 return undefined
260 })
253 } 261 }
254 262
255 const completeLocale = getCompleteLocale(locale) 263 const completeLocale = getCompleteLocale(locale)
@@ -266,6 +274,10 @@ function getServerTranslations (serverUrl: string, locale: string) {
266 274
267 return fetch(path + '/server.json') 275 return fetch(path + '/server.json')
268 .then(res => res.json()) 276 .then(res => res.json())
277 .catch(err => {
278 console.error('Cannot get server translations', err)
279 return undefined
280 })
269} 281}
270 282
271// ############################################################################ 283// ############################################################################
diff --git a/client/src/assets/player/peertube-videojs-plugin.ts b/client/src/assets/player/peertube-videojs-plugin.ts
index 4fd5a9be2..e9fb90c61 100644
--- a/client/src/assets/player/peertube-videojs-plugin.ts
+++ b/client/src/assets/player/peertube-videojs-plugin.ts
@@ -11,10 +11,12 @@ import { isMobile, timeToInt, videoFileMaxByResolution, videoFileMinByResolution
11import { PeertubeChunkStore } from './peertube-chunk-store' 11import { PeertubeChunkStore } from './peertube-chunk-store'
12import { 12import {
13 getAverageBandwidthInStore, 13 getAverageBandwidthInStore,
14 getStoredLastSubtitle,
14 getStoredMute, 15 getStoredMute,
15 getStoredVolume, 16 getStoredVolume,
16 getStoredWebTorrentEnabled, 17 getStoredWebTorrentEnabled,
17 saveAverageBandwidth, 18 saveAverageBandwidth,
19 saveLastSubtitle,
18 saveMuteInStore, 20 saveMuteInStore,
19 saveVolumeInStore 21 saveVolumeInStore
20} from './peertube-player-local-storage' 22} from './peertube-player-local-storage'
@@ -67,10 +69,11 @@ class PeerTubePlugin extends Plugin {
67 private currentVideoFile: VideoFile 69 private currentVideoFile: VideoFile
68 private torrent: WebTorrent.Torrent 70 private torrent: WebTorrent.Torrent
69 private videoCaptions: VideoJSCaption[] 71 private videoCaptions: VideoJSCaption[]
72 private defaultSubtitle: string
70 73
71 private renderer: any 74 private renderer: any
72 private fakeRenderer: any 75 private fakeRenderer: any
73 private destoyingFakeRenderer = false 76 private destroyingFakeRenderer = false
74 77
75 private autoResolution = true 78 private autoResolution = true
76 private forbidAutoResolution = false 79 private forbidAutoResolution = false
@@ -106,11 +109,34 @@ class PeerTubePlugin extends Plugin {
106 if (this.autoplay === true) this.player.addClass('vjs-has-autoplay') 109 if (this.autoplay === true) this.player.addClass('vjs-has-autoplay')
107 110
108 this.player.ready(() => { 111 this.player.ready(() => {
112 const playerOptions = this.player.options_
113
109 const volume = getStoredVolume() 114 const volume = getStoredVolume()
110 if (volume !== undefined) this.player.volume(volume) 115 if (volume !== undefined) this.player.volume(volume)
111 const muted = getStoredMute() 116
117 const muted = playerOptions.muted !== undefined ? playerOptions.muted : getStoredMute()
112 if (muted !== undefined) this.player.muted(muted) 118 if (muted !== undefined) this.player.muted(muted)
113 119
120 this.defaultSubtitle = options.subtitle || getStoredLastSubtitle()
121
122 this.player.on('volumechange', () => {
123 saveVolumeInStore(this.player.volume())
124 saveMuteInStore(this.player.muted())
125 })
126
127 this.player.textTracks().on('change', () => {
128 const showing = this.player.textTracks().tracks_.find((t: { kind: string, mode: string }) => {
129 return t.kind === 'captions' && t.mode === 'showing'
130 })
131
132 if (!showing) {
133 saveLastSubtitle('off')
134 return
135 }
136
137 saveLastSubtitle(showing.language)
138 })
139
114 this.player.duration(options.videoDuration) 140 this.player.duration(options.videoDuration)
115 141
116 this.initializePlayer() 142 this.initializePlayer()
@@ -124,11 +150,6 @@ class PeerTubePlugin extends Plugin {
124 this.runAutoQualitySchedulerTimer = setTimeout(() => this.runAutoQualityScheduler(), this.CONSTANTS.AUTO_QUALITY_SCHEDULER) 150 this.runAutoQualitySchedulerTimer = setTimeout(() => this.runAutoQualityScheduler(), this.CONSTANTS.AUTO_QUALITY_SCHEDULER)
125 }) 151 })
126 }) 152 })
127
128 this.player.on('volumechange', () => {
129 saveVolumeInStore(this.player.volume())
130 saveMuteInStore(this.player.muted())
131 })
132 } 153 }
133 154
134 dispose () { 155 dispose () {
@@ -599,6 +620,9 @@ class PeerTubePlugin extends Plugin {
599 this.player.src = this.savePlayerSrcFunction 620 this.player.src = this.savePlayerSrcFunction
600 this.player.src(httpUrl) 621 this.player.src(httpUrl)
601 622
623 // We changed the source, so reinit captions
624 this.initCaptions()
625
602 return this.tryToPlay(err => { 626 return this.tryToPlay(err => {
603 if (err && done) return done(err) 627 if (err && done) return done(err)
604 628
@@ -657,14 +681,14 @@ class PeerTubePlugin extends Plugin {
657 } 681 }
658 682
659 private renderFileInFakeElement (file: WebTorrent.TorrentFile, delay: number) { 683 private renderFileInFakeElement (file: WebTorrent.TorrentFile, delay: number) {
660 this.destoyingFakeRenderer = false 684 this.destroyingFakeRenderer = false
661 685
662 const fakeVideoElem = document.createElement('video') 686 const fakeVideoElem = document.createElement('video')
663 renderVideo(file, fakeVideoElem, { autoplay: false, controls: false }, (err, renderer) => { 687 renderVideo(file, fakeVideoElem, { autoplay: false, controls: false }, (err, renderer) => {
664 this.fakeRenderer = renderer 688 this.fakeRenderer = renderer
665 689
666 // The renderer returns an error when we destroy it, so skip them 690 // The renderer returns an error when we destroy it, so skip them
667 if (this.destoyingFakeRenderer === false && err) { 691 if (this.destroyingFakeRenderer === false && err) {
668 console.error('Cannot render new torrent in fake video element.', err) 692 console.error('Cannot render new torrent in fake video element.', err)
669 } 693 }
670 694
@@ -675,7 +699,7 @@ class PeerTubePlugin extends Plugin {
675 699
676 private destroyFakeRenderer () { 700 private destroyFakeRenderer () {
677 if (this.fakeRenderer) { 701 if (this.fakeRenderer) {
678 this.destoyingFakeRenderer = true 702 this.destroyingFakeRenderer = true
679 703
680 if (this.fakeRenderer.destroy) { 704 if (this.fakeRenderer.destroy) {
681 try { 705 try {
@@ -695,9 +719,12 @@ class PeerTubePlugin extends Plugin {
695 label: caption.label, 719 label: caption.label,
696 language: caption.language, 720 language: caption.language,
697 id: caption.language, 721 id: caption.language,
698 src: caption.src 722 src: caption.src,
723 default: this.defaultSubtitle === caption.language
699 }, false) 724 }, false)
700 } 725 }
726
727 this.player.trigger('captionsChanged')
701 } 728 }
702 729
703 // Thanks: https://github.com/videojs/video.js/issues/4460#issuecomment-312861657 730 // Thanks: https://github.com/videojs/video.js/issues/4460#issuecomment-312861657
diff --git a/client/src/assets/player/peertube-videojs-typings.ts b/client/src/assets/player/peertube-videojs-typings.ts
index d127230fa..634c7fdc9 100644
--- a/client/src/assets/player/peertube-videojs-typings.ts
+++ b/client/src/assets/player/peertube-videojs-typings.ts
@@ -39,6 +39,7 @@ type PeertubePluginOptions = {
39 autoplay: boolean, 39 autoplay: boolean,
40 videoCaptions: VideoJSCaption[] 40 videoCaptions: VideoJSCaption[]
41 41
42 subtitle?: string
42 userWatching?: UserWatching 43 userWatching?: UserWatching
43} 44}
44 45
diff --git a/client/src/assets/player/settings-menu-item.ts b/client/src/assets/player/settings-menu-item.ts
index 698f4627a..2a3460ae5 100644
--- a/client/src/assets/player/settings-menu-item.ts
+++ b/client/src/assets/player/settings-menu-item.ts
@@ -48,6 +48,19 @@ class SettingsMenuItem extends MenuItem {
48 // Update on rate change 48 // Update on rate change
49 player.on('ratechange', this.submenuClickHandler) 49 player.on('ratechange', this.submenuClickHandler)
50 50
51 if (subMenuName === 'CaptionsButton') {
52 // Hack to regenerate captions on HTTP fallback
53 player.on('captionsChanged', () => {
54 setTimeout(() => {
55 this.settingsSubMenuEl_.innerHTML = ''
56 this.settingsSubMenuEl_.appendChild(this.subMenu.menu.el_)
57 this.update()
58 this.bindClickEvents()
59
60 }, 0)
61 })
62 }
63
51 this.reset() 64 this.reset()
52 }, 0) 65 }, 0)
53 }) 66 })
diff --git a/client/src/assets/player/utils.ts b/client/src/assets/player/utils.ts
index c87287482..8b9f34b99 100644
--- a/client/src/assets/player/utils.ts
+++ b/client/src/assets/player/utils.ts
@@ -39,6 +39,7 @@ function buildVideoLink (time?: number, url?: string) {
39} 39}
40 40
41function timeToInt (time: number | string) { 41function timeToInt (time: number | string) {
42 if (!time) return 0
42 if (typeof time === 'number') return time 43 if (typeof time === 'number') return time
43 44
44 const reg = /^((\d+)h)?((\d+)m)?((\d+)s?)?$/ 45 const reg = /^((\d+)h)?((\d+)m)?((\d+)s?)?$/
diff --git a/client/src/environments/environment.ts b/client/src/environments/environment.ts
index 5bb6f4b34..1ea483554 100644
--- a/client/src/environments/environment.ts
+++ b/client/src/environments/environment.ts
@@ -2,6 +2,13 @@
2// `ng build --env=prod` then `environment.prod.ts` will be used instead. 2// `ng build --env=prod` then `environment.prod.ts` will be used instead.
3// The list of which env maps to which file can be found in `.angular-cli.json`. 3// The list of which env maps to which file can be found in `.angular-cli.json`.
4 4
5// Reflect.metadata polyfill is only needed in the JIT/dev mode.
6//
7// In order to load these polyfills early enough (before app code), polyfill.ts imports this file to
8// to change the order in the final bundle.
9import 'core-js/es6/reflect'
10import 'core-js/es7/reflect'
11
5export const environment = { 12export const environment = {
6 production: false, 13 production: false,
7 hmr: false, 14 hmr: false,
diff --git a/client/src/locale/source/angular_en_US.xml b/client/src/locale/source/angular_en_US.xml
index 7ebdd8e07..3aa178825 100644
--- a/client/src/locale/source/angular_en_US.xml
+++ b/client/src/locale/source/angular_en_US.xml
@@ -210,7 +210,7 @@
210 </context-group> 210 </context-group>
211 <context-group purpose="location"> 211 <context-group purpose="location">
212 <context context-type="sourcefile">app/login/login.component.html</context> 212 <context context-type="sourcefile">app/login/login.component.html</context>
213 <context context-type="linenumber">72</context> 213 <context context-type="linenumber">77</context>
214 </context-group> 214 </context-group>
215 <context-group purpose="location"> 215 <context-group purpose="location">
216 <context context-type="sourcefile">app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.html</context> 216 <context context-type="sourcefile">app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.html</context>
@@ -226,6 +226,113 @@
226 <context context-type="sourcefile">app/shared/forms/reactive-file.component.html</context> 226 <context context-type="sourcefile">app/shared/forms/reactive-file.component.html</context>
227 <context context-type="linenumber">11</context> 227 <context context-type="linenumber">11</context>
228 </context-group> 228 </context-group>
229 </trans-unit><trans-unit id="f3e63578c50546530daf6050d2ba6f8226040f2c" datatype="html">
230 <source>You don&apos;t have notifications.</source>
231 <context-group purpose="location">
232 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
233 <context context-type="linenumber">1</context>
234 </context-group>
235 </trans-unit><trans-unit id="f79d1d9ecaab3deb3d44e23017f8283a04d2a0f3" datatype="html">
236 <source>
237 &lt;x id="INTERPOLATION" equiv-text="{{ notification.video.channel.displayName }}"/&gt; published a &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;new video&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt;
238 </source>
239 <context-group purpose="location">
240 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
241 <context context-type="linenumber">7</context>
242 </context-group>
243 </trans-unit><trans-unit id="04f2cb4c88c17d5f3e5ce969479b4eba9db114cb" datatype="html">
244 <source>
245 Your video &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;&lt;x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/&gt;&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt; has been unblacklisted
246 </source>
247 <context-group purpose="location">
248 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
249 <context context-type="linenumber">11</context>
250 </context-group>
251 </trans-unit><trans-unit id="65514a0efdae3b173130166416700ddeb369f37f" datatype="html">
252 <source>
253 Your video &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;&lt;x id="INTERPOLATION" equiv-text="{{ notification.videoBlacklist.video.name }}"/&gt;&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt; has been blacklisted
254 </source>
255 <context-group purpose="location">
256 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
257 <context context-type="linenumber">15</context>
258 </context-group>
259 </trans-unit><trans-unit id="4ea67498da562ab450950a69f4331b8c4ddfd431" datatype="html">
260 <source>
261 &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;A new video abuse&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt; has been created on video &lt;x id="START_LINK_1" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;&lt;x id="INTERPOLATION" equiv-text="{{ notification.videoAbuse.video.name }}"/&gt;&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt;
262 </source>
263 <context-group purpose="location">
264 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
265 <context context-type="linenumber">19</context>
266 </context-group>
267 </trans-unit><trans-unit id="23b7d6f08c5c3b8722ecd627c3d54f4950923156" datatype="html">
268 <source>
269 &lt;x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/&gt; commented your video &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;&lt;x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/&gt;&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt;
270 </source>
271 <context-group purpose="location">
272 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
273 <context context-type="linenumber">23</context>
274 </context-group>
275 </trans-unit><trans-unit id="2d0ee93317d4daa301eee7fec775c21c2f7b5a4b" datatype="html">
276 <source>
277 Your video &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;&lt;x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/&gt;&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt; has been published
278 </source>
279 <context-group purpose="location">
280 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
281 <context context-type="linenumber">27</context>
282 </context-group>
283 </trans-unit><trans-unit id="371391b88724e5ee455582f07eb97728e371f24a" datatype="html">
284 <source>
285 &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;Your video import&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt; &lt;x id="INTERPOLATION" equiv-text="{{ notification.videoImportIdentifier }}"/&gt; succeeded
286 </source>
287 <context-group purpose="location">
288 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
289 <context context-type="linenumber">31</context>
290 </context-group>
291 </trans-unit><trans-unit id="56e72a0a79d53e9ff8d5f92528664bcb2cf1363a" datatype="html">
292 <source>
293 &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;Your video import&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt; &lt;x id="INTERPOLATION" equiv-text="{{ notification.videoImportIdentifier }}"/&gt; failed
294 </source>
295 <context-group purpose="location">
296 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
297 <context context-type="linenumber">35</context>
298 </context-group>
299 </trans-unit><trans-unit id="d7f123ae20ca6bfb5ac0f897b90423fdc52d8e78" datatype="html">
300 <source>
301 User &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;&lt;x id="INTERPOLATION" equiv-text="{{ notification.account.name }}"/&gt; registered&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt; on your instance
302 </source>
303 <context-group purpose="location">
304 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
305 <context context-type="linenumber">39</context>
306 </context-group>
307 </trans-unit><trans-unit id="9a05dc5206104085b2b6654fb9137291194a72ef" datatype="html">
308 <source>
309 &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;&lt;x id="INTERPOLATION" equiv-text="{{ notification.actorFollow.follower.displayName }}"/&gt;&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt; is following
310
311 &lt;x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/&gt;
312 your channel &lt;x id="INTERPOLATION_1" equiv-text="{{ notification.actorFollow.following.displayName }}"/&gt;
313 &lt;x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/&gt;
314 &lt;x id="START_TAG_NG-CONTAINER_1" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/&gt;your account&lt;x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/&gt;
315 </source>
316 <context-group purpose="location">
317 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
318 <context context-type="linenumber">43</context>
319 </context-group>
320 </trans-unit><trans-unit id="98b174525a2c9b4de0a510fb6eae7bdf285c0c7f" datatype="html">
321 <source>
322 &lt;x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/&gt; mentioned you on &lt;x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/&gt;video &lt;x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/&gt;&lt;x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/&gt;
323 </source>
324 <context-group purpose="location">
325 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
326 <context context-type="linenumber">52</context>
327 </context-group>
328 </trans-unit><trans-unit id="473117e02024f603dc2dbd24a0bf81f8722cf8dc" datatype="html">
329 <source>
330 &lt;x id="START_TAG_DIV" ctype="x-div" equiv-text="&lt;div&gt;"/&gt;&lt;x id="CLOSE_TAG_DIV" ctype="x-div" equiv-text="&lt;/div&gt;"/&gt;
331 </source>
332 <context-group purpose="location">
333 <context context-type="sourcefile">app/shared/users/user-notifications.component.html</context>
334 <context context-type="linenumber">57</context>
335 </context-group>
229 </trans-unit><trans-unit id="4b3963c6d0863118fe9e9e33447d12be3c2db081" datatype="html"> 336 </trans-unit><trans-unit id="4b3963c6d0863118fe9e9e33447d12be3c2db081" datatype="html">
230 <source>Unlisted</source> 337 <source>Unlisted</source>
231 <context-group purpose="location"> 338 <context-group purpose="location">
@@ -256,7 +363,7 @@
256 </context-group> 363 </context-group>
257 <context-group purpose="location"> 364 <context-group purpose="location">
258 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 365 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
259 <context context-type="linenumber">161</context> 366 <context context-type="linenumber">162</context>
260 </context-group> 367 </context-group>
261 <context-group purpose="location"> 368 <context-group purpose="location">
262 <context context-type="sourcefile">app/videos/+video-watch/video-watch.component.html</context> 369 <context context-type="sourcefile">app/videos/+video-watch/video-watch.component.html</context>
@@ -412,7 +519,7 @@
412 </context-group> 519 </context-group>
413 <context-group purpose="location"> 520 <context-group purpose="location">
414 <context context-type="sourcefile">app/videos/+video-watch/modal/video-report.component.html</context> 521 <context context-type="sourcefile">app/videos/+video-watch/modal/video-report.component.html</context>
415 <context context-type="linenumber">11</context> 522 <context context-type="linenumber">16</context>
416 </context-group> 523 </context-group>
417 <context-group purpose="location"> 524 <context-group purpose="location">
418 <context context-type="sourcefile">app/videos/+video-watch/modal/video-blacklist.component.html</context> 525 <context context-type="sourcefile">app/videos/+video-watch/modal/video-blacklist.component.html</context>
@@ -432,6 +539,12 @@
432 <context context-type="sourcefile">app/shared/moderation/user-ban-modal.component.html</context> 539 <context context-type="sourcefile">app/shared/moderation/user-ban-modal.component.html</context>
433 <context context-type="linenumber">25</context> 540 <context context-type="linenumber">25</context>
434 </context-group> 541 </context-group>
542 </trans-unit><trans-unit id="c078d4901a5fac169665947cc7a6108b94dd80c7" datatype="html">
543 <source>&lt;x id="INTERPOLATION" equiv-text="{{ menuEntry.label }}"/&gt;</source>
544 <context-group purpose="location">
545 <context context-type="sourcefile">app/shared/menu/top-menu-dropdown.component.html</context>
546 <context context-type="linenumber">11</context>
547 </context-group>
435 </trans-unit><trans-unit id="12910217fdcdbca64bee06f511639b653d5428ea" datatype="html"> 548 </trans-unit><trans-unit id="12910217fdcdbca64bee06f511639b653d5428ea" datatype="html">
436 <source> 549 <source>
437 Login 550 Login
@@ -520,7 +633,7 @@
520 </context-group> 633 </context-group>
521 <context-group purpose="location"> 634 <context-group purpose="location">
522 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-settings.component.html</context> 635 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-settings.component.html</context>
523 <context context-type="linenumber">12</context> 636 <context context-type="linenumber">13</context>
524 </context-group> 637 </context-group>
525 </trans-unit><trans-unit id="b87e81682959464211443afc3e23c506865d2eda" datatype="html"> 638 </trans-unit><trans-unit id="b87e81682959464211443afc3e23c506865d2eda" datatype="html">
526 <source>I forgot my password</source> 639 <source>I forgot my password</source>
@@ -536,7 +649,7 @@
536 </context-group> 649 </context-group>
537 <context-group purpose="location"> 650 <context-group purpose="location">
538 <context context-type="sourcefile">app/menu/menu.component.html</context> 651 <context context-type="sourcefile">app/menu/menu.component.html</context>
539 <context context-type="linenumber">38</context> 652 <context context-type="linenumber">36</context>
540 </context-group> 653 </context-group>
541 </trans-unit><trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681" datatype="html"> 654 </trans-unit><trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681" datatype="html">
542 <source>Forgot your password</source> 655 <source>Forgot your password</source>
@@ -544,11 +657,19 @@
544 <context context-type="sourcefile">app/login/login.component.html</context> 657 <context context-type="sourcefile">app/login/login.component.html</context>
545 <context context-type="linenumber">57</context> 658 <context context-type="linenumber">57</context>
546 </context-group> 659 </context-group>
660 </trans-unit><trans-unit id="f876804a6725f7b950c8e4c56ca596206856e6a2" datatype="html">
661 <source>
662 We are sorry, you cannot recover you password because your instance administrator did not configure the PeerTube email system.
663 </source>
664 <context-group purpose="location">
665 <context context-type="sourcefile">app/login/login.component.html</context>
666 <context context-type="linenumber">63</context>
667 </context-group>
547 </trans-unit><trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html"> 668 </trans-unit><trans-unit id="244aae9346da82b0922506c2d2581373a15641cc" datatype="html">
548 <source>Email</source> 669 <source>Email</source>
549 <context-group purpose="location"> 670 <context-group purpose="location">
550 <context context-type="sourcefile">app/login/login.component.html</context> 671 <context context-type="sourcefile">app/login/login.component.html</context>
551 <context context-type="linenumber">63</context> 672 <context context-type="linenumber">68</context>
552 </context-group> 673 </context-group>
553 <context-group purpose="location"> 674 <context-group purpose="location">
554 <context context-type="sourcefile">app/signup/signup.component.html</context> 675 <context context-type="sourcefile">app/signup/signup.component.html</context>
@@ -571,6 +692,10 @@
571 <context context-type="linenumber">41</context> 692 <context context-type="linenumber">41</context>
572 </context-group> 693 </context-group>
573 <context-group purpose="location"> 694 <context-group purpose="location">
695 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html</context>
696 <context context-type="linenumber">4</context>
697 </context-group>
698 <context-group purpose="location">
574 <context context-type="sourcefile">app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.html</context> 699 <context context-type="sourcefile">app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.html</context>
575 <context context-type="linenumber">8</context> 700 <context context-type="linenumber">8</context>
576 </context-group> 701 </context-group>
@@ -578,7 +703,7 @@
578 <source>Email address</source> 703 <source>Email address</source>
579 <context-group purpose="location"> 704 <context-group purpose="location">
580 <context context-type="sourcefile">app/login/login.component.html</context> 705 <context context-type="sourcefile">app/login/login.component.html</context>
581 <context context-type="linenumber">65</context> 706 <context context-type="linenumber">70</context>
582 </context-group> 707 </context-group>
583 <context-group purpose="location"> 708 <context-group purpose="location">
584 <context context-type="sourcefile">app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.html</context> 709 <context context-type="sourcefile">app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.html</context>
@@ -588,7 +713,7 @@
588 <source>Send me an email to reset my password</source> 713 <source>Send me an email to reset my password</source>
589 <context-group purpose="location"> 714 <context-group purpose="location">
590 <context context-type="sourcefile">app/login/login.component.html</context> 715 <context context-type="sourcefile">app/login/login.component.html</context>
591 <context context-type="linenumber">75</context> 716 <context context-type="linenumber">80</context>
592 </context-group> 717 </context-group>
593 </trans-unit><trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa" datatype="html"> 718 </trans-unit><trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa" datatype="html">
594 <source> 719 <source>
@@ -658,11 +783,11 @@
658 </context-group> 783 </context-group>
659 <context-group purpose="location"> 784 <context-group purpose="location">
660 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context> 785 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context>
661 <context context-type="linenumber">22</context> 786 <context context-type="linenumber">26</context>
662 </context-group> 787 </context-group>
663 <context-group purpose="location"> 788 <context-group purpose="location">
664 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 789 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
665 <context context-type="linenumber">88</context> 790 <context context-type="linenumber">78</context>
666 </context-group> 791 </context-group>
667 </trans-unit><trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1" datatype="html"> 792 </trans-unit><trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1" datatype="html">
668 <source>Features found on this instance</source> 793 <source>Features found on this instance</source>
@@ -721,7 +846,15 @@
721 </context-group> 846 </context-group>
722 <context-group purpose="location"> 847 <context-group purpose="location">
723 <context context-type="sourcefile">app/menu/menu.component.html</context> 848 <context context-type="sourcefile">app/menu/menu.component.html</context>
724 <context context-type="linenumber">88</context> 849 <context context-type="linenumber">86</context>
850 </context-group>
851 </trans-unit><trans-unit id="1c98d728375e7bd5b166d1aeb29485ef8b5d6e28" datatype="html">
852 <source>
853 Help to translate PeerTube!
854 </source>
855 <context-group purpose="location">
856 <context context-type="sourcefile">app/menu/language-chooser.component.html</context>
857 <context context-type="linenumber">8</context>
725 </context-group> 858 </context-group>
726 </trans-unit><trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6" datatype="html"> 859 </trans-unit><trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6" datatype="html">
727 <source> 860 <source>
@@ -729,7 +862,7 @@
729 </source> 862 </source>
730 <context-group purpose="location"> 863 <context-group purpose="location">
731 <context context-type="sourcefile">app/menu/menu.component.html</context> 864 <context context-type="sourcefile">app/menu/menu.component.html</context>
732 <context context-type="linenumber">18</context> 865 <context context-type="linenumber">16</context>
733 </context-group> 866 </context-group>
734 </trans-unit><trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb" datatype="html"> 867 </trans-unit><trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb" datatype="html">
735 <source> 868 <source>
@@ -737,7 +870,7 @@
737 </source> 870 </source>
738 <context-group purpose="location"> 871 <context-group purpose="location">
739 <context context-type="sourcefile">app/menu/menu.component.html</context> 872 <context context-type="sourcefile">app/menu/menu.component.html</context>
740 <context context-type="linenumber">22</context> 873 <context context-type="linenumber">20</context>
741 </context-group> 874 </context-group>
742 </trans-unit><trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10" datatype="html"> 875 </trans-unit><trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10" datatype="html">
743 <source> 876 <source>
@@ -745,7 +878,7 @@
745 </source> 878 </source>
746 <context-group purpose="location"> 879 <context-group purpose="location">
747 <context context-type="sourcefile">app/menu/menu.component.html</context> 880 <context context-type="sourcefile">app/menu/menu.component.html</context>
748 <context context-type="linenumber">26</context> 881 <context context-type="linenumber">24</context>
749 </context-group> 882 </context-group>
750 </trans-unit><trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1" datatype="html"> 883 </trans-unit><trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1" datatype="html">
751 <source> 884 <source>
@@ -753,19 +886,19 @@
753 </source> 886 </source>
754 <context-group purpose="location"> 887 <context-group purpose="location">
755 <context context-type="sourcefile">app/menu/menu.component.html</context> 888 <context context-type="sourcefile">app/menu/menu.component.html</context>
756 <context context-type="linenumber">30</context> 889 <context context-type="linenumber">28</context>
757 </context-group> 890 </context-group>
758 </trans-unit><trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87" datatype="html"> 891 </trans-unit><trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87" datatype="html">
759 <source>Create an account</source> 892 <source>Create an account</source>
760 <context-group purpose="location"> 893 <context-group purpose="location">
761 <context context-type="sourcefile">app/menu/menu.component.html</context> 894 <context context-type="sourcefile">app/menu/menu.component.html</context>
762 <context context-type="linenumber">39</context> 895 <context context-type="linenumber">37</context>
763 </context-group> 896 </context-group>
764 </trans-unit><trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238" datatype="html"> 897 </trans-unit><trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238" datatype="html">
765 <source>Videos</source> 898 <source>Videos</source>
766 <context-group purpose="location"> 899 <context-group purpose="location">
767 <context context-type="sourcefile">app/menu/menu.component.html</context> 900 <context context-type="sourcefile">app/menu/menu.component.html</context>
768 <context context-type="linenumber">43</context> 901 <context context-type="linenumber">41</context>
769 </context-group> 902 </context-group>
770 <context-group purpose="location"> 903 <context-group purpose="location">
771 <context context-type="sourcefile">app/+accounts/accounts.component.html</context> 904 <context context-type="sourcefile">app/+accounts/accounts.component.html</context>
@@ -779,49 +912,49 @@
779 <source>Subscriptions</source> 912 <source>Subscriptions</source>
780 <context-group purpose="location"> 913 <context-group purpose="location">
781 <context context-type="sourcefile">app/menu/menu.component.html</context> 914 <context context-type="sourcefile">app/menu/menu.component.html</context>
782 <context context-type="linenumber">47</context> 915 <context context-type="linenumber">45</context>
783 </context-group> 916 </context-group>
784 </trans-unit><trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html"> 917 </trans-unit><trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5" datatype="html">
785 <source>Overview</source> 918 <source>Overview</source>
786 <context-group purpose="location"> 919 <context-group purpose="location">
787 <context context-type="sourcefile">app/menu/menu.component.html</context> 920 <context context-type="sourcefile">app/menu/menu.component.html</context>
788 <context context-type="linenumber">52</context> 921 <context context-type="linenumber">50</context>
789 </context-group> 922 </context-group>
790 </trans-unit><trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807" datatype="html"> 923 </trans-unit><trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807" datatype="html">
791 <source>Trending</source> 924 <source>Trending</source>
792 <context-group purpose="location"> 925 <context-group purpose="location">
793 <context context-type="sourcefile">app/menu/menu.component.html</context> 926 <context context-type="sourcefile">app/menu/menu.component.html</context>
794 <context context-type="linenumber">57</context> 927 <context context-type="linenumber">55</context>
795 </context-group> 928 </context-group>
796 </trans-unit><trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1" datatype="html"> 929 </trans-unit><trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1" datatype="html">
797 <source>Recently added</source> 930 <source>Recently added</source>
798 <context-group purpose="location"> 931 <context-group purpose="location">
799 <context context-type="sourcefile">app/menu/menu.component.html</context> 932 <context context-type="sourcefile">app/menu/menu.component.html</context>
800 <context context-type="linenumber">62</context> 933 <context context-type="linenumber">60</context>
801 </context-group> 934 </context-group>
802 </trans-unit><trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d" datatype="html"> 935 </trans-unit><trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d" datatype="html">
803 <source>Local</source> 936 <source>Local</source>
804 <context-group purpose="location"> 937 <context-group purpose="location">
805 <context context-type="sourcefile">app/menu/menu.component.html</context> 938 <context context-type="sourcefile">app/menu/menu.component.html</context>
806 <context context-type="linenumber">67</context> 939 <context context-type="linenumber">65</context>
807 </context-group> 940 </context-group>
808 </trans-unit><trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f" datatype="html"> 941 </trans-unit><trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f" datatype="html">
809 <source>More</source> 942 <source>More</source>
810 <context-group purpose="location"> 943 <context-group purpose="location">
811 <context context-type="sourcefile">app/menu/menu.component.html</context> 944 <context context-type="sourcefile">app/menu/menu.component.html</context>
812 <context context-type="linenumber">72</context> 945 <context context-type="linenumber">70</context>
813 </context-group> 946 </context-group>
814 </trans-unit><trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919" datatype="html"> 947 </trans-unit><trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919" datatype="html">
815 <source>Administration</source> 948 <source>Administration</source>
816 <context-group purpose="location"> 949 <context-group purpose="location">
817 <context context-type="sourcefile">app/menu/menu.component.html</context> 950 <context context-type="sourcefile">app/menu/menu.component.html</context>
818 <context context-type="linenumber">76</context> 951 <context context-type="linenumber">74</context>
819 </context-group> 952 </context-group>
820 </trans-unit><trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html"> 953 </trans-unit><trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
821 <source>About</source> 954 <source>About</source>
822 <context-group purpose="location"> 955 <context-group purpose="location">
823 <context context-type="sourcefile">app/menu/menu.component.html</context> 956 <context context-type="sourcefile">app/menu/menu.component.html</context>
824 <context context-type="linenumber">81</context> 957 <context context-type="linenumber">79</context>
825 </context-group> 958 </context-group>
826 <context-group purpose="location"> 959 <context-group purpose="location">
827 <context context-type="sourcefile">app/+accounts/accounts.component.html</context> 960 <context context-type="sourcefile">app/+accounts/accounts.component.html</context>
@@ -835,13 +968,41 @@
835 <source>Show keyboard shortcuts</source> 968 <source>Show keyboard shortcuts</source>
836 <context-group purpose="location"> 969 <context-group purpose="location">
837 <context context-type="sourcefile">app/menu/menu.component.html</context> 970 <context context-type="sourcefile">app/menu/menu.component.html</context>
838 <context context-type="linenumber">91</context> 971 <context context-type="linenumber">89</context>
839 </context-group> 972 </context-group>
840 </trans-unit><trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768" datatype="html"> 973 </trans-unit><trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768" datatype="html">
841 <source>Toggle dark interface</source> 974 <source>Toggle dark interface</source>
842 <context-group purpose="location"> 975 <context-group purpose="location">
843 <context context-type="sourcefile">app/menu/menu.component.html</context> 976 <context context-type="sourcefile">app/menu/menu.component.html</context>
844 <context context-type="linenumber">94</context> 977 <context context-type="linenumber">92</context>
978 </context-group>
979 </trans-unit><trans-unit id="2dc8a0a3763cd5c456c84630fc335398c9b86771" datatype="html">
980 <source>View your notifications</source>
981 <context-group purpose="location">
982 <context context-type="sourcefile">app/menu/avatar-notification.component.html</context>
983 <context context-type="linenumber">3</context>
984 </context-group>
985 </trans-unit><trans-unit id="8bcabdf6b16cad0313a86c7e940c5e3ad7f9f8ab" datatype="html">
986 <source>Notifications</source>
987 <context-group purpose="location">
988 <context context-type="sourcefile">app/menu/avatar-notification.component.html</context>
989 <context context-type="linenumber">12</context>
990 </context-group>
991 <context-group purpose="location">
992 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-settings.component.html</context>
993 <context context-type="linenumber">10</context>
994 </context-group>
995 </trans-unit><trans-unit id="341e026e3f317aa3164916cc63a059c961a78b81" datatype="html">
996 <source>Update your notification preferences</source>
997 <context-group purpose="location">
998 <context context-type="sourcefile">app/menu/avatar-notification.component.html</context>
999 <context context-type="linenumber">15</context>
1000 </context-group>
1001 </trans-unit><trans-unit id="3d1b5c9cd76948c04fdb7bb3fe51b6c1242c1bd5" datatype="html">
1002 <source>See all your notifications</source>
1003 <context-group purpose="location">
1004 <context context-type="sourcefile">app/menu/avatar-notification.component.html</context>
1005 <context context-type="linenumber">22</context>
845 </context-group> 1006 </context-group>
846 </trans-unit><trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599" datatype="html"> 1007 </trans-unit><trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599" datatype="html">
847 <source>Search...</source> 1008 <source>Search...</source>
@@ -959,45 +1120,45 @@
959 <source>Display unlisted and private videos</source> 1120 <source>Display unlisted and private videos</source>
960 <context-group purpose="location"> 1121 <context-group purpose="location">
961 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1122 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
962 <context context-type="linenumber">11</context> 1123 <context context-type="linenumber">14</context>
963 </context-group> 1124 </context-group>
964 <context-group purpose="location"> 1125 <context-group purpose="location">
965 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1126 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
966 <context context-type="linenumber">11</context> 1127 <context context-type="linenumber">14</context>
967 </context-group> 1128 </context-group>
968 <context-group purpose="location"> 1129 <context-group purpose="location">
969 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1130 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
970 <context context-type="linenumber">11</context> 1131 <context context-type="linenumber">14</context>
971 </context-group> 1132 </context-group>
972 <context-group purpose="location"> 1133 <context-group purpose="location">
973 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1134 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
974 <context context-type="linenumber">11</context> 1135 <context context-type="linenumber">14</context>
975 </context-group> 1136 </context-group>
976 <context-group purpose="location"> 1137 <context-group purpose="location">
977 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1138 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
978 <context context-type="linenumber">11</context> 1139 <context context-type="linenumber">14</context>
979 </context-group> 1140 </context-group>
980 <context-group purpose="location"> 1141 <context-group purpose="location">
981 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1142 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
982 <context context-type="linenumber">11</context> 1143 <context context-type="linenumber">14</context>
983 </context-group> 1144 </context-group>
984 </trans-unit><trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e" datatype="html"> 1145 </trans-unit><trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e" datatype="html">
985 <source>No results.</source> 1146 <source>No results.</source>
986 <context-group purpose="location"> 1147 <context-group purpose="location">
987 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1148 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
988 <context context-type="linenumber">17</context> 1149 <context context-type="linenumber">20</context>
989 </context-group> 1150 </context-group>
990 <context-group purpose="location"> 1151 <context-group purpose="location">
991 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1152 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
992 <context context-type="linenumber">17</context> 1153 <context context-type="linenumber">20</context>
993 </context-group> 1154 </context-group>
994 <context-group purpose="location"> 1155 <context-group purpose="location">
995 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1156 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
996 <context context-type="linenumber">17</context> 1157 <context context-type="linenumber">20</context>
997 </context-group> 1158 </context-group>
998 <context-group purpose="location"> 1159 <context-group purpose="location">
999 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1160 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
1000 <context context-type="linenumber">17</context> 1161 <context context-type="linenumber">20</context>
1001 </context-group> 1162 </context-group>
1002 <context-group purpose="location"> 1163 <context-group purpose="location">
1003 <context context-type="sourcefile">app/videos/video-list/video-overview.component.html</context> 1164 <context context-type="sourcefile">app/videos/video-list/video-overview.component.html</context>
@@ -1005,7 +1166,7 @@
1005 </context-group> 1166 </context-group>
1006 <context-group purpose="location"> 1167 <context-group purpose="location">
1007 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1168 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
1008 <context context-type="linenumber">17</context> 1169 <context context-type="linenumber">20</context>
1009 </context-group> 1170 </context-group>
1010 <context-group purpose="location"> 1171 <context-group purpose="location">
1011 <context context-type="sourcefile">app/+my-account/my-account-videos/my-account-videos.component.html</context> 1172 <context context-type="sourcefile">app/+my-account/my-account-videos/my-account-videos.component.html</context>
@@ -1013,7 +1174,7 @@
1013 </context-group> 1174 </context-group>
1014 <context-group purpose="location"> 1175 <context-group purpose="location">
1015 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context> 1176 <context context-type="sourcefile">app/shared/video/abstract-video-list.html</context>
1016 <context context-type="linenumber">17</context> 1177 <context context-type="linenumber">20</context>
1017 </context-group> 1178 </context-group>
1018 </trans-unit><trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6" datatype="html"> 1179 </trans-unit><trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6" datatype="html">
1019 <source> 1180 <source>
@@ -1067,19 +1228,85 @@
1067 <context context-type="sourcefile">app/+about/about.component.html</context> 1228 <context context-type="sourcefile">app/+about/about.component.html</context>
1068 <context context-type="linenumber">7</context> 1229 <context context-type="linenumber">7</context>
1069 </context-group> 1230 </context-group>
1070 </trans-unit><trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2" datatype="html"> 1231 </trans-unit><trans-unit id="5fea66be16da46ed7a0775e9a62b7b5e94b77473" datatype="html">
1232 <source>Contact &lt;x id="INTERPOLATION" equiv-text="{{ instanceName }}"/&gt; administrator</source>
1233 <context-group purpose="location">
1234 <context context-type="sourcefile">app/+about/about-instance/contact-admin-modal.component.html</context>
1235 <context context-type="linenumber">3</context>
1236 </context-group>
1237 </trans-unit><trans-unit id="533b2b9a76ee1335cb44c01f0bfd50d43e9400b0" datatype="html">
1238 <source>Your name</source>
1239 <context-group purpose="location">
1240 <context context-type="sourcefile">app/+about/about-instance/contact-admin-modal.component.html</context>
1241 <context context-type="linenumber">11</context>
1242 </context-group>
1243 </trans-unit><trans-unit id="0b892c7805a1c5afc0b7c21c3449760860fe7f3d" datatype="html">
1244 <source>Your email</source>
1245 <context-group purpose="location">
1246 <context context-type="sourcefile">app/+about/about-instance/contact-admin-modal.component.html</context>
1247 <context context-type="linenumber">20</context>
1248 </context-group>
1249 </trans-unit><trans-unit id="d2815c9b510b8172d8cac4008b9709df69d636df" datatype="html">
1250 <source>Your message</source>
1251 <context-group purpose="location">
1252 <context context-type="sourcefile">app/+about/about-instance/contact-admin-modal.component.html</context>
1253 <context context-type="linenumber">29</context>
1254 </context-group>
1255 </trans-unit><trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb" datatype="html">
1071 <source> 1256 <source>
1072 About &lt;x id="INTERPOLATION" equiv-text="{{ instanceName }}"/&gt; instance 1257 Cancel
1073</source> 1258 </source>
1259 <context-group purpose="location">
1260 <context context-type="sourcefile">app/+about/about-instance/contact-admin-modal.component.html</context>
1261 <context context-type="linenumber">38</context>
1262 </context-group>
1263 <context-group purpose="location">
1264 <context context-type="sourcefile">app/videos/+video-watch/modal/video-report.component.html</context>
1265 <context context-type="linenumber">24</context>
1266 </context-group>
1267 <context-group purpose="location">
1268 <context context-type="sourcefile">app/videos/+video-watch/modal/video-blacklist.component.html</context>
1269 <context context-type="linenumber">26</context>
1270 </context-group>
1271 </trans-unit><trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd" datatype="html">
1272 <source>Submit</source>
1273 <context-group purpose="location">
1274 <context context-type="sourcefile">app/+about/about-instance/contact-admin-modal.component.html</context>
1275 <context context-type="linenumber">43</context>
1276 </context-group>
1277 <context-group purpose="location">
1278 <context context-type="sourcefile">app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html</context>
1279 <context context-type="linenumber">25</context>
1280 </context-group>
1281 <context-group purpose="location">
1282 <context context-type="sourcefile">app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.html</context>
1283 <context context-type="linenumber">28</context>
1284 </context-group>
1285 <context-group purpose="location">
1286 <context context-type="sourcefile">app/videos/+video-watch/modal/video-report.component.html</context>
1287 <context context-type="linenumber">29</context>
1288 </context-group>
1289 <context-group purpose="location">
1290 <context context-type="sourcefile">app/videos/+video-watch/modal/video-blacklist.component.html</context>
1291 <context context-type="linenumber">31</context>
1292 </context-group>
1293 </trans-unit><trans-unit id="89e55a86cb300f06139ff398c9c8bb7376f78b07" datatype="html">
1294 <source>About &lt;x id="INTERPOLATION" equiv-text="{{ instanceName }}"/&gt; instance</source>
1074 <context-group purpose="location"> 1295 <context-group purpose="location">
1075 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context> 1296 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context>
1076 <context context-type="linenumber">1</context> 1297 <context context-type="linenumber">4</context>
1298 </context-group>
1299 </trans-unit><trans-unit id="3c1aff50472b313c70a72ee02c081b8eeb1c616c" datatype="html">
1300 <source>Contact administrator</source>
1301 <context-group purpose="location">
1302 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context>
1303 <context context-type="linenumber">6</context>
1077 </context-group> 1304 </context-group>
1078 </trans-unit><trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html"> 1305 </trans-unit><trans-unit id="eec715de352a6b114713b30b640d319fa78207a0" datatype="html">
1079 <source>Description</source> 1306 <source>Description</source>
1080 <context-group purpose="location"> 1307 <context-group purpose="location">
1081 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context> 1308 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context>
1082 <context context-type="linenumber">10</context> 1309 <context context-type="linenumber">14</context>
1083 </context-group> 1310 </context-group>
1084 <context-group purpose="location"> 1311 <context-group purpose="location">
1085 <context context-type="sourcefile">app/+accounts/account-about/account-about.component.html</context> 1312 <context context-type="sourcefile">app/+accounts/account-about/account-about.component.html</context>
@@ -1087,7 +1314,7 @@
1087 </context-group> 1314 </context-group>
1088 <context-group purpose="location"> 1315 <context-group purpose="location">
1089 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1316 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1090 <context context-type="linenumber">33</context> 1317 <context context-type="linenumber">30</context>
1091 </context-group> 1318 </context-group>
1092 <context-group purpose="location"> 1319 <context-group purpose="location">
1093 <context context-type="sourcefile">app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html</context> 1320 <context context-type="sourcefile">app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html</context>
@@ -1113,41 +1340,41 @@
1113 <source>Terms</source> 1340 <source>Terms</source>
1114 <context-group purpose="location"> 1341 <context-group purpose="location">
1115 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context> 1342 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context>
1116 <context context-type="linenumber">16</context> 1343 <context context-type="linenumber">20</context>
1117 </context-group> 1344 </context-group>
1118 <context-group purpose="location"> 1345 <context-group purpose="location">
1119 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1346 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1120 <context context-type="linenumber">44</context> 1347 <context context-type="linenumber">39</context>
1121 </context-group> 1348 </context-group>
1122 </trans-unit><trans-unit id="9c6e6db693ab265457c6578df179c65694141d27" datatype="html"> 1349 </trans-unit><trans-unit id="9c6e6db693ab265457c6578df179c65694141d27" datatype="html">
1123 <source>User registration is allowed and</source> 1350 <source>User registration is allowed and</source>
1124 <context-group purpose="location"> 1351 <context-group purpose="location">
1125 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context> 1352 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context>
1126 <context context-type="linenumber">25</context> 1353 <context context-type="linenumber">29</context>
1127 </context-group> 1354 </context-group>
1128 </trans-unit><trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e" datatype="html"> 1355 </trans-unit><trans-unit id="7a0a7b5a5bc9ee7b7e415f87ecc404145fb51dff" datatype="html">
1129 <source> 1356 <source>
1130 this instance provides a baseline quota of &lt;x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/&gt; space for the videos of its users. 1357 this instance provides a baseline quota of &lt;x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/&gt; space for the videos of its users.
1131 </source> 1358 </source>
1132 <context-group purpose="location"> 1359 <context-group purpose="location">
1133 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context> 1360 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context>
1134 <context context-type="linenumber">27</context> 1361 <context context-type="linenumber">31</context>
1135 </context-group> 1362 </context-group>
1136 </trans-unit><trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae" datatype="html"> 1363 </trans-unit><trans-unit id="7bee5dd41c0007820f150ee33b8257dc1aac281b" datatype="html">
1137 <source> 1364 <source>
1138 this instance provides unlimited space for the videos of its users. 1365 this instance provides unlimited space for the videos of its users.
1139 </source> 1366 </source>
1140 <context-group purpose="location"> 1367 <context-group purpose="location">
1141 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context> 1368 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context>
1142 <context context-type="linenumber">31</context> 1369 <context context-type="linenumber">35</context>
1143 </context-group> 1370 </context-group>
1144 </trans-unit><trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1" datatype="html"> 1371 </trans-unit><trans-unit id="b6e2ede24a2ee0f6ba2f1924ede2ae408ffc2574" datatype="html">
1145 <source> 1372 <source>
1146 User registration is currently not allowed. 1373 User registration is currently not allowed.
1147 </source> 1374 </source>
1148 <context-group purpose="location"> 1375 <context-group purpose="location">
1149 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context> 1376 <context context-type="sourcefile">app/+about/about-instance/about-instance.component.html</context>
1150 <context context-type="linenumber">36</context> 1377 <context context-type="linenumber">40</context>
1151 </context-group> 1378 </context-group>
1152 </trans-unit><trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc" datatype="html"> 1379 </trans-unit><trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc" datatype="html">
1153 <source> 1380 <source>
@@ -1433,7 +1660,7 @@
1433 <source>Name</source> 1660 <source>Name</source>
1434 <context-group purpose="location"> 1661 <context-group purpose="location">
1435 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1662 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1436 <context context-type="linenumber">11</context> 1663 <context context-type="linenumber">12</context>
1437 </context-group> 1664 </context-group>
1438 <context-group purpose="location"> 1665 <context-group purpose="location">
1439 <context context-type="sourcefile">app/+admin/follows/followers-list/followers-list.component.html</context> 1666 <context context-type="sourcefile">app/+admin/follows/followers-list/followers-list.component.html</context>
@@ -1451,49 +1678,49 @@
1451 <source>Short description</source> 1678 <source>Short description</source>
1452 <context-group purpose="location"> 1679 <context-group purpose="location">
1453 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1680 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1454 <context context-type="linenumber">22</context> 1681 <context context-type="linenumber">21</context>
1455 </context-group> 1682 </context-group>
1456 </trans-unit><trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003" datatype="html"> 1683 </trans-unit><trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003" datatype="html">
1457 <source>Default client route</source> 1684 <source>Default client route</source>
1458 <context-group purpose="location"> 1685 <context-group purpose="location">
1459 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1686 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1460 <context context-type="linenumber">55</context> 1687 <context context-type="linenumber">48</context>
1461 </context-group> 1688 </context-group>
1462 </trans-unit><trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d" datatype="html"> 1689 </trans-unit><trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d" datatype="html">
1463 <source>Videos Overview</source> 1690 <source>Videos Overview</source>
1464 <context-group purpose="location"> 1691 <context-group purpose="location">
1465 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1692 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1466 <context context-type="linenumber">58</context> 1693 <context context-type="linenumber">51</context>
1467 </context-group> 1694 </context-group>
1468 </trans-unit><trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948" datatype="html"> 1695 </trans-unit><trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948" datatype="html">
1469 <source>Videos Trending</source> 1696 <source>Videos Trending</source>
1470 <context-group purpose="location"> 1697 <context-group purpose="location">
1471 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1698 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1472 <context context-type="linenumber">59</context> 1699 <context context-type="linenumber">52</context>
1473 </context-group> 1700 </context-group>
1474 </trans-unit><trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883" datatype="html"> 1701 </trans-unit><trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883" datatype="html">
1475 <source>Videos Recently Added</source> 1702 <source>Videos Recently Added</source>
1476 <context-group purpose="location"> 1703 <context-group purpose="location">
1477 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1704 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1478 <context context-type="linenumber">60</context> 1705 <context context-type="linenumber">53</context>
1479 </context-group> 1706 </context-group>
1480 </trans-unit><trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f" datatype="html"> 1707 </trans-unit><trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f" datatype="html">
1481 <source>Local videos</source> 1708 <source>Local videos</source>
1482 <context-group purpose="location"> 1709 <context-group purpose="location">
1483 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1710 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1484 <context context-type="linenumber">61</context> 1711 <context context-type="linenumber">54</context>
1485 </context-group> 1712 </context-group>
1486 </trans-unit><trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9" datatype="html"> 1713 </trans-unit><trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9" datatype="html">
1487 <source>Policy on videos containing sensitive content</source> 1714 <source>Policy on videos containing sensitive content</source>
1488 <context-group purpose="location"> 1715 <context-group purpose="location">
1489 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1716 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1490 <context context-type="linenumber">70</context> 1717 <context context-type="linenumber">61</context>
1491 </context-group> 1718 </context-group>
1492 </trans-unit><trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df" datatype="html"> 1719 </trans-unit><trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df" datatype="html">
1493 <source>With &lt;strong&gt;Do not list&lt;/strong&gt; or &lt;strong&gt;Blur thumbnails&lt;/strong&gt;, a confirmation will be requested to watch the video.</source> 1720 <source>With &lt;strong&gt;Do not list&lt;/strong&gt; or &lt;strong&gt;Blur thumbnails&lt;/strong&gt;, a confirmation will be requested to watch the video.</source>
1494 <context-group purpose="location"> 1721 <context-group purpose="location">
1495 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1722 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1496 <context context-type="linenumber">73</context> 1723 <context context-type="linenumber">64</context>
1497 </context-group> 1724 </context-group>
1498 <context-group purpose="location"> 1725 <context-group purpose="location">
1499 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html</context> 1726 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html</context>
@@ -1503,7 +1730,7 @@
1503 <source>Do not list</source> 1730 <source>Do not list</source>
1504 <context-group purpose="location"> 1731 <context-group purpose="location">
1505 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1732 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1506 <context context-type="linenumber">78</context> 1733 <context context-type="linenumber">69</context>
1507 </context-group> 1734 </context-group>
1508 <context-group purpose="location"> 1735 <context-group purpose="location">
1509 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html</context> 1736 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html</context>
@@ -1513,7 +1740,7 @@
1513 <source>Blur thumbnails</source> 1740 <source>Blur thumbnails</source>
1514 <context-group purpose="location"> 1741 <context-group purpose="location">
1515 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1742 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1516 <context context-type="linenumber">79</context> 1743 <context context-type="linenumber">70</context>
1517 </context-group> 1744 </context-group>
1518 <context-group purpose="location"> 1745 <context-group purpose="location">
1519 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html</context> 1746 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html</context>
@@ -1523,7 +1750,7 @@
1523 <source>Display</source> 1750 <source>Display</source>
1524 <context-group purpose="location"> 1751 <context-group purpose="location">
1525 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1752 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1526 <context context-type="linenumber">80</context> 1753 <context context-type="linenumber">71</context>
1527 </context-group> 1754 </context-group>
1528 <context-group purpose="location"> 1755 <context-group purpose="location">
1529 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html</context> 1756 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html</context>
@@ -1533,25 +1760,43 @@
1533 <source>Signup enabled</source> 1760 <source>Signup enabled</source>
1534 <context-group purpose="location"> 1761 <context-group purpose="location">
1535 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1762 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1536 <context context-type="linenumber">93</context> 1763 <context context-type="linenumber">84</context>
1537 </context-group> 1764 </context-group>
1538 </trans-unit><trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7" datatype="html"> 1765 </trans-unit><trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7" datatype="html">
1539 <source>Signup requires email verification</source> 1766 <source>Signup requires email verification</source>
1540 <context-group purpose="location"> 1767 <context-group purpose="location">
1541 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1768 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1542 <context context-type="linenumber">100</context> 1769 <context context-type="linenumber">91</context>
1543 </context-group> 1770 </context-group>
1544 </trans-unit><trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402" datatype="html"> 1771 </trans-unit><trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402" datatype="html">
1545 <source>Signup limit</source> 1772 <source>Signup limit</source>
1546 <context-group purpose="location"> 1773 <context-group purpose="location">
1547 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1774 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1775 <context context-type="linenumber">96</context>
1776 </context-group>
1777 </trans-unit><trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
1778 <source>Users</source>
1779 <context-group purpose="location">
1780 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1548 <context context-type="linenumber">105</context> 1781 <context context-type="linenumber">105</context>
1549 </context-group> 1782 </context-group>
1783 </trans-unit><trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09" datatype="html">
1784 <source>User default video quota</source>
1785 <context-group purpose="location">
1786 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1787 <context context-type="linenumber">109</context>
1788 </context-group>
1789 </trans-unit><trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe" datatype="html">
1790 <source>User default daily upload limit</source>
1791 <context-group purpose="location">
1792 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1793 <context context-type="linenumber">121</context>
1794 </context-group>
1550 </trans-unit><trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36" datatype="html"> 1795 </trans-unit><trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36" datatype="html">
1551 <source>Import</source> 1796 <source>Import</source>
1552 <context-group purpose="location"> 1797 <context-group purpose="location">
1553 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1798 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1554 <context context-type="linenumber">115</context> 1799 <context context-type="linenumber">133</context>
1555 </context-group> 1800 </context-group>
1556 <context-group purpose="location"> 1801 <context-group purpose="location">
1557 <context context-type="sourcefile">app/videos/+video-edit/video-add-components/video-import-url.component.html</context> 1802 <context context-type="sourcefile">app/videos/+video-edit/video-add-components/video-import-url.component.html</context>
@@ -1565,43 +1810,31 @@
1565 <source>Video import with HTTP URL (i.e. YouTube) enabled</source> 1810 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1566 <context-group purpose="location"> 1811 <context-group purpose="location">
1567 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1812 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1568 <context context-type="linenumber">120</context> 1813 <context context-type="linenumber">141</context>
1569 </context-group> 1814 </context-group>
1570 </trans-unit><trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e" datatype="html"> 1815 </trans-unit><trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e" datatype="html">
1571 <source>Video import with a torrent file or a magnet URI enabled</source> 1816 <source>Video import with a torrent file or a magnet URI enabled</source>
1572 <context-group purpose="location"> 1817 <context-group purpose="location">
1573 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1818 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1574 <context context-type="linenumber">127</context> 1819 <context context-type="linenumber">148</context>
1575 </context-group> 1820 </context-group>
1576 </trans-unit><trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011" datatype="html"> 1821 </trans-unit><trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011" datatype="html">
1577 <source>Administrator</source> 1822 <source>Administrator</source>
1578 <context-group purpose="location"> 1823 <context-group purpose="location">
1579 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1824 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1580 <context context-type="linenumber">131</context> 1825 <context context-type="linenumber">155</context>
1581 </context-group> 1826 </context-group>
1582 </trans-unit><trans-unit id="55a0f51e38679d3141841e8333da5779d349c587" datatype="html"> 1827 </trans-unit><trans-unit id="55a0f51e38679d3141841e8333da5779d349c587" datatype="html">
1583 <source>Admin email</source> 1828 <source>Admin email</source>
1584 <context-group purpose="location"> 1829 <context-group purpose="location">
1585 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1830 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1586 <context context-type="linenumber">134</context> 1831 <context context-type="linenumber">158</context>
1587 </context-group>
1588 </trans-unit><trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be" datatype="html">
1589 <source>Users</source>
1590 <context-group purpose="location">
1591 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1592 <context context-type="linenumber">144</context>
1593 </context-group>
1594 </trans-unit><trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09" datatype="html">
1595 <source>User default video quota</source>
1596 <context-group purpose="location">
1597 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1598 <context context-type="linenumber">147</context>
1599 </context-group> 1832 </context-group>
1600 </trans-unit><trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe" datatype="html"> 1833 </trans-unit><trans-unit id="f9bda6652199995a4bd4424f2e35b748eb0bda8a" datatype="html">
1601 <source>User default daily upload limit</source> 1834 <source>Enable contact form</source>
1602 <context-group purpose="location"> 1835 <context-group purpose="location">
1603 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1836 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1604 <context context-type="linenumber">161</context> 1837 <context context-type="linenumber">169</context>
1605 </context-group> 1838 </context-group>
1606 </trans-unit><trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5" datatype="html"> 1839 </trans-unit><trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5" datatype="html">
1607 <source>Basic configuration</source> 1840 <source>Basic configuration</source>
@@ -1619,27 +1852,27 @@
1619 <source>Your Twitter username</source> 1852 <source>Your Twitter username</source>
1620 <context-group purpose="location"> 1853 <context-group purpose="location">
1621 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1854 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1622 <context context-type="linenumber">181</context> 1855 <context context-type="linenumber">184</context>
1623 </context-group> 1856 </context-group>
1624 </trans-unit><trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c" datatype="html"> 1857 </trans-unit><trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c" datatype="html">
1625 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1858 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1626 <context-group purpose="location"> 1859 <context-group purpose="location">
1627 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1860 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1628 <context context-type="linenumber">184</context> 1861 <context context-type="linenumber">187</context>
1629 </context-group> 1862 </context-group>
1630 </trans-unit><trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605" datatype="html"> 1863 </trans-unit><trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605" datatype="html">
1631 <source>Instance whitelisted by Twitter</source> 1864 <source>Instance whitelisted by Twitter</source>
1632 <context-group purpose="location"> 1865 <context-group purpose="location">
1633 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1866 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1634 <context context-type="linenumber">198</context> 1867 <context context-type="linenumber">199</context>
1635 </context-group> 1868 </context-group>
1636 </trans-unit><trans-unit id="8b0ee765cc3fea9baef14bfb9d5288dfcbe386b6" datatype="html"> 1869 </trans-unit><trans-unit id="f1276a50033dfc7a71290086d0f57d89e3438e6b" datatype="html">
1637 <source>If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.&lt;br /&gt; 1870 <source>If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.&lt;br /&gt;
1638 If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.&lt;br /&gt;&lt;br /&gt; 1871 If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.&lt;br /&gt;&lt;br /&gt;
1639 Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on &lt;a target=&apos;_blank&apos; rel=&apos;noopener noreferrer&apos; href=&apos;https://cards-dev.twitter.com/validator&apos;&gt;https://cards-dev.twitter.com/validator&lt;/a&gt; to see if you instance is whitelisted.</source> 1872 Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on &lt;a target=&apos;_blank&apos; rel=&apos;noopener noreferrer&apos; href=&apos;https://cards-dev.twitter.com/validator&apos;&gt;https://cards-dev.twitter.com/validator&lt;/a&gt; to see if you instance is whitelisted.</source>
1640 <context-group purpose="location"> 1873 <context-group purpose="location">
1641 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1874 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1642 <context context-type="linenumber">199</context> 1875 <context context-type="linenumber">200</context>
1643 </context-group> 1876 </context-group>
1644 </trans-unit><trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html"> 1877 </trans-unit><trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5" datatype="html">
1645 <source>Services</source> 1878 <source>Services</source>
@@ -1651,31 +1884,43 @@
1651 <source>Transcoding</source> 1884 <source>Transcoding</source>
1652 <context-group purpose="location"> 1885 <context-group purpose="location">
1653 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1886 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1654 <context context-type="linenumber">210</context> 1887 <context context-type="linenumber">215</context>
1655 </context-group> 1888 </context-group>
1656 </trans-unit><trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9" datatype="html"> 1889 </trans-unit><trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9" datatype="html">
1657 <source>Transcoding enabled</source> 1890 <source>Transcoding enabled</source>
1658 <context-group purpose="location"> 1891 <context-group purpose="location">
1659 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1892 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1660 <context context-type="linenumber">215</context> 1893 <context context-type="linenumber">221</context>
1661 </context-group> 1894 </context-group>
1662 </trans-unit><trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f" datatype="html"> 1895 </trans-unit><trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f" datatype="html">
1663 <source>If you disable transcoding, many videos from your users will not work!</source> 1896 <source>If you disable transcoding, many videos from your users will not work!</source>
1664 <context-group purpose="location"> 1897 <context-group purpose="location">
1665 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1898 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1666 <context context-type="linenumber">216</context> 1899 <context context-type="linenumber">222</context>
1900 </context-group>
1901 </trans-unit><trans-unit id="0050a55afb9c565df1f9b3f750c2d4adb697698f" datatype="html">
1902 <source>Allow additional extensions</source>
1903 <context-group purpose="location">
1904 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1905 <context context-type="linenumber">231</context>
1906 </context-group>
1907 </trans-unit><trans-unit id="9b82c3a407ee5a98c92483fbd987be8db8384c33" datatype="html">
1908 <source>Allow your users to upload .mkv, .mov, .avi, .flv videos</source>
1909 <context-group purpose="location">
1910 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1911 <context context-type="linenumber">232</context>
1667 </context-group> 1912 </context-group>
1668 </trans-unit><trans-unit id="a33feadefbb776217c2db96100736314f8b765c2" datatype="html"> 1913 </trans-unit><trans-unit id="a33feadefbb776217c2db96100736314f8b765c2" datatype="html">
1669 <source>Transcoding threads</source> 1914 <source>Transcoding threads</source>
1670 <context-group purpose="location"> 1915 <context-group purpose="location">
1671 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1916 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1672 <context context-type="linenumber">223</context> 1917 <context context-type="linenumber">237</context>
1673 </context-group> 1918 </context-group>
1674 </trans-unit><trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500" datatype="html"> 1919 </trans-unit><trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500" datatype="html">
1675 <source>Resolution &lt;x id="INTERPOLATION" equiv-text="{{resolution}}"/&gt; enabled</source> 1920 <source>Resolution &lt;x id="INTERPOLATION" equiv-text="{{resolution}}"/&gt; enabled</source>
1676 <context-group purpose="location"> 1921 <context-group purpose="location">
1677 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1922 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1678 <context context-type="linenumber">239</context> 1923 <context context-type="linenumber">252</context>
1679 </context-group> 1924 </context-group>
1680 </trans-unit><trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5" datatype="html"> 1925 </trans-unit><trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5" datatype="html">
1681 <source> 1926 <source>
@@ -1685,81 +1930,81 @@
1685 </source> 1930 </source>
1686 <context-group purpose="location"> 1931 <context-group purpose="location">
1687 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1932 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1688 <context context-type="linenumber">244</context> 1933 <context context-type="linenumber">260</context>
1689 </context-group> 1934 </context-group>
1690 </trans-unit><trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0" datatype="html"> 1935 </trans-unit><trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0" datatype="html">
1691 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1936 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1692 <context-group purpose="location"> 1937 <context-group purpose="location">
1693 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1938 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1694 <context context-type="linenumber">249</context> 1939 <context context-type="linenumber">265</context>
1695 </context-group> 1940 </context-group>
1696 </trans-unit><trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7" datatype="html"> 1941 </trans-unit><trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7" datatype="html">
1697 <source>Previews cache size</source> 1942 <source>Previews cache size</source>
1698 <context-group purpose="location"> 1943 <context-group purpose="location">
1699 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1944 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1700 <context context-type="linenumber">254</context> 1945 <context context-type="linenumber">271</context>
1701 </context-group> 1946 </context-group>
1702 </trans-unit><trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607" datatype="html"> 1947 </trans-unit><trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607" datatype="html">
1703 <source>Video captions cache size</source> 1948 <source>Video captions cache size</source>
1704 <context-group purpose="location"> 1949 <context-group purpose="location">
1705 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1950 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1706 <context context-type="linenumber">265</context> 1951 <context context-type="linenumber">280</context>
1707 </context-group> 1952 </context-group>
1708 </trans-unit><trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c" datatype="html"> 1953 </trans-unit><trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c" datatype="html">
1709 <source>Customizations</source> 1954 <source>Customizations</source>
1710 <context-group purpose="location"> 1955 <context-group purpose="location">
1711 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1956 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1712 <context context-type="linenumber">275</context> 1957 <context context-type="linenumber">289</context>
1713 </context-group> 1958 </context-group>
1714 </trans-unit><trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c" datatype="html"> 1959 </trans-unit><trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c" datatype="html">
1715 <source>JavaScript</source> 1960 <source>JavaScript</source>
1716 <context-group purpose="location"> 1961 <context-group purpose="location">
1717 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1962 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1718 <context context-type="linenumber">278</context> 1963 <context context-type="linenumber">294</context>
1719 </context-group> 1964 </context-group>
1720 </trans-unit><trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c" datatype="html"> 1965 </trans-unit><trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c" datatype="html">
1721 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log(&apos;my instance is amazing&apos;);&lt;/pre&gt;</source> 1966 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log(&apos;my instance is amazing&apos;);&lt;/pre&gt;</source>
1722 <context-group purpose="location"> 1967 <context-group purpose="location">
1723 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1968 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1724 <context context-type="linenumber">281</context> 1969 <context context-type="linenumber">297</context>
1725 </context-group> 1970 </context-group>
1726 </trans-unit><trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5" datatype="html"> 1971 </trans-unit><trans-unit id="d7caa08cd9b3119881bbaec3f5a3c5707f573dde" datatype="html">
1727 <source> 1972 <source>
1728 Write directly CSS code. Example:&lt;br /&gt; 1973 Write directly CSS code. Example:&lt;br /&gt;
1729 &lt;pre&gt; 1974 &lt;pre&gt;
1730 body &lt;x id="INTERPOLATION" equiv-text="{{ &apos;{&apos; }}"/&gt; 1975 body &lt;x id="INTERPOLATION" equiv-text="{{ &apos;{&apos; }}"/&gt;
1731 background-color: red; 1976 background-color: red;
1732 &lt;x id="INTERPOLATION_1" equiv-text="{{ &apos;}&apos; }}"/&gt; 1977 &lt;x id="INTERPOLATION_1" equiv-text="{{ &apos;}&apos; }}"/&gt;
1733 &lt;/pre&gt; 1978 &lt;/pre&gt;
1734 1979
1735 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example: 1980 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1736 &lt;pre&gt; 1981 &lt;pre&gt;
1737 #custom-css .logged-in-email &lt;x id="INTERPOLATION" equiv-text="{{ &apos;{&apos; }}"/&gt; 1982 #custom-css .logged-in-email &lt;x id="INTERPOLATION" equiv-text="{{ &apos;{&apos; }}"/&gt;
1738 color: red; 1983 color: red;
1739 &lt;x id="INTERPOLATION_1" equiv-text="{{ &apos;}&apos; }}"/&gt; 1984 &lt;x id="INTERPOLATION_1" equiv-text="{{ &apos;}&apos; }}"/&gt;
1740 &lt;/pre&gt; 1985 &lt;/pre&gt;
1741 </source> 1986 </source>
1742 <context-group purpose="location"> 1987 <context-group purpose="location">
1743 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1988 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1744 <context context-type="linenumber">297</context> 1989 <context context-type="linenumber">311</context>
1745 </context-group> 1990 </context-group>
1746 </trans-unit><trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab" datatype="html"> 1991 </trans-unit><trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab" datatype="html">
1747 <source>Advanced configuration</source> 1992 <source>Advanced configuration</source>
1748 <context-group purpose="location"> 1993 <context-group purpose="location">
1749 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 1994 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1750 <context context-type="linenumber">207</context> 1995 <context context-type="linenumber">212</context>
1751 </context-group> 1996 </context-group>
1752 </trans-unit><trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8" datatype="html"> 1997 </trans-unit><trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8" datatype="html">
1753 <source>Update configuration</source> 1998 <source>Update configuration</source>
1754 <context-group purpose="location"> 1999 <context-group purpose="location">
1755 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 2000 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1756 <context context-type="linenumber">325</context> 2001 <context context-type="linenumber">340</context>
1757 </context-group> 2002 </context-group>
1758 </trans-unit><trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca" datatype="html"> 2003 </trans-unit><trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca" datatype="html">
1759 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 2004 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1760 <context-group purpose="location"> 2005 <context-group purpose="location">
1761 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context> 2006 <context context-type="sourcefile">app/+admin/config/edit-custom-config/edit-custom-config.component.html</context>
1762 <context context-type="linenumber">326</context> 2007 <context context-type="linenumber">341</context>
1763 </context-group> 2008 </context-group>
1764 </trans-unit><trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c" datatype="html"> 2009 </trans-unit><trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c" datatype="html">
1765 <source> 2010 <source>
@@ -2102,19 +2347,19 @@
2102 <source>User&apos;s email must be verified to login</source> 2347 <source>User&apos;s email must be verified to login</source>
2103 <context-group purpose="location"> 2348 <context-group purpose="location">
2104 <context context-type="sourcefile">app/+admin/users/user-list/user-list.component.html</context> 2349 <context context-type="sourcefile">app/+admin/users/user-list/user-list.component.html</context>
2105 <context context-type="linenumber">70</context> 2350 <context context-type="linenumber">72</context>
2106 </context-group> 2351 </context-group>
2107 </trans-unit><trans-unit id="79cee9973620b2592ff2824c525aa8ed0b5e2b8b" datatype="html"> 2352 </trans-unit><trans-unit id="79cee9973620b2592ff2824c525aa8ed0b5e2b8b" datatype="html">
2108 <source>User&apos;s email is verified / User can login without email verification</source> 2353 <source>User&apos;s email is verified / User can login without email verification</source>
2109 <context-group purpose="location"> 2354 <context-group purpose="location">
2110 <context context-type="sourcefile">app/+admin/users/user-list/user-list.component.html</context> 2355 <context context-type="sourcefile">app/+admin/users/user-list/user-list.component.html</context>
2111 <context context-type="linenumber">74</context> 2356 <context context-type="linenumber">76</context>
2112 </context-group> 2357 </context-group>
2113 </trans-unit><trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee" datatype="html"> 2358 </trans-unit><trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee" datatype="html">
2114 <source>Ban reason:</source> 2359 <source>Ban reason:</source>
2115 <context-group purpose="location"> 2360 <context-group purpose="location">
2116 <context context-type="sourcefile">app/+admin/users/user-list/user-list.component.html</context> 2361 <context context-type="sourcefile">app/+admin/users/user-list/user-list.component.html</context>
2117 <context context-type="linenumber">92</context> 2362 <context context-type="linenumber">95</context>
2118 </context-group> 2363 </context-group>
2119 </trans-unit><trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f" datatype="html"> 2364 </trans-unit><trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f" datatype="html">
2120 <source>Moderation comment</source> 2365 <source>Moderation comment</source>
@@ -2180,7 +2425,7 @@
2180 </context-group> 2425 </context-group>
2181 <context-group purpose="location"> 2426 <context-group purpose="location">
2182 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context> 2427 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context>
2183 <context context-type="linenumber">24</context> 2428 <context context-type="linenumber">25</context>
2184 </context-group> 2429 </context-group>
2185 <context-group purpose="location"> 2430 <context-group purpose="location">
2186 <context context-type="sourcefile">app/+my-account/my-account-ownership/my-account-ownership.component.html</context> 2431 <context context-type="sourcefile">app/+my-account/my-account-ownership/my-account-ownership.component.html</context>
@@ -2194,7 +2439,7 @@
2194 </context-group> 2439 </context-group>
2195 <context-group purpose="location"> 2440 <context-group purpose="location">
2196 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context> 2441 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context>
2197 <context context-type="linenumber">33</context> 2442 <context context-type="linenumber">35</context>
2198 </context-group> 2443 </context-group>
2199 </trans-unit><trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2" datatype="html"> 2444 </trans-unit><trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2" datatype="html">
2200 <source>Reason:</source> 2445 <source>Reason:</source>
@@ -2220,17 +2465,23 @@
2220 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context> 2465 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context>
2221 <context context-type="linenumber">9</context> 2466 <context context-type="linenumber">9</context>
2222 </context-group> 2467 </context-group>
2468 </trans-unit><trans-unit id="b748c96a1ee98d2fa9a645fb71838f5d4938855b" datatype="html">
2469 <source>Unfederated</source>
2470 <context-group purpose="location">
2471 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context>
2472 <context context-type="linenumber">10</context>
2473 </context-group>
2223 </trans-unit><trans-unit id="a7f42da3bb4eea0b71b0a20a2aff6612a82cab99" datatype="html"> 2474 </trans-unit><trans-unit id="a7f42da3bb4eea0b71b0a20a2aff6612a82cab99" datatype="html">
2224 <source>Date &lt;x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/&gt;&lt;x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/&gt;</source> 2475 <source>Date &lt;x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/&gt;&lt;x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/&gt;</source>
2225 <context-group purpose="location"> 2476 <context-group purpose="location">
2226 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context> 2477 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context>
2227 <context context-type="linenumber">10</context> 2478 <context context-type="linenumber">11</context>
2228 </context-group> 2479 </context-group>
2229 </trans-unit><trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f" datatype="html"> 2480 </trans-unit><trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f" datatype="html">
2230 <source>Blacklist reason:</source> 2481 <source>Blacklist reason:</source>
2231 <context-group purpose="location"> 2482 <context-group purpose="location">
2232 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context> 2483 <context context-type="sourcefile">app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html</context>
2233 <context context-type="linenumber">41</context> 2484 <context context-type="linenumber">43</context>
2234 </context-group> 2485 </context-group>
2235 </trans-unit><trans-unit id="90868353e7e6f5994109ee1011131cefa992116c" datatype="html"> 2486 </trans-unit><trans-unit id="90868353e7e6f5994109ee1011131cefa992116c" datatype="html">
2236 <source>Moderation</source> 2487 <source>Moderation</source>
@@ -2257,10 +2508,6 @@
2257 <context context-type="linenumber">9</context> 2508 <context context-type="linenumber">9</context>
2258 </context-group> 2509 </context-group>
2259 <context-group purpose="location"> 2510 <context-group purpose="location">
2260 <context context-type="sourcefile">app/+my-account/my-account.component.html</context>
2261 <context context-type="linenumber">29</context>
2262 </context-group>
2263 <context-group purpose="location">
2264 <context context-type="sourcefile">app/+my-account/my-account-blocklist/my-account-blocklist.component.html</context> 2511 <context context-type="sourcefile">app/+my-account/my-account-blocklist/my-account-blocklist.component.html</context>
2265 <context context-type="linenumber">2</context> 2512 <context context-type="linenumber">2</context>
2266 </context-group> 2513 </context-group>
@@ -2316,64 +2563,6 @@
2316 <context context-type="sourcefile">app/+my-account/my-account-blocklist/my-account-server-blocklist.component.html</context> 2563 <context context-type="sourcefile">app/+my-account/my-account-blocklist/my-account-server-blocklist.component.html</context>
2317 <context context-type="linenumber">23</context> 2564 <context context-type="linenumber">23</context>
2318 </context-group> 2565 </context-group>
2319 </trans-unit><trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6" datatype="html">
2320 <source>My settings</source>
2321 <context-group purpose="location">
2322 <context context-type="sourcefile">app/+my-account/my-account.component.html</context>
2323 <context context-type="linenumber">3</context>
2324 </context-group>
2325 </trans-unit><trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432" datatype="html">
2326 <source>My library</source>
2327 <context-group purpose="location">
2328 <context context-type="sourcefile">app/+my-account/my-account.component.html</context>
2329 <context context-type="linenumber">7</context>
2330 </context-group>
2331 </trans-unit><trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f" datatype="html">
2332 <source>My channels</source>
2333 <context-group purpose="location">
2334 <context context-type="sourcefile">app/+my-account/my-account.component.html</context>
2335 <context context-type="linenumber">12</context>
2336 </context-group>
2337 </trans-unit><trans-unit id="d02888c485d3aeab6de628508f4a00312a722894" datatype="html">
2338 <source>My videos</source>
2339 <context-group purpose="location">
2340 <context context-type="sourcefile">app/+my-account/my-account.component.html</context>
2341 <context context-type="linenumber">14</context>
2342 </context-group>
2343 </trans-unit><trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9" datatype="html">
2344 <source>My subscriptions</source>
2345 <context-group purpose="location">
2346 <context context-type="sourcefile">app/+my-account/my-account.component.html</context>
2347 <context context-type="linenumber">16</context>
2348 </context-group>
2349 </trans-unit><trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed" datatype="html">
2350 <source>My imports</source>
2351 <context-group purpose="location">
2352 <context context-type="sourcefile">app/+my-account/my-account.component.html</context>
2353 <context context-type="linenumber">18</context>
2354 </context-group>
2355 </trans-unit><trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029" datatype="html">
2356 <source>Misc</source>
2357 <context-group purpose="location">
2358 <context context-type="sourcefile">app/+my-account/my-account.component.html</context>
2359 <context context-type="linenumber">24</context>
2360 </context-group>
2361 </trans-unit><trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e" datatype="html">
2362 <source>Muted instances</source>
2363 <context-group purpose="location">
2364 <context context-type="sourcefile">app/+my-account/my-account.component.html</context>
2365 <context context-type="linenumber">31</context>
2366 </context-group>
2367 <context-group purpose="location">
2368 <context context-type="sourcefile">app/+my-account/my-account-blocklist/my-account-server-blocklist.component.html</context>
2369 <context context-type="linenumber">2</context>
2370 </context-group>
2371 </trans-unit><trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7" datatype="html">
2372 <source>Ownership changes</source>
2373 <context-group purpose="location">
2374 <context context-type="sourcefile">app/+my-account/my-account.component.html</context>
2375 <context context-type="linenumber">33</context>
2376 </context-group>
2377 </trans-unit><trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48" datatype="html"> 2566 </trans-unit><trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48" datatype="html">
2378 <source>Video quota:</source> 2567 <source>Video quota:</source>
2379 <context-group purpose="location"> 2568 <context-group purpose="location">
@@ -2384,19 +2573,19 @@
2384 <source>Profile</source> 2573 <source>Profile</source>
2385 <context-group purpose="location"> 2574 <context-group purpose="location">
2386 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-settings.component.html</context> 2575 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-settings.component.html</context>
2387 <context context-type="linenumber">8</context> 2576 <context context-type="linenumber">7</context>
2388 </context-group> 2577 </context-group>
2389 </trans-unit><trans-unit id="b5398623f87ee72ed23f5023918db1707771e925" datatype="html"> 2578 </trans-unit><trans-unit id="b5398623f87ee72ed23f5023918db1707771e925" datatype="html">
2390 <source>Video settings</source> 2579 <source>Video settings</source>
2391 <context-group purpose="location"> 2580 <context-group purpose="location">
2392 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-settings.component.html</context> 2581 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-settings.component.html</context>
2393 <context context-type="linenumber">15</context> 2582 <context context-type="linenumber">16</context>
2394 </context-group> 2583 </context-group>
2395 </trans-unit><trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735" datatype="html"> 2584 </trans-unit><trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735" datatype="html">
2396 <source>Danger zone</source> 2585 <source>Danger zone</source>
2397 <context-group purpose="location"> 2586 <context-group purpose="location">
2398 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-settings.component.html</context> 2587 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-settings.component.html</context>
2399 <context context-type="linenumber">18</context> 2588 <context context-type="linenumber">19</context>
2400 </context-group> 2589 </context-group>
2401 </trans-unit><trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf" datatype="html"> 2590 </trans-unit><trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf" datatype="html">
2402 <source>Change ownership</source> 2591 <source>Change ownership</source>
@@ -2430,24 +2619,6 @@
2430 <context context-type="sourcefile">app/videos/+video-edit/shared/video-caption-add-modal.component.html</context> 2619 <context context-type="sourcefile">app/videos/+video-edit/shared/video-caption-add-modal.component.html</context>
2431 <context context-type="linenumber">35</context> 2620 <context context-type="linenumber">35</context>
2432 </context-group> 2621 </context-group>
2433 </trans-unit><trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd" datatype="html">
2434 <source>Submit</source>
2435 <context-group purpose="location">
2436 <context context-type="sourcefile">app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html</context>
2437 <context context-type="linenumber">25</context>
2438 </context-group>
2439 <context-group purpose="location">
2440 <context context-type="sourcefile">app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.html</context>
2441 <context context-type="linenumber">28</context>
2442 </context-group>
2443 <context-group purpose="location">
2444 <context context-type="sourcefile">app/videos/+video-watch/modal/video-report.component.html</context>
2445 <context context-type="linenumber">24</context>
2446 </context-group>
2447 <context-group purpose="location">
2448 <context context-type="sourcefile">app/videos/+video-watch/modal/video-blacklist.component.html</context>
2449 <context context-type="linenumber">24</context>
2450 </context-group>
2451 </trans-unit><trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79" datatype="html"> 2622 </trans-unit><trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79" datatype="html">
2452 <source>&lt;x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/&gt; - &lt;x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/&gt; views</source> 2623 <source>&lt;x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/&gt; - &lt;x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/&gt; views</source>
2453 <context-group purpose="location"> 2624 <context-group purpose="location">
@@ -2612,6 +2783,48 @@ When you will upload a video in this channel, the video support field will be au
2612 <context context-type="sourcefile">app/+my-account/my-account-ownership/my-account-ownership.component.html</context> 2783 <context context-type="sourcefile">app/+my-account/my-account-ownership/my-account-ownership.component.html</context>
2613 <context context-type="linenumber">47</context> 2784 <context context-type="linenumber">47</context>
2614 </context-group> 2785 </context-group>
2786 </trans-unit><trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e" datatype="html">
2787 <source>Muted instances</source>
2788 <context-group purpose="location">
2789 <context context-type="sourcefile">app/+my-account/my-account-blocklist/my-account-server-blocklist.component.html</context>
2790 <context context-type="linenumber">2</context>
2791 </context-group>
2792 </trans-unit><trans-unit id="e8e93a7ae9a47c035bf5170b105c418b1deae530" datatype="html">
2793 <source>History enabled</source>
2794 <context-group purpose="location">
2795 <context context-type="sourcefile">app/+my-account/my-account-history/my-account-history.component.html</context>
2796 <context context-type="linenumber">4</context>
2797 </context-group>
2798 </trans-unit><trans-unit id="0f1fd6758625c6a39d796378d362cdcc2b092123" datatype="html">
2799 <source>Delete history</source>
2800 <context-group purpose="location">
2801 <context context-type="sourcefile">app/+my-account/my-account-history/my-account-history.component.html</context>
2802 <context context-type="linenumber">8</context>
2803 </context-group>
2804 </trans-unit><trans-unit id="6b4dc5732f1f2211833d4b5e76deb5985f3749af" datatype="html">
2805 <source>You don&apos;t have videos history yet.</source>
2806 <context-group purpose="location">
2807 <context context-type="sourcefile">app/+my-account/my-account-history/my-account-history.component.html</context>
2808 <context context-type="linenumber">13</context>
2809 </context-group>
2810 </trans-unit><trans-unit id="6aec8cb024acc333218d72f279caa8ea623bb628" datatype="html">
2811 <source>&lt;x id="INTERPOLATION" equiv-text="{{ video.views | myNumberFormatter }}"/&gt; views</source>
2812 <context-group purpose="location">
2813 <context context-type="sourcefile">app/+my-account/my-account-history/my-account-history.component.html</context>
2814 <context context-type="linenumber">22</context>
2815 </context-group>
2816 </trans-unit><trans-unit id="3a6903ba6b8cf2d828d0c86fd1feb09a27be4105" datatype="html">
2817 <source>Notification preferences</source>
2818 <context-group purpose="location">
2819 <context context-type="sourcefile">app/+my-account/my-account-notifications/my-account-notifications.component.html</context>
2820 <context context-type="linenumber">2</context>
2821 </context-group>
2822 </trans-unit><trans-unit id="1da23f4068fd3796fbcb24d0c42bb62f92c96829" datatype="html">
2823 <source>Mark all as read</source>
2824 <context-group purpose="location">
2825 <context context-type="sourcefile">app/+my-account/my-account-notifications/my-account-notifications.component.html</context>
2826 <context context-type="linenumber">4</context>
2827 </context-group>
2615 </trans-unit><trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html"> 2828 </trans-unit><trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9" datatype="html">
2616 <source>Change password</source> 2829 <source>Change password</source>
2617 <context-group purpose="location"> 2830 <context-group purpose="location">
@@ -2700,6 +2913,18 @@ When you will upload a video in this channel, the video support field will be au
2700 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.html</context> 2913 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.html</context>
2701 <context context-type="linenumber">4</context> 2914 <context context-type="linenumber">4</context>
2702 </context-group> 2915 </context-group>
2916 </trans-unit><trans-unit id="dd3b6c367381ddfa8f317b8e9b31c55368c65136" datatype="html">
2917 <source>Activities</source>
2918 <context-group purpose="location">
2919 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html</context>
2920 <context context-type="linenumber">2</context>
2921 </context-group>
2922 </trans-unit><trans-unit id="847dffd493abbb2a5c71f3313f0eb730dd88a355" datatype="html">
2923 <source>Web</source>
2924 <context-group purpose="location">
2925 <context context-type="sourcefile">app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html</context>
2926 <context context-type="linenumber">3</context>
2927 </context-group>
2703 </trans-unit><trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd" datatype="html"> 2928 </trans-unit><trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd" datatype="html">
2704 <source> 2929 <source>
2705 Sorry, but we couldn&apos;t find the page you were looking for. 2930 Sorry, but we couldn&apos;t find the page you were looking for.
@@ -2870,17 +3095,25 @@ When you will upload a video in this channel, the video support field will be au
2870 <context context-type="sourcefile">app/videos/+video-edit/video-add-components/video-upload.component.html</context> 3095 <context context-type="sourcefile">app/videos/+video-edit/video-add-components/video-upload.component.html</context>
2871 <context context-type="linenumber">25</context> 3096 <context context-type="linenumber">25</context>
2872 </context-group> 3097 </context-group>
3098 </trans-unit><trans-unit id="6357683911e256c566259880de43ea9403de00d3" datatype="html">
3099 <source>
3100 Congratulations! Your video is now available in your private library.
3101</source>
3102 <context-group purpose="location">
3103 <context context-type="sourcefile">app/videos/+video-edit/video-add-components/video-upload.component.html</context>
3104 <context context-type="linenumber">45</context>
3105 </context-group>
2873 </trans-unit><trans-unit id="f7ac2376749c7985f94f0fc89ba75ea624de1215" datatype="html"> 3106 </trans-unit><trans-unit id="f7ac2376749c7985f94f0fc89ba75ea624de1215" datatype="html">
2874 <source>Publish will be available when upload is finished</source> 3107 <source>Publish will be available when upload is finished</source>
2875 <context-group purpose="location"> 3108 <context-group purpose="location">
2876 <context context-type="sourcefile">app/videos/+video-edit/video-add-components/video-upload.component.html</context> 3109 <context context-type="sourcefile">app/videos/+video-edit/video-add-components/video-upload.component.html</context>
2877 <context context-type="linenumber">53</context> 3110 <context context-type="linenumber">58</context>
2878 </context-group> 3111 </context-group>
2879 </trans-unit><trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3" datatype="html"> 3112 </trans-unit><trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3" datatype="html">
2880 <source>Publish</source> 3113 <source>Publish</source>
2881 <context-group purpose="location"> 3114 <context-group purpose="location">
2882 <context context-type="sourcefile">app/videos/+video-edit/video-add-components/video-upload.component.html</context> 3115 <context context-type="sourcefile">app/videos/+video-edit/video-add-components/video-upload.component.html</context>
2883 <context context-type="linenumber">60</context> 3116 <context context-type="linenumber">65</context>
2884 </context-group> 3117 </context-group>
2885 </trans-unit><trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b" datatype="html"> 3118 </trans-unit><trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b" datatype="html">
2886 <source>Select the torrent to import</source> 3119 <source>Select the torrent to import</source>
@@ -3038,13 +3271,13 @@ When you will upload a video in this channel, the video support field will be au
3038 <source>Wait transcoding before publishing the video</source> 3271 <source>Wait transcoding before publishing the video</source>
3039 <context-group purpose="location"> 3272 <context-group purpose="location">
3040 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3273 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3041 <context context-type="linenumber">130</context> 3274 <context context-type="linenumber">131</context>
3042 </context-group> 3275 </context-group>
3043 </trans-unit><trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63" datatype="html"> 3276 </trans-unit><trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63" datatype="html">
3044 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 3277 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
3045 <context-group purpose="location"> 3278 <context-group purpose="location">
3046 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3279 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3047 <context context-type="linenumber">131</context> 3280 <context context-type="linenumber">132</context>
3048 </context-group> 3281 </context-group>
3049 </trans-unit><trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7" datatype="html"> 3282 </trans-unit><trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7" datatype="html">
3050 <source>Basic info</source> 3283 <source>Basic info</source>
@@ -3056,43 +3289,43 @@ When you will upload a video in this channel, the video support field will be au
3056 <source>Add another caption</source> 3289 <source>Add another caption</source>
3057 <context-group purpose="location"> 3290 <context-group purpose="location">
3058 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3291 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3059 <context context-type="linenumber">146</context> 3292 <context context-type="linenumber">147</context>
3060 </context-group> 3293 </context-group>
3061 </trans-unit><trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed" datatype="html"> 3294 </trans-unit><trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed" datatype="html">
3062 <source>See the subtitle file</source> 3295 <source>See the subtitle file</source>
3063 <context-group purpose="location"> 3296 <context-group purpose="location">
3064 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3297 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3065 <context context-type="linenumber">155</context> 3298 <context context-type="linenumber">156</context>
3066 </context-group> 3299 </context-group>
3067 </trans-unit><trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee" datatype="html"> 3300 </trans-unit><trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee" datatype="html">
3068 <source>Already uploaded ✔</source> 3301 <source>Already uploaded ✔</source>
3069 <context-group purpose="location"> 3302 <context-group purpose="location">
3070 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3303 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3071 <context context-type="linenumber">159</context> 3304 <context context-type="linenumber">160</context>
3072 </context-group> 3305 </context-group>
3073 </trans-unit><trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad" datatype="html"> 3306 </trans-unit><trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad" datatype="html">
3074 <source>Will be created on update</source> 3307 <source>Will be created on update</source>
3075 <context-group purpose="location"> 3308 <context-group purpose="location">
3076 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3309 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3077 <context context-type="linenumber">167</context> 3310 <context context-type="linenumber">168</context>
3078 </context-group> 3311 </context-group>
3079 </trans-unit><trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9" datatype="html"> 3312 </trans-unit><trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9" datatype="html">
3080 <source>Cancel create</source> 3313 <source>Cancel create</source>
3081 <context-group purpose="location"> 3314 <context-group purpose="location">
3082 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3315 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3083 <context context-type="linenumber">169</context> 3316 <context context-type="linenumber">170</context>
3084 </context-group> 3317 </context-group>
3085 </trans-unit><trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393" datatype="html"> 3318 </trans-unit><trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393" datatype="html">
3086 <source>Will be deleted on update</source> 3319 <source>Will be deleted on update</source>
3087 <context-group purpose="location"> 3320 <context-group purpose="location">
3088 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3321 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3089 <context context-type="linenumber">175</context> 3322 <context context-type="linenumber">176</context>
3090 </context-group> 3323 </context-group>
3091 </trans-unit><trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c" datatype="html"> 3324 </trans-unit><trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c" datatype="html">
3092 <source>Cancel deletion</source> 3325 <source>Cancel deletion</source>
3093 <context-group purpose="location"> 3326 <context-group purpose="location">
3094 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3327 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3095 <context context-type="linenumber">177</context> 3328 <context context-type="linenumber">178</context>
3096 </context-group> 3329 </context-group>
3097 </trans-unit><trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0" datatype="html"> 3330 </trans-unit><trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0" datatype="html">
3098 <source> 3331 <source>
@@ -3100,31 +3333,31 @@ When you will upload a video in this channel, the video support field will be au
3100 </source> 3333 </source>
3101 <context-group purpose="location"> 3334 <context-group purpose="location">
3102 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3335 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3103 <context context-type="linenumber">182</context> 3336 <context context-type="linenumber">183</context>
3104 </context-group> 3337 </context-group>
3105 </trans-unit><trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93" datatype="html"> 3338 </trans-unit><trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93" datatype="html">
3106 <source>Captions</source> 3339 <source>Captions</source>
3107 <context-group purpose="location"> 3340 <context-group purpose="location">
3108 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3341 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3109 <context context-type="linenumber">139</context> 3342 <context context-type="linenumber">140</context>
3110 </context-group> 3343 </context-group>
3111 </trans-unit><trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513" datatype="html"> 3344 </trans-unit><trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513" datatype="html">
3112 <source>Upload thumbnail</source> 3345 <source>Upload thumbnail</source>
3113 <context-group purpose="location"> 3346 <context-group purpose="location">
3114 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3347 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3115 <context context-type="linenumber">195</context> 3348 <context context-type="linenumber">196</context>
3116 </context-group> 3349 </context-group>
3117 </trans-unit><trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639" datatype="html"> 3350 </trans-unit><trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639" datatype="html">
3118 <source>Upload preview</source> 3351 <source>Upload preview</source>
3119 <context-group purpose="location"> 3352 <context-group purpose="location">
3120 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3353 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3121 <context context-type="linenumber">202</context> 3354 <context context-type="linenumber">203</context>
3122 </context-group> 3355 </context-group>
3123 </trans-unit><trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604" datatype="html"> 3356 </trans-unit><trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604" datatype="html">
3124 <source>Support</source> 3357 <source>Support</source>
3125 <context-group purpose="location"> 3358 <context-group purpose="location">
3126 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3359 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3127 <context context-type="linenumber">208</context> 3360 <context context-type="linenumber">209</context>
3128 </context-group> 3361 </context-group>
3129 <context-group purpose="location"> 3362 <context-group purpose="location">
3130 <context context-type="sourcefile">app/videos/+video-watch/modal/video-support.component.html</context> 3363 <context context-type="sourcefile">app/videos/+video-watch/modal/video-support.component.html</context>
@@ -3138,13 +3371,13 @@ When you will upload a video in this channel, the video support field will be au
3138 <source>Short text to tell people how they can support you (membership platform...).</source> 3371 <source>Short text to tell people how they can support you (membership platform...).</source>
3139 <context-group purpose="location"> 3372 <context-group purpose="location">
3140 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3373 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3141 <context context-type="linenumber">209</context> 3374 <context context-type="linenumber">210</context>
3142 </context-group> 3375 </context-group>
3143 </trans-unit><trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1" datatype="html"> 3376 </trans-unit><trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1" datatype="html">
3144 <source>Advanced settings</source> 3377 <source>Advanced settings</source>
3145 <context-group purpose="location"> 3378 <context-group purpose="location">
3146 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context> 3379 <context context-type="sourcefile">app/videos/+video-edit/shared/video-edit.component.html</context>
3147 <context context-type="linenumber">190</context> 3380 <context context-type="linenumber">191</context>
3148 </context-group> 3381 </context-group>
3149 </trans-unit><trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0" datatype="html"> 3382 </trans-unit><trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0" datatype="html">
3150 <source> 3383 <source>
@@ -3206,17 +3439,14 @@ When you will upload a video in this channel, the video support field will be au
3206 <context context-type="sourcefile">app/videos/+video-watch/modal/video-report.component.html</context> 3439 <context context-type="sourcefile">app/videos/+video-watch/modal/video-report.component.html</context>
3207 <context context-type="linenumber">3</context> 3440 <context context-type="linenumber">3</context>
3208 </context-group> 3441 </context-group>
3209 </trans-unit><trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb" datatype="html"> 3442 </trans-unit><trans-unit id="827b1376aa35c7a7de90f7724d6a51ccfa20c908" datatype="html">
3210 <source> 3443 <source>
3211 Cancel 3444 Your report will be sent to moderators of &lt;x id="INTERPOLATION" equiv-text="{{ currentHost }}"/&gt;.
3212 </source> 3445 &lt;x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/&gt; It will be forwarded to origin instance &lt;x id="INTERPOLATION_1" equiv-text="{{ originHost }}"/&gt; too.&lt;x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/&gt;
3446 </source>
3213 <context-group purpose="location"> 3447 <context-group purpose="location">
3214 <context context-type="sourcefile">app/videos/+video-watch/modal/video-report.component.html</context> 3448 <context context-type="sourcefile">app/videos/+video-watch/modal/video-report.component.html</context>
3215 <context context-type="linenumber">19</context> 3449 <context context-type="linenumber">9</context>
3216 </context-group>
3217 <context-group purpose="location">
3218 <context context-type="sourcefile">app/videos/+video-watch/modal/video-blacklist.component.html</context>
3219 <context context-type="linenumber">19</context>
3220 </context-group> 3450 </context-group>
3221 </trans-unit><trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9" datatype="html"> 3451 </trans-unit><trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9" datatype="html">
3222 <source>Share</source> 3452 <source>Share</source>
@@ -3260,6 +3490,12 @@ When you will upload a video in this channel, the video support field will be au
3260 <context context-type="sourcefile">app/videos/+video-watch/modal/video-blacklist.component.html</context> 3490 <context context-type="sourcefile">app/videos/+video-watch/modal/video-blacklist.component.html</context>
3261 <context context-type="linenumber">3</context> 3491 <context context-type="linenumber">3</context>
3262 </context-group> 3492 </context-group>
3493 </trans-unit><trans-unit id="9849bf6a9e45a9a91d13a419afbb5176f9b2367d" datatype="html">
3494 <source>Unfederate the video (ask for its deletion from the remote instances)</source>
3495 <context-group purpose="location">
3496 <context context-type="sourcefile">app/videos/+video-watch/modal/video-blacklist.component.html</context>
3497 <context context-type="linenumber">21</context>
3498 </context-group>
3263 </trans-unit><trans-unit id="7584313e33a66811eb10646627914a01fff0347d" datatype="html"> 3499 </trans-unit><trans-unit id="7584313e33a66811eb10646627914a01fff0347d" datatype="html">
3264 <source> 3500 <source>
3265 The video is being imported, it will be available when the import is finished. 3501 The video is being imported, it will be available when the import is finished.
@@ -3531,13 +3767,27 @@ When you will upload a video in this channel, the video support field will be au
3531 <context context-type="linenumber">14</context> 3767 <context context-type="linenumber">14</context>
3532 </context-group> 3768 </context-group>
3533 </trans-unit> 3769 </trans-unit>
3534 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08" datatype="html"> 3770 <trans-unit id="e0e3a472479c8ce1b78f682ffadbe59daf04d331" datatype="html">
3535 <source>Error getting about from server</source> 3771 <source>Cannot get about information from server</source>
3536 <context-group purpose="location"> 3772 <context-group purpose="location">
3537 <context context-type="sourcefile">src/app/+about/about-instance/about-instance.component.ts</context> 3773 <context context-type="sourcefile">src/app/+about/about-instance/about-instance.component.ts</context>
3538 <context context-type="linenumber">1</context> 3774 <context context-type="linenumber">1</context>
3539 </context-group> 3775 </context-group>
3540 </trans-unit> 3776 </trans-unit>
3777 <trans-unit id="9e601a3b227bb70afbb9b59cd43547b710af1e10" datatype="html">
3778 <source>Your message has been sent.</source>
3779 <context-group purpose="location">
3780 <context context-type="sourcefile">src/app/+about/about-instance/contact-admin-modal.component.ts</context>
3781 <context context-type="linenumber">1</context>
3782 </context-group>
3783 </trans-unit>
3784 <trans-unit id="8d6d4f48dae547bb32e0669cda5a665dc8db536c" datatype="html">
3785 <source>You already sent this form recently</source>
3786 <context-group purpose="location">
3787 <context context-type="sourcefile">src/app/+about/about-instance/contact-admin-modal.component.ts</context>
3788 <context context-type="linenumber">1</context>
3789 </context-group>
3790 </trans-unit>
3541 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968" datatype="html"> 3791 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968" datatype="html">
3542 <source>No description</source> 3792 <source>No description</source>
3543 <context-group purpose="location"> 3793 <context-group purpose="location">
@@ -3571,345 +3821,6 @@ When you will upload a video in this channel, the video support field will be au
3571 <context context-type="linenumber">1</context> 3821 <context context-type="linenumber">1</context>
3572 </context-group> 3822 </context-group>
3573 </trans-unit> 3823 </trans-unit>
3574 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d" datatype="html">
3575 <source>Error</source>
3576 <context-group purpose="location">
3577 <context context-type="sourcefile">src/app/+accounts/accounts.component.ts</context>
3578 <context context-type="linenumber">1</context>
3579 </context-group>
3580 <context-group purpose="location">
3581 <context context-type="sourcefile">src/app/+accounts/accounts.component.ts</context>
3582 <context context-type="linenumber">1</context>
3583 </context-group>
3584 <context-group purpose="location">
3585 <context context-type="sourcefile">src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context>
3586 <context context-type="linenumber">1</context>
3587 </context-group>
3588 <context-group purpose="location">
3589 <context context-type="sourcefile">src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context>
3590 <context context-type="linenumber">1</context>
3591 </context-group>
3592 <context-group purpose="location">
3593 <context context-type="sourcefile">src/app/+admin/follows/followers-list/followers-list.component.ts</context>
3594 <context context-type="linenumber">1</context>
3595 </context-group>
3596 <context-group purpose="location">
3597 <context context-type="sourcefile">src/app/+admin/follows/following-add/following-add.component.ts</context>
3598 <context context-type="linenumber">1</context>
3599 </context-group>
3600 <context-group purpose="location">
3601 <context context-type="sourcefile">src/app/+admin/follows/following-list/following-list.component.ts</context>
3602 <context context-type="linenumber">1</context>
3603 </context-group>
3604 <context-group purpose="location">
3605 <context context-type="sourcefile">src/app/+admin/follows/following-list/following-list.component.ts</context>
3606 <context context-type="linenumber">1</context>
3607 </context-group>
3608 <context-group purpose="location">
3609 <context context-type="sourcefile">src/app/+admin/follows/shared/redundancy-checkbox.component.ts</context>
3610 <context context-type="linenumber">1</context>
3611 </context-group>
3612 <context-group purpose="location">
3613 <context context-type="sourcefile">src/app/+admin/jobs/jobs-list/jobs-list.component.ts</context>
3614 <context context-type="linenumber">1</context>
3615 </context-group>
3616 <context-group purpose="location">
3617 <context context-type="sourcefile">src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts</context>
3618 <context context-type="linenumber">1</context>
3619 </context-group>
3620 <context-group purpose="location">
3621 <context context-type="sourcefile">src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts</context>
3622 <context context-type="linenumber">1</context>
3623 </context-group>
3624 <context-group purpose="location">
3625 <context context-type="sourcefile">src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts</context>
3626 <context context-type="linenumber">1</context>
3627 </context-group>
3628 <context-group purpose="location">
3629 <context context-type="sourcefile">src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts</context>
3630 <context context-type="linenumber">1</context>
3631 </context-group>
3632 <context-group purpose="location">
3633 <context context-type="sourcefile">src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts</context>
3634 <context context-type="linenumber">1</context>
3635 </context-group>
3636 <context-group purpose="location">
3637 <context context-type="sourcefile">src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts</context>
3638 <context context-type="linenumber">1</context>
3639 </context-group>
3640 <context-group purpose="location">
3641 <context context-type="sourcefile">src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts</context>
3642 <context context-type="linenumber">1</context>
3643 </context-group>
3644 <context-group purpose="location">
3645 <context context-type="sourcefile">src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts</context>
3646 <context context-type="linenumber">1</context>
3647 </context-group>
3648 <context-group purpose="location">
3649 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context>
3650 <context context-type="linenumber">1</context>
3651 </context-group>
3652 <context-group purpose="location">
3653 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context>
3654 <context context-type="linenumber">1</context>
3655 </context-group>
3656 <context-group purpose="location">
3657 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context>
3658 <context context-type="linenumber">1</context>
3659 </context-group>
3660 <context-group purpose="location">
3661 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context>
3662 <context context-type="linenumber">1</context>
3663 </context-group>
3664 <context-group purpose="location">
3665 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context>
3666 <context context-type="linenumber">1</context>
3667 </context-group>
3668 <context-group purpose="location">
3669 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context>
3670 <context context-type="linenumber">1</context>
3671 </context-group>
3672 <context-group purpose="location">
3673 <context context-type="sourcefile">src/app/+my-account/my-account-blocklist/my-account-blocklist.component.ts</context>
3674 <context context-type="linenumber">1</context>
3675 </context-group>
3676 <context-group purpose="location">
3677 <context context-type="sourcefile">src/app/+my-account/my-account-blocklist/my-account-server-blocklist.component.ts</context>
3678 <context context-type="linenumber">1</context>
3679 </context-group>
3680 <context-group purpose="location">
3681 <context context-type="sourcefile">src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts</context>
3682 <context context-type="linenumber">1</context>
3683 </context-group>
3684 <context-group purpose="location">
3685 <context context-type="sourcefile">src/app/+my-account/my-account-ownership/my-account-ownership.component.ts</context>
3686 <context context-type="linenumber">1</context>
3687 </context-group>
3688 <context-group purpose="location">
3689 <context context-type="sourcefile">src/app/+my-account/my-account-ownership/my-account-ownership.component.ts</context>
3690 <context context-type="linenumber">1</context>
3691 </context-group>
3692 <context-group purpose="location">
3693 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts</context>
3694 <context context-type="linenumber">1</context>
3695 </context-group>
3696 <context-group purpose="location">
3697 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-settings.component.ts</context>
3698 <context context-type="linenumber">1</context>
3699 </context-group>
3700 <context-group purpose="location">
3701 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts</context>
3702 <context context-type="linenumber">1</context>
3703 </context-group>
3704 <context-group purpose="location">
3705 <context context-type="sourcefile">src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts</context>
3706 <context context-type="linenumber">1</context>
3707 </context-group>
3708 <context-group purpose="location">
3709 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts</context>
3710 <context context-type="linenumber">1</context>
3711 </context-group>
3712 <context-group purpose="location">
3713 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context>
3714 <context context-type="linenumber">1</context>
3715 </context-group>
3716 <context-group purpose="location">
3717 <context context-type="sourcefile">src/app/+my-account/my-account-video-imports/my-account-video-imports.component.ts</context>
3718 <context context-type="linenumber">1</context>
3719 </context-group>
3720 <context-group purpose="location">
3721 <context context-type="sourcefile">src/app/+my-account/my-account-videos/my-account-videos.component.ts</context>
3722 <context context-type="linenumber">1</context>
3723 </context-group>
3724 <context-group purpose="location">
3725 <context context-type="sourcefile">src/app/+my-account/my-account-videos/my-account-videos.component.ts</context>
3726 <context context-type="linenumber">1</context>
3727 </context-group>
3728 <context-group purpose="location">
3729 <context context-type="sourcefile">src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts</context>
3730 <context context-type="linenumber">1</context>
3731 </context-group>
3732 <context-group purpose="location">
3733 <context context-type="sourcefile">src/app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts</context>
3734 <context context-type="linenumber">1</context>
3735 </context-group>
3736 <context-group purpose="location">
3737 <context context-type="sourcefile">src/app/+verify-account/verify-account-email/verify-account-email.component.ts</context>
3738 <context context-type="linenumber">1</context>
3739 </context-group>
3740 <context-group purpose="location">
3741 <context context-type="sourcefile">src/app/+verify-account/verify-account-email/verify-account-email.component.ts</context>
3742 <context context-type="linenumber">1</context>
3743 </context-group>
3744 <context-group purpose="location">
3745 <context context-type="sourcefile">src/app/core/auth/auth.service.ts</context>
3746 <context context-type="linenumber">1</context>
3747 </context-group>
3748 <context-group purpose="location">
3749 <context context-type="sourcefile">src/app/login/login.component.ts</context>
3750 <context context-type="linenumber">1</context>
3751 </context-group>
3752 <context-group purpose="location">
3753 <context context-type="sourcefile">src/app/reset-password/reset-password.component.ts</context>
3754 <context context-type="linenumber">1</context>
3755 </context-group>
3756 <context-group purpose="location">
3757 <context context-type="sourcefile">src/app/search/search.component.ts</context>
3758 <context context-type="linenumber">1</context>
3759 </context-group>
3760 <context-group purpose="location">
3761 <context context-type="sourcefile">src/app/shared/forms/reactive-file.component.ts</context>
3762 <context context-type="linenumber">1</context>
3763 </context-group>
3764 <context-group purpose="location">
3765 <context context-type="sourcefile">src/app/shared/moderation/user-ban-modal.component.ts</context>
3766 <context context-type="linenumber">1</context>
3767 </context-group>
3768 <context-group purpose="location">
3769 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3770 <context context-type="linenumber">1</context>
3771 </context-group>
3772 <context-group purpose="location">
3773 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3774 <context context-type="linenumber">1</context>
3775 </context-group>
3776 <context-group purpose="location">
3777 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3778 <context context-type="linenumber">1</context>
3779 </context-group>
3780 <context-group purpose="location">
3781 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3782 <context context-type="linenumber">1</context>
3783 </context-group>
3784 <context-group purpose="location">
3785 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3786 <context context-type="linenumber">1</context>
3787 </context-group>
3788 <context-group purpose="location">
3789 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3790 <context context-type="linenumber">1</context>
3791 </context-group>
3792 <context-group purpose="location">
3793 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3794 <context context-type="linenumber">1</context>
3795 </context-group>
3796 <context-group purpose="location">
3797 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3798 <context context-type="linenumber">1</context>
3799 </context-group>
3800 <context-group purpose="location">
3801 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3802 <context context-type="linenumber">1</context>
3803 </context-group>
3804 <context-group purpose="location">
3805 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3806 <context context-type="linenumber">1</context>
3807 </context-group>
3808 <context-group purpose="location">
3809 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3810 <context context-type="linenumber">1</context>
3811 </context-group>
3812 <context-group purpose="location">
3813 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3814 <context context-type="linenumber">1</context>
3815 </context-group>
3816 <context-group purpose="location">
3817 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
3818 <context context-type="linenumber">1</context>
3819 </context-group>
3820 <context-group purpose="location">
3821 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context>
3822 <context context-type="linenumber">1</context>
3823 </context-group>
3824 <context-group purpose="location">
3825 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context>
3826 <context context-type="linenumber">1</context>
3827 </context-group>
3828 <context-group purpose="location">
3829 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context>
3830 <context context-type="linenumber">1</context>
3831 </context-group>
3832 <context-group purpose="location">
3833 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts</context>
3834 <context context-type="linenumber">1</context>
3835 </context-group>
3836 <context-group purpose="location">
3837 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-import-url.component.ts</context>
3838 <context context-type="linenumber">1</context>
3839 </context-group>
3840 <context-group purpose="location">
3841 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-upload.component.ts</context>
3842 <context context-type="linenumber">1</context>
3843 </context-group>
3844 <context-group purpose="location">
3845 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-upload.component.ts</context>
3846 <context context-type="linenumber">1</context>
3847 </context-group>
3848 <context-group purpose="location">
3849 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-upload.component.ts</context>
3850 <context context-type="linenumber">1</context>
3851 </context-group>
3852 <context-group purpose="location">
3853 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-upload.component.ts</context>
3854 <context context-type="linenumber">1</context>
3855 </context-group>
3856 <context-group purpose="location">
3857 <context context-type="sourcefile">src/app/videos/+video-edit/video-update.component.ts</context>
3858 <context context-type="linenumber">1</context>
3859 </context-group>
3860 <context-group purpose="location">
3861 <context context-type="sourcefile">src/app/videos/+video-edit/video-update.component.ts</context>
3862 <context context-type="linenumber">1</context>
3863 </context-group>
3864 <context-group purpose="location">
3865 <context context-type="sourcefile">src/app/videos/+video-watch/comment/video-comment-add.component.ts</context>
3866 <context context-type="linenumber">1</context>
3867 </context-group>
3868 <context-group purpose="location">
3869 <context context-type="sourcefile">src/app/videos/+video-watch/comment/video-comments.component.ts</context>
3870 <context context-type="linenumber">1</context>
3871 </context-group>
3872 <context-group purpose="location">
3873 <context context-type="sourcefile">src/app/videos/+video-watch/comment/video-comments.component.ts</context>
3874 <context context-type="linenumber">1</context>
3875 </context-group>
3876 <context-group purpose="location">
3877 <context context-type="sourcefile">src/app/videos/+video-watch/comment/video-comments.component.ts</context>
3878 <context context-type="linenumber">1</context>
3879 </context-group>
3880 <context-group purpose="location">
3881 <context context-type="sourcefile">src/app/videos/+video-watch/modal/video-blacklist.component.ts</context>
3882 <context context-type="linenumber">1</context>
3883 </context-group>
3884 <context-group purpose="location">
3885 <context context-type="sourcefile">src/app/videos/+video-watch/modal/video-report.component.ts</context>
3886 <context context-type="linenumber">1</context>
3887 </context-group>
3888 <context-group purpose="location">
3889 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
3890 <context context-type="linenumber">1</context>
3891 </context-group>
3892 <context-group purpose="location">
3893 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
3894 <context context-type="linenumber">1</context>
3895 </context-group>
3896 <context-group purpose="location">
3897 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
3898 <context context-type="linenumber">1</context>
3899 </context-group>
3900 <context-group purpose="location">
3901 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
3902 <context context-type="linenumber">1</context>
3903 </context-group>
3904 <context-group purpose="location">
3905 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
3906 <context context-type="linenumber">1</context>
3907 </context-group>
3908 <context-group purpose="location">
3909 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
3910 <context context-type="linenumber">1</context>
3911 </context-group>
3912 </trans-unit>
3913 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6" datatype="html"> 3824 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6" datatype="html">
3914 <source>240p</source> 3825 <source>240p</source>
3915 <context-group purpose="location"> 3826 <context-group purpose="location">
@@ -3952,229 +3863,6 @@ When you will upload a video in this channel, the video support field will be au
3952 <context context-type="linenumber">1</context> 3863 <context context-type="linenumber">1</context>
3953 </context-group> 3864 </context-group>
3954 </trans-unit> 3865 </trans-unit>
3955 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba" datatype="html">
3956 <source>Success</source>
3957 <context-group purpose="location">
3958 <context context-type="sourcefile">src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts</context>
3959 <context context-type="linenumber">1</context>
3960 </context-group>
3961 <context-group purpose="location">
3962 <context context-type="sourcefile">src/app/+admin/follows/following-add/following-add.component.ts</context>
3963 <context context-type="linenumber">1</context>
3964 </context-group>
3965 <context-group purpose="location">
3966 <context context-type="sourcefile">src/app/+admin/follows/following-list/following-list.component.ts</context>
3967 <context context-type="linenumber">1</context>
3968 </context-group>
3969 <context-group purpose="location">
3970 <context context-type="sourcefile">src/app/+admin/follows/shared/redundancy-checkbox.component.ts</context>
3971 <context context-type="linenumber">1</context>
3972 </context-group>
3973 <context-group purpose="location">
3974 <context context-type="sourcefile">src/app/+admin/moderation/instance-blocklist/instance-account-blocklist.component.ts</context>
3975 <context context-type="linenumber">1</context>
3976 </context-group>
3977 <context-group purpose="location">
3978 <context context-type="sourcefile">src/app/+admin/moderation/instance-blocklist/instance-server-blocklist.component.ts</context>
3979 <context context-type="linenumber">1</context>
3980 </context-group>
3981 <context-group purpose="location">
3982 <context context-type="sourcefile">src/app/+admin/moderation/video-abuse-list/moderation-comment-modal.component.ts</context>
3983 <context context-type="linenumber">1</context>
3984 </context-group>
3985 <context-group purpose="location">
3986 <context context-type="sourcefile">src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts</context>
3987 <context context-type="linenumber">1</context>
3988 </context-group>
3989 <context-group purpose="location">
3990 <context context-type="sourcefile">src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts</context>
3991 <context context-type="linenumber">1</context>
3992 </context-group>
3993 <context-group purpose="location">
3994 <context context-type="sourcefile">src/app/+admin/users/user-edit/user-create.component.ts</context>
3995 <context context-type="linenumber">1</context>
3996 </context-group>
3997 <context-group purpose="location">
3998 <context context-type="sourcefile">src/app/+admin/users/user-edit/user-update.component.ts</context>
3999 <context context-type="linenumber">1</context>
4000 </context-group>
4001 <context-group purpose="location">
4002 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context>
4003 <context context-type="linenumber">1</context>
4004 </context-group>
4005 <context-group purpose="location">
4006 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context>
4007 <context context-type="linenumber">1</context>
4008 </context-group>
4009 <context-group purpose="location">
4010 <context context-type="sourcefile">src/app/+admin/users/user-list/user-list.component.ts</context>
4011 <context context-type="linenumber">1</context>
4012 </context-group>
4013 <context-group purpose="location">
4014 <context context-type="sourcefile">src/app/+my-account/my-account-blocklist/my-account-blocklist.component.ts</context>
4015 <context context-type="linenumber">1</context>
4016 </context-group>
4017 <context-group purpose="location">
4018 <context context-type="sourcefile">src/app/+my-account/my-account-blocklist/my-account-server-blocklist.component.ts</context>
4019 <context context-type="linenumber">1</context>
4020 </context-group>
4021 <context-group purpose="location">
4022 <context context-type="sourcefile">src/app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component.ts</context>
4023 <context context-type="linenumber">1</context>
4024 </context-group>
4025 <context-group purpose="location">
4026 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts</context>
4027 <context context-type="linenumber">1</context>
4028 </context-group>
4029 <context-group purpose="location">
4030 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts</context>
4031 <context context-type="linenumber">1</context>
4032 </context-group>
4033 <context-group purpose="location">
4034 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-profile/my-account-profile.component.ts</context>
4035 <context context-type="linenumber">1</context>
4036 </context-group>
4037 <context-group purpose="location">
4038 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-settings.component.ts</context>
4039 <context context-type="linenumber">1</context>
4040 </context-group>
4041 <context-group purpose="location">
4042 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts</context>
4043 <context context-type="linenumber">1</context>
4044 </context-group>
4045 <context-group purpose="location">
4046 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channel-create.component.ts</context>
4047 <context context-type="linenumber">1</context>
4048 </context-group>
4049 <context-group purpose="location">
4050 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts</context>
4051 <context context-type="linenumber">1</context>
4052 </context-group>
4053 <context-group purpose="location">
4054 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts</context>
4055 <context context-type="linenumber">1</context>
4056 </context-group>
4057 <context-group purpose="location">
4058 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context>
4059 <context context-type="linenumber">1</context>
4060 </context-group>
4061 <context-group purpose="location">
4062 <context context-type="sourcefile">src/app/+my-account/my-account-videos/my-account-videos.component.ts</context>
4063 <context context-type="linenumber">1</context>
4064 </context-group>
4065 <context-group purpose="location">
4066 <context context-type="sourcefile">src/app/+my-account/my-account-videos/my-account-videos.component.ts</context>
4067 <context context-type="linenumber">1</context>
4068 </context-group>
4069 <context-group purpose="location">
4070 <context context-type="sourcefile">src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.ts</context>
4071 <context context-type="linenumber">1</context>
4072 </context-group>
4073 <context-group purpose="location">
4074 <context context-type="sourcefile">src/app/+verify-account/verify-account-ask-send-email/verify-account-ask-send-email.component.ts</context>
4075 <context context-type="linenumber">1</context>
4076 </context-group>
4077 <context-group purpose="location">
4078 <context context-type="sourcefile">src/app/login/login.component.ts</context>
4079 <context context-type="linenumber">1</context>
4080 </context-group>
4081 <context-group purpose="location">
4082 <context context-type="sourcefile">src/app/reset-password/reset-password.component.ts</context>
4083 <context context-type="linenumber">1</context>
4084 </context-group>
4085 <context-group purpose="location">
4086 <context context-type="sourcefile">src/app/shared/moderation/user-ban-modal.component.ts</context>
4087 <context context-type="linenumber">1</context>
4088 </context-group>
4089 <context-group purpose="location">
4090 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4091 <context context-type="linenumber">1</context>
4092 </context-group>
4093 <context-group purpose="location">
4094 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4095 <context context-type="linenumber">1</context>
4096 </context-group>
4097 <context-group purpose="location">
4098 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4099 <context context-type="linenumber">1</context>
4100 </context-group>
4101 <context-group purpose="location">
4102 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4103 <context context-type="linenumber">1</context>
4104 </context-group>
4105 <context-group purpose="location">
4106 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4107 <context context-type="linenumber">1</context>
4108 </context-group>
4109 <context-group purpose="location">
4110 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4111 <context context-type="linenumber">1</context>
4112 </context-group>
4113 <context-group purpose="location">
4114 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4115 <context context-type="linenumber">1</context>
4116 </context-group>
4117 <context-group purpose="location">
4118 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4119 <context context-type="linenumber">1</context>
4120 </context-group>
4121 <context-group purpose="location">
4122 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4123 <context context-type="linenumber">1</context>
4124 </context-group>
4125 <context-group purpose="location">
4126 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4127 <context context-type="linenumber">1</context>
4128 </context-group>
4129 <context-group purpose="location">
4130 <context context-type="sourcefile">src/app/shared/moderation/user-moderation-dropdown.component.ts</context>
4131 <context context-type="linenumber">1</context>
4132 </context-group>
4133 <context-group purpose="location">
4134 <context context-type="sourcefile">src/app/signup/signup.component.ts</context>
4135 <context context-type="linenumber">1</context>
4136 </context-group>
4137 <context-group purpose="location">
4138 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-import-torrent.component.ts</context>
4139 <context context-type="linenumber">1</context>
4140 </context-group>
4141 <context-group purpose="location">
4142 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-import-url.component.ts</context>
4143 <context context-type="linenumber">1</context>
4144 </context-group>
4145 <context-group purpose="location">
4146 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-upload.component.ts</context>
4147 <context context-type="linenumber">1</context>
4148 </context-group>
4149 <context-group purpose="location">
4150 <context context-type="sourcefile">src/app/videos/+video-edit/video-update.component.ts</context>
4151 <context context-type="linenumber">1</context>
4152 </context-group>
4153 <context-group purpose="location">
4154 <context context-type="sourcefile">src/app/videos/+video-watch/modal/video-blacklist.component.ts</context>
4155 <context context-type="linenumber">1</context>
4156 </context-group>
4157 <context-group purpose="location">
4158 <context context-type="sourcefile">src/app/videos/+video-watch/modal/video-download.component.ts</context>
4159 <context context-type="linenumber">1</context>
4160 </context-group>
4161 <context-group purpose="location">
4162 <context context-type="sourcefile">src/app/videos/+video-watch/modal/video-report.component.ts</context>
4163 <context context-type="linenumber">1</context>
4164 </context-group>
4165 <context-group purpose="location">
4166 <context context-type="sourcefile">src/app/videos/+video-watch/modal/video-share.component.ts</context>
4167 <context context-type="linenumber">1</context>
4168 </context-group>
4169 <context-group purpose="location">
4170 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
4171 <context context-type="linenumber">1</context>
4172 </context-group>
4173 <context-group purpose="location">
4174 <context context-type="sourcefile">src/app/videos/+video-watch/video-watch.component.ts</context>
4175 <context context-type="linenumber">1</context>
4176 </context-group>
4177 </trans-unit>
4178 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048" datatype="html"> 3866 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048" datatype="html">
4179 <source>Configuration updated.</source> 3867 <source>Configuration updated.</source>
4180 <context-group purpose="location"> 3868 <context-group purpose="location">
@@ -4423,6 +4111,20 @@ When you will upload a video in this channel, the video support field will be au
4423 <context context-type="linenumber">1</context> 4111 <context context-type="linenumber">1</context>
4424 </context-group> 4112 </context-group>
4425 </trans-unit> 4113 </trans-unit>
4114 <trans-unit id="0594812d4c50c2adbd1a892a3497c4e5c19e4b32" datatype="html">
4115 <source>yes</source>
4116 <context-group purpose="location">
4117 <context context-type="sourcefile">src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts</context>
4118 <context context-type="linenumber">1</context>
4119 </context-group>
4120 </trans-unit>
4121 <trans-unit id="6320692861e01fa9c9d4e692d0d27b6c12b21c3b" datatype="html">
4122 <source>no</source>
4123 <context-group purpose="location">
4124 <context context-type="sourcefile">src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts</context>
4125 <context context-type="linenumber">1</context>
4126 </context-group>
4127 </trans-unit>
4426 <trans-unit id="652845b2b32b2e117b9b02879b1af07859b0e223" datatype="html"> 4128 <trans-unit id="652845b2b32b2e117b9b02879b1af07859b0e223" datatype="html">
4427 <source>Do you really want to remove this video from the blacklist? It will be available again in the videos list.</source> 4129 <source>Do you really want to remove this video from the blacklist? It will be available again in the videos list.</source>
4428 <context-group purpose="location"> 4130 <context-group purpose="location">
@@ -4575,6 +4277,48 @@ When you will upload a video in this channel, the video support field will be au
4575 <context context-type="linenumber">1</context> 4277 <context context-type="linenumber">1</context>
4576 </context-group> 4278 </context-group>
4577 </trans-unit> 4279 </trans-unit>
4280 <trans-unit id="80057baa3b97a4349304bdaa0a880e6f4778561f" datatype="html">
4281 <source>My videos history</source>
4282 <context-group purpose="location">
4283 <context context-type="sourcefile">src/app/+my-account/my-account-history/my-account-history.component.ts</context>
4284 <context context-type="linenumber">1</context>
4285 </context-group>
4286 </trans-unit>
4287 <trans-unit id="05f6dda1754741495451b8658bd2248856765d95" datatype="html">
4288 <source>Videos history is enabled</source>
4289 <context-group purpose="location">
4290 <context context-type="sourcefile">src/app/+my-account/my-account-history/my-account-history.component.ts</context>
4291 <context context-type="linenumber">1</context>
4292 </context-group>
4293 </trans-unit>
4294 <trans-unit id="6bb9ade8637c5e35fb5cb36cf7dbec71c65d4013" datatype="html">
4295 <source>Videos history is disabled</source>
4296 <context-group purpose="location">
4297 <context context-type="sourcefile">src/app/+my-account/my-account-history/my-account-history.component.ts</context>
4298 <context context-type="linenumber">1</context>
4299 </context-group>
4300 </trans-unit>
4301 <trans-unit id="8453a7a55b8b23bbbc293cd0939fb59a73307de8" datatype="html">
4302 <source>Delete videos history</source>
4303 <context-group purpose="location">
4304 <context context-type="sourcefile">src/app/+my-account/my-account-history/my-account-history.component.ts</context>
4305 <context context-type="linenumber">1</context>
4306 </context-group>
4307 </trans-unit>
4308 <trans-unit id="f8f86df8a1ae711944c3ab819bb19bf360dfa7a4" datatype="html">
4309 <source>Are you sure you want to delete all your videos history?</source>
4310 <context-group purpose="location">
4311 <context context-type="sourcefile">src/app/+my-account/my-account-history/my-account-history.component.ts</context>
4312 <context context-type="linenumber">1</context>
4313 </context-group>
4314 </trans-unit>
4315 <trans-unit id="195d5ba6c8bd05762d9318d0afd0b094fd776164" datatype="html">
4316 <source>Videos history deleted</source>
4317 <context-group purpose="location">
4318 <context context-type="sourcefile">src/app/+my-account/my-account-history/my-account-history.component.ts</context>
4319 <context context-type="linenumber">1</context>
4320 </context-group>
4321 </trans-unit>
4578 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e" datatype="html"> 4322 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e" datatype="html">
4579 <source>Ownership accepted</source> 4323 <source>Ownership accepted</source>
4580 <context-group purpose="location"> 4324 <context-group purpose="location">
@@ -4624,6 +4368,76 @@ When you will upload a video in this channel, the video support field will be au
4624 <context context-type="linenumber">1</context> 4368 <context context-type="linenumber">1</context>
4625 </context-group> 4369 </context-group>
4626 </trans-unit> 4370 </trans-unit>
4371 <trans-unit id="7c193bf704577e514b63497c4f366511afdb6585" datatype="html">
4372 <source>New video from your subscriptions</source>
4373 <context-group purpose="location">
4374 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts</context>
4375 <context context-type="linenumber">1</context>
4376 </context-group>
4377 </trans-unit>
4378 <trans-unit id="ba897defa2e6c34d5ee3d10edf8d797a35e7e3e5" datatype="html">
4379 <source>New comment on your video</source>
4380 <context-group purpose="location">
4381 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts</context>
4382 <context context-type="linenumber">1</context>
4383 </context-group>
4384 </trans-unit>
4385 <trans-unit id="0a9650640ddd1dfadfe456891d6d4f6093ad428e" datatype="html">
4386 <source>New video abuse on local video</source>
4387 <context-group purpose="location">
4388 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts</context>
4389 <context context-type="linenumber">1</context>
4390 </context-group>
4391 </trans-unit>
4392 <trans-unit id="abac8b7629cfcd85bff25770f83ea229f646f996" datatype="html">
4393 <source>One of your video is blacklisted/unblacklisted</source>
4394 <context-group purpose="location">
4395 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts</context>
4396 <context context-type="linenumber">1</context>
4397 </context-group>
4398 </trans-unit>
4399 <trans-unit id="f3eff4df9e4aa9dab411e6eb83833a33016a88bc" datatype="html">
4400 <source>Video published (after transcoding/scheduled update)</source>
4401 <context-group purpose="location">
4402 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts</context>
4403 <context context-type="linenumber">1</context>
4404 </context-group>
4405 </trans-unit>
4406 <trans-unit id="ec7ddc265da1df78011ae7677d62a2ae10aef7a4" datatype="html">
4407 <source>Video import finished</source>
4408 <context-group purpose="location">
4409 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts</context>
4410 <context context-type="linenumber">1</context>
4411 </context-group>
4412 </trans-unit>
4413 <trans-unit id="c327bbac87cca61f5c52f5825d564878e98b9034" datatype="html">
4414 <source>A new user registered on your instance</source>
4415 <context-group purpose="location">
4416 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts</context>
4417 <context context-type="linenumber">1</context>
4418 </context-group>
4419 </trans-unit>
4420 <trans-unit id="f407b90e99a04e2e0d1872c02f01eadbf53e08e2" datatype="html">
4421 <source>You or your channel(s) has a new follower</source>
4422 <context-group purpose="location">
4423 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts</context>
4424 <context context-type="linenumber">1</context>
4425 </context-group>
4426 </trans-unit>
4427 <trans-unit id="14c3050a9da4c1bc49d555c45d5660804d08e83b" datatype="html">
4428 <source>Someone mentioned you in video comments</source>
4429 <context-group purpose="location">
4430 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts</context>
4431 <context context-type="linenumber">1</context>
4432 </context-group>
4433 </trans-unit>
4434 <trans-unit id="a0f04081717f5f00c0a2c723903c3a2d4c296401" datatype="html">
4435 <source>Preferences saved</source>
4436 <context-group purpose="location">
4437 <context context-type="sourcefile">src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts</context>
4438 <context context-type="linenumber">1</context>
4439 </context-group>
4440 </trans-unit>
4627 <trans-unit id="db4ff52375f6a25ad0472e92754c8c265ae47c6b" datatype="html"> 4441 <trans-unit id="db4ff52375f6a25ad0472e92754c8c265ae47c6b" datatype="html">
4628 <source>Profile updated.</source> 4442 <source>Profile updated.</source>
4629 <context-group purpose="location"> 4443 <context-group purpose="location">
@@ -4677,24 +4491,28 @@ When you will upload a video in this channel, the video support field will be au
4677 <context context-type="linenumber">1</context> 4491 <context context-type="linenumber">1</context>
4678 </context-group> 4492 </context-group>
4679 </trans-unit> 4493 </trans-unit>
4680 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814" datatype="html"> 4494 <trans-unit id="3859ca2a7577ba8797058d7d97eb8054bc56ec99" datatype="html">
4681 <source>Do you really want to delete &lt;x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/&gt;? It will delete all videos uploaded in this channel too.</source> 4495 <source>Please type the display name of the video channel (&lt;x id="INTERPOLATION" equiv-text="{{displayName}}"/&gt;) to confirm</source>
4682 <context-group purpose="location"> 4496 <context-group purpose="location">
4683 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context> 4497 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context>
4684 <context context-type="linenumber">1</context> 4498 <context context-type="linenumber">1</context>
4685 </context-group> 4499 </context-group>
4686 </trans-unit> 4500 </trans-unit>
4687 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e" datatype="html"> 4501 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2" datatype="html">
4688 <source>Please type the name of the video channel to confirm</source> 4502 <source>Video channel &lt;x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/&gt; deleted.</source>
4689 <context-group purpose="location"> 4503 <context-group purpose="location">
4690 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context> 4504 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context>
4691 <context context-type="linenumber">1</context> 4505 <context context-type="linenumber">1</context>
4692 </context-group> 4506 </context-group>
4693 </trans-unit> 4507 </trans-unit>
4694 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2" datatype="html"> 4508 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894" datatype="html">
4695 <source>Video channel &lt;x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/&gt; deleted.</source> 4509 <source>My videos</source>
4696 <context-group purpose="location"> 4510 <context-group purpose="location">
4697 <context context-type="sourcefile">src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts</context> 4511 <context context-type="sourcefile">src/app/+my-account/my-account-videos/my-account-videos.component.ts</context>
4512 <context context-type="linenumber">1</context>
4513 </context-group>
4514 <context-group purpose="location">
4515 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context>
4698 <context context-type="linenumber">1</context> 4516 <context context-type="linenumber">1</context>
4699 </context-group> 4517 </context-group>
4700 </trans-unit> 4518 </trans-unit>
@@ -4772,15 +4590,57 @@ When you will upload a video in this channel, the video support field will be au
4772 <context context-type="linenumber">1</context> 4590 <context context-type="linenumber">1</context>
4773 </context-group> 4591 </context-group>
4774 </trans-unit> 4592 </trans-unit>
4775 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19" datatype="html"> 4593 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432" datatype="html">
4776 <source>Channels</source> 4594 <source>My library</source>
4777 <context-group purpose="location"> 4595 <context-group purpose="location">
4778 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context> 4596 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context>
4779 <context context-type="linenumber">1</context> 4597 <context context-type="linenumber">1</context>
4780 </context-group> 4598 </context-group>
4781 </trans-unit> 4599 </trans-unit>
4782 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d" datatype="html"> 4600 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f" datatype="html">
4783 <source>Video imports</source> 4601 <source>My channels</source>
4602 <context-group purpose="location">
4603 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context>
4604 <context context-type="linenumber">1</context>
4605 </context-group>
4606 </trans-unit>
4607 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9" datatype="html">
4608 <source>My subscriptions</source>
4609 <context-group purpose="location">
4610 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context>
4611 <context context-type="linenumber">1</context>
4612 </context-group>
4613 </trans-unit>
4614 <trans-unit id="4f953496ca94b4f83af049ff715172df2729fb79" datatype="html">
4615 <source>My history</source>
4616 <context-group purpose="location">
4617 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context>
4618 <context context-type="linenumber">1</context>
4619 </context-group>
4620 </trans-unit>
4621 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029" datatype="html">
4622 <source>Misc</source>
4623 <context-group purpose="location">
4624 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context>
4625 <context context-type="linenumber">1</context>
4626 </context-group>
4627 </trans-unit>
4628 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7" datatype="html">
4629 <source>Ownership changes</source>
4630 <context-group purpose="location">
4631 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context>
4632 <context context-type="linenumber">1</context>
4633 </context-group>
4634 </trans-unit>
4635 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6" datatype="html">
4636 <source>My settings</source>
4637 <context-group purpose="location">
4638 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context>
4639 <context context-type="linenumber">1</context>
4640 </context-group>
4641 </trans-unit>
4642 <trans-unit id="0e2434e7d84145c4e8a930ccc4c26c3cb2887e0d" datatype="html">
4643 <source>My notifications</source>
4784 <context-group purpose="location"> 4644 <context-group purpose="location">
4785 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context> 4645 <context context-type="sourcefile">src/app/+my-account/my-account.component.ts</context>
4786 <context context-type="linenumber">1</context> 4646 <context context-type="linenumber">1</context>
@@ -4914,6 +4774,17 @@ When you will upload a video in this channel, the video support field will be au
4914 <context context-type="linenumber">1</context> 4774 <context context-type="linenumber">1</context>
4915 </context-group> 4775 </context-group>
4916 </trans-unit> 4776 </trans-unit>
4777 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d" datatype="html">
4778 <source>Error</source>
4779 <context-group purpose="location">
4780 <context context-type="sourcefile">src/app/core/auth/auth.service.ts</context>
4781 <context context-type="linenumber">1</context>
4782 </context-group>
4783 <context-group purpose="location">
4784 <context context-type="sourcefile">src/app/core/notification/notifier.service.ts</context>
4785 <context context-type="linenumber">1</context>
4786 </context-group>
4787 </trans-unit>
4917 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87" datatype="html"> 4788 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87" datatype="html">
4918 <source>You need to reconnect.</source> 4789 <source>You need to reconnect.</source>
4919 <context-group purpose="location"> 4790 <context-group purpose="location">
@@ -4935,6 +4806,20 @@ When you will upload a video in this channel, the video support field will be au
4935 <context context-type="linenumber">1</context> 4806 <context context-type="linenumber">1</context>
4936 </context-group> 4807 </context-group>
4937 </trans-unit> 4808 </trans-unit>
4809 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5" datatype="html">
4810 <source>Info</source>
4811 <context-group purpose="location">
4812 <context context-type="sourcefile">src/app/core/notification/notifier.service.ts</context>
4813 <context context-type="linenumber">1</context>
4814 </context-group>
4815 </trans-unit>
4816 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba" datatype="html">
4817 <source>Success</source>
4818 <context-group purpose="location">
4819 <context context-type="sourcefile">src/app/core/notification/notifier.service.ts</context>
4820 <context context-type="linenumber">1</context>
4821 </context-group>
4822 </trans-unit>
4938 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe" datatype="html"> 4823 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe" datatype="html">
4939 <source>Incorrect username or password.</source> 4824 <source>Incorrect username or password.</source>
4940 <context-group purpose="location"> 4825 <context-group purpose="location">
@@ -5156,10 +5041,10 @@ When you will upload a video in this channel, the video support field will be au
5156 <context context-type="linenumber">1</context> 5041 <context context-type="linenumber">1</context>
5157 </context-group> 5042 </context-group>
5158 </trans-unit> 5043 </trans-unit>
5159 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149" datatype="html"> 5044 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0" datatype="html">
5160 <source>Username is required.</source> 5045 <source>Email is required.</source>
5161 <context-group purpose="location"> 5046 <context-group purpose="location">
5162 <context context-type="sourcefile">src/app/shared/forms/form-validators/login-validators.service.ts</context> 5047 <context context-type="sourcefile">src/app/shared/forms/form-validators/instance-validators.service.ts</context>
5163 <context context-type="linenumber">1</context> 5048 <context context-type="linenumber">1</context>
5164 </context-group> 5049 </context-group>
5165 <context-group purpose="location"> 5050 <context-group purpose="location">
@@ -5167,10 +5052,10 @@ When you will upload a video in this channel, the video support field will be au
5167 <context context-type="linenumber">1</context> 5052 <context context-type="linenumber">1</context>
5168 </context-group> 5053 </context-group>
5169 </trans-unit> 5054 </trans-unit>
5170 <trans-unit id="4eb39d69b74d7a56652ec84fa6826994ee26c0e5" datatype="html"> 5055 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1" datatype="html">
5171 <source>Password is required.</source> 5056 <source>Email must be valid.</source>
5172 <context-group purpose="location"> 5057 <context-group purpose="location">
5173 <context context-type="sourcefile">src/app/shared/forms/form-validators/login-validators.service.ts</context> 5058 <context context-type="sourcefile">src/app/shared/forms/form-validators/instance-validators.service.ts</context>
5174 <context context-type="linenumber">1</context> 5059 <context context-type="linenumber">1</context>
5175 </context-group> 5060 </context-group>
5176 <context-group purpose="location"> 5061 <context-group purpose="location">
@@ -5178,43 +5063,93 @@ When you will upload a video in this channel, the video support field will be au
5178 <context context-type="linenumber">1</context> 5063 <context context-type="linenumber">1</context>
5179 </context-group> 5064 </context-group>
5180 </trans-unit> 5065 </trans-unit>
5181 <trans-unit id="c90872a06666a51c2957c4b29724e68df5c67154" datatype="html"> 5066 <trans-unit id="ac451f128840b34804ea69c820dc3566f476fb33" datatype="html">
5182 <source>Confirmation of the password is required.</source> 5067 <source>Your name is required.</source>
5183 <context-group purpose="location"> 5068 <context-group purpose="location">
5184 <context context-type="sourcefile">src/app/shared/forms/form-validators/reset-password-validators.service.ts</context> 5069 <context context-type="sourcefile">src/app/shared/forms/form-validators/instance-validators.service.ts</context>
5070 <context context-type="linenumber">1</context>
5071 </context-group>
5072 </trans-unit>
5073 <trans-unit id="1fc4633008a2431fdec891d58efcc8b865d7de1a" datatype="html">
5074 <source>Your name must be at least 1 character long.</source>
5075 <context-group purpose="location">
5076 <context context-type="sourcefile">src/app/shared/forms/form-validators/instance-validators.service.ts</context>
5077 <context context-type="linenumber">1</context>
5078 </context-group>
5079 </trans-unit>
5080 <trans-unit id="c7b44b92c0ce3ccd2f804d001e13da399524e11b" datatype="html">
5081 <source>Your name cannot be more than 120 characters long.</source>
5082 <context-group purpose="location">
5083 <context context-type="sourcefile">src/app/shared/forms/form-validators/instance-validators.service.ts</context>
5084 <context context-type="linenumber">1</context>
5085 </context-group>
5086 </trans-unit>
5087 <trans-unit id="40b35cf927f9f9a59404a6c914ec4632690b69b2" datatype="html">
5088 <source>A message is required.</source>
5089 <context-group purpose="location">
5090 <context context-type="sourcefile">src/app/shared/forms/form-validators/instance-validators.service.ts</context>
5185 <context context-type="linenumber">1</context> 5091 <context context-type="linenumber">1</context>
5186 </context-group> 5092 </context-group>
5187 </trans-unit> 5093 </trans-unit>
5188 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea" datatype="html"> 5094 <trans-unit id="d8d4a23f467ee3e93ca0edb1198c233ed633cf64" datatype="html">
5189 <source>Username must be at least 3 characters long.</source> 5095 <source>The message must be at least 3 characters long.</source>
5096 <context-group purpose="location">
5097 <context context-type="sourcefile">src/app/shared/forms/form-validators/instance-validators.service.ts</context>
5098 <context context-type="linenumber">1</context>
5099 </context-group>
5100 </trans-unit>
5101 <trans-unit id="07422f6141cfcabaf3c2ce77e3e063222849ef60" datatype="html">
5102 <source>The message cannot be more than 5000 characters long.</source>
5103 <context-group purpose="location">
5104 <context context-type="sourcefile">src/app/shared/forms/form-validators/instance-validators.service.ts</context>
5105 <context context-type="linenumber">1</context>
5106 </context-group>
5107 </trans-unit>
5108 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149" datatype="html">
5109 <source>Username is required.</source>
5110 <context-group purpose="location">
5111 <context context-type="sourcefile">src/app/shared/forms/form-validators/login-validators.service.ts</context>
5112 <context context-type="linenumber">1</context>
5113 </context-group>
5190 <context-group purpose="location"> 5114 <context-group purpose="location">
5191 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context> 5115 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
5192 <context context-type="linenumber">1</context> 5116 <context context-type="linenumber">1</context>
5193 </context-group> 5117 </context-group>
5194 </trans-unit> 5118 </trans-unit>
5195 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef" datatype="html"> 5119 <trans-unit id="4eb39d69b74d7a56652ec84fa6826994ee26c0e5" datatype="html">
5196 <source>Username cannot be more than 20 characters long.</source> 5120 <source>Password is required.</source>
5121 <context-group purpose="location">
5122 <context context-type="sourcefile">src/app/shared/forms/form-validators/login-validators.service.ts</context>
5123 <context context-type="linenumber">1</context>
5124 </context-group>
5197 <context-group purpose="location"> 5125 <context-group purpose="location">
5198 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context> 5126 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
5199 <context context-type="linenumber">1</context> 5127 <context context-type="linenumber">1</context>
5200 </context-group> 5128 </context-group>
5201 </trans-unit> 5129 </trans-unit>
5202 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9" datatype="html"> 5130 <trans-unit id="c90872a06666a51c2957c4b29724e68df5c67154" datatype="html">
5203 <source>Username should be only lowercase alphanumeric characters.</source> 5131 <source>Confirmation of the password is required.</source>
5132 <context-group purpose="location">
5133 <context context-type="sourcefile">src/app/shared/forms/form-validators/reset-password-validators.service.ts</context>
5134 <context context-type="linenumber">1</context>
5135 </context-group>
5136 </trans-unit>
5137 <trans-unit id="6330d25a3bc6f55dfd5177da6e681d1d3b1a2b1a" datatype="html">
5138 <source>Username must be at least 1 character long.</source>
5204 <context-group purpose="location"> 5139 <context-group purpose="location">
5205 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context> 5140 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
5206 <context context-type="linenumber">1</context> 5141 <context context-type="linenumber">1</context>
5207 </context-group> 5142 </context-group>
5208 </trans-unit> 5143 </trans-unit>
5209 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0" datatype="html"> 5144 <trans-unit id="aaaf3d00c35f809eebc7fd68a3f7b8b0230b197a" datatype="html">
5210 <source>Email is required.</source> 5145 <source>Username cannot be more than 50 characters long.</source>
5211 <context-group purpose="location"> 5146 <context-group purpose="location">
5212 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context> 5147 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
5213 <context context-type="linenumber">1</context> 5148 <context context-type="linenumber">1</context>
5214 </context-group> 5149 </context-group>
5215 </trans-unit> 5150 </trans-unit>
5216 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1" datatype="html"> 5151 <trans-unit id="6f3e95be2538a22da07beaefc39bb2195683990c" datatype="html">
5217 <source>Email must be valid.</source> 5152 <source>Username should be lowercase alphanumeric; dots and underscores are allowed.</source>
5218 <context-group purpose="location"> 5153 <context-group purpose="location">
5219 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context> 5154 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
5220 <context context-type="linenumber">1</context> 5155 <context context-type="linenumber">1</context>
@@ -5287,8 +5222,8 @@ When you will upload a video in this channel, the video support field will be au
5287 <context context-type="linenumber">1</context> 5222 <context context-type="linenumber">1</context>
5288 </context-group> 5223 </context-group>
5289 </trans-unit> 5224 </trans-unit>
5290 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674" datatype="html"> 5225 <trans-unit id="085b2d6f79819a72a2b56cada4ef5085ba51d90c" datatype="html">
5291 <source>Display name must be at least 3 characters long.</source> 5226 <source>Display name must be at least 1 character long.</source>
5292 <context-group purpose="location"> 5227 <context-group purpose="location">
5293 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context> 5228 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
5294 <context context-type="linenumber">1</context> 5229 <context context-type="linenumber">1</context>
@@ -5298,8 +5233,8 @@ When you will upload a video in this channel, the video support field will be au
5298 <context context-type="linenumber">1</context> 5233 <context context-type="linenumber">1</context>
5299 </context-group> 5234 </context-group>
5300 </trans-unit> 5235 </trans-unit>
5301 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9" datatype="html"> 5236 <trans-unit id="5a920575b8e1067f5b11c66a4a36d3ced87756f1" datatype="html">
5302 <source>Display name cannot be more than 120 characters long.</source> 5237 <source>Display name cannot be more than 50 characters long.</source>
5303 <context-group purpose="location"> 5238 <context-group purpose="location">
5304 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context> 5239 <context context-type="sourcefile">src/app/shared/forms/form-validators/user-validators.service.ts</context>
5305 <context context-type="linenumber">1</context> 5240 <context context-type="linenumber">1</context>
@@ -5366,8 +5301,8 @@ When you will upload a video in this channel, the video support field will be au
5366 <context context-type="linenumber">1</context> 5301 <context context-type="linenumber">1</context>
5367 </context-group> 5302 </context-group>
5368 </trans-unit> 5303 </trans-unit>
5369 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9" datatype="html"> 5304 <trans-unit id="8c7d4c82b057aea5dbae811e16935f9bcae4c2aa" datatype="html">
5370 <source>Report reason cannot be more than 300 characters long.</source> 5305 <source>Report reason cannot be more than 3000 characters long.</source>
5371 <context-group purpose="location"> 5306 <context-group purpose="location">
5372 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-abuse-validators.service.ts</context> 5307 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-abuse-validators.service.ts</context>
5373 <context context-type="linenumber">1</context> 5308 <context context-type="linenumber">1</context>
@@ -5387,8 +5322,8 @@ When you will upload a video in this channel, the video support field will be au
5387 <context context-type="linenumber">1</context> 5322 <context context-type="linenumber">1</context>
5388 </context-group> 5323 </context-group>
5389 </trans-unit> 5324 </trans-unit>
5390 <trans-unit id="89d0b662dde0871cf17244e79b2cb62cd517e44f" datatype="html"> 5325 <trans-unit id="23c1c2e105a98b0b6728949418a256b026b8971c" datatype="html">
5391 <source>Moderation comment cannot be more than 300 characters long.</source> 5326 <source>Moderation comment cannot be more than 3000 characters long.</source>
5392 <context-group purpose="location"> 5327 <context-group purpose="location">
5393 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-abuse-validators.service.ts</context> 5328 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-abuse-validators.service.ts</context>
5394 <context context-type="linenumber">1</context> 5329 <context context-type="linenumber">1</context>
@@ -5450,22 +5385,22 @@ When you will upload a video in this channel, the video support field will be au
5450 <context context-type="linenumber">1</context> 5385 <context context-type="linenumber">1</context>
5451 </context-group> 5386 </context-group>
5452 </trans-unit> 5387 </trans-unit>
5453 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069" datatype="html"> 5388 <trans-unit id="b8b59b6284a14fc71268cf722ed98c62c5af4a76" datatype="html">
5454 <source>Name must be at least 3 characters long.</source> 5389 <source>Name must be at least 1 character long.</source>
5455 <context-group purpose="location"> 5390 <context-group purpose="location">
5456 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context> 5391 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context>
5457 <context context-type="linenumber">1</context> 5392 <context context-type="linenumber">1</context>
5458 </context-group> 5393 </context-group>
5459 </trans-unit> 5394 </trans-unit>
5460 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482" datatype="html"> 5395 <trans-unit id="e14cd37d29f13eac7384c339e4f1df58d96e4e3d" datatype="html">
5461 <source>Name cannot be more than 20 characters long.</source> 5396 <source>Name cannot be more than 50 characters long.</source>
5462 <context-group purpose="location"> 5397 <context-group purpose="location">
5463 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context> 5398 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context>
5464 <context context-type="linenumber">1</context> 5399 <context context-type="linenumber">1</context>
5465 </context-group> 5400 </context-group>
5466 </trans-unit> 5401 </trans-unit>
5467 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9" datatype="html"> 5402 <trans-unit id="135185da003b14cbb69521f570fa617a00bbbe18" datatype="html">
5468 <source>Name should be only lowercase alphanumeric characters.</source> 5403 <source>Name should be lowercase alphanumeric; dots and underscores are allowed.</source>
5469 <context-group purpose="location"> 5404 <context-group purpose="location">
5470 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context> 5405 <context context-type="sourcefile">src/app/shared/forms/form-validators/video-channel-validators.service.ts</context>
5471 <context context-type="linenumber">1</context> 5406 <context context-type="linenumber">1</context>
@@ -5597,6 +5532,13 @@ When you will upload a video in this channel, the video support field will be au
5597 <context context-type="linenumber">1</context> 5532 <context context-type="linenumber">1</context>
5598 </context-group> 5533 </context-group>
5599 </trans-unit> 5534 </trans-unit>
5535 <trans-unit id="2f5f2093f14679fed82ff76a0cd2a28145a83ca9" datatype="html">
5536 <source>PeerTube cannot handle this kind of file. Accepted extensions are &lt;x id="INTERPOLATION" equiv-text="{{extensions}}"/&gt;.</source>
5537 <context-group purpose="location">
5538 <context context-type="sourcefile">src/app/shared/forms/reactive-file.component.ts</context>
5539 <context context-type="linenumber">1</context>
5540 </context-group>
5541 </trans-unit>
5600 <trans-unit id="0bf41abaa85526711f7952b4600e4044bc7f04a4" datatype="html"> 5542 <trans-unit id="0bf41abaa85526711f7952b4600e4044bc7f04a4" datatype="html">
5601 <source>All unsaved data will be lost, are you sure you want to leave this page?</source> 5543 <source>All unsaved data will be lost, are you sure you want to leave this page?</source>
5602 <context-group purpose="location"> 5544 <context-group purpose="location">
@@ -6313,29 +6255,29 @@ When you will upload a video in this channel, the video support field will be au
6313 <context context-type="linenumber">1</context> 6255 <context context-type="linenumber">1</context>
6314 </context-group> 6256 </context-group>
6315 </trans-unit> 6257 </trans-unit>
6316 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1" datatype="html"> 6258 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded" datatype="html">
6317 <source>Subscribed</source> 6259 <source>Subscribed to &lt;x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/&gt;</source>
6318 <context-group purpose="location"> 6260 <context-group purpose="location">
6319 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context> 6261 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context>
6320 <context context-type="linenumber">1</context> 6262 <context context-type="linenumber">1</context>
6321 </context-group> 6263 </context-group>
6322 </trans-unit> 6264 </trans-unit>
6323 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded" datatype="html"> 6265 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1" datatype="html">
6324 <source>Subscribed to &lt;x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/&gt;</source> 6266 <source>Subscribed</source>
6325 <context-group purpose="location"> 6267 <context-group purpose="location">
6326 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context> 6268 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context>
6327 <context context-type="linenumber">1</context> 6269 <context context-type="linenumber">1</context>
6328 </context-group> 6270 </context-group>
6329 </trans-unit> 6271 </trans-unit>
6330 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471" datatype="html"> 6272 <trans-unit id="3e7735fa326fcdc9e1188b6d9ff4b4329312fc26" datatype="html">
6331 <source>Unsubscribed</source> 6273 <source>Unsubscribed from &lt;x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/&gt;</source>
6332 <context-group purpose="location"> 6274 <context-group purpose="location">
6333 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context> 6275 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context>
6334 <context context-type="linenumber">1</context> 6276 <context context-type="linenumber">1</context>
6335 </context-group> 6277 </context-group>
6336 </trans-unit> 6278 </trans-unit>
6337 <trans-unit id="3e7735fa326fcdc9e1188b6d9ff4b4329312fc26" datatype="html"> 6279 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471" datatype="html">
6338 <source>Unsubscribed from &lt;x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/&gt;</source> 6280 <source>Unsubscribed</source>
6339 <context-group purpose="location"> 6281 <context-group purpose="location">
6340 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context> 6282 <context context-type="sourcefile">src/app/shared/user-subscription/subscribe-button.component.ts</context>
6341 <context context-type="linenumber">1</context> 6283 <context context-type="linenumber">1</context>
@@ -6415,13 +6357,6 @@ When you will upload a video in this channel, the video support field will be au
6415 <context context-type="linenumber">1</context> 6357 <context context-type="linenumber">1</context>
6416 </context-group> 6358 </context-group>
6417 </trans-unit> 6359 </trans-unit>
6418 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5" datatype="html">
6419 <source>Info</source>
6420 <context-group purpose="location">
6421 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-upload.component.ts</context>
6422 <context context-type="linenumber">1</context>
6423 </context-group>
6424 </trans-unit>
6425 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9" datatype="html"> 6360 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9" datatype="html">
6426 <source>Upload cancelled</source> 6361 <source>Upload cancelled</source>
6427 <context-group purpose="location"> 6362 <context-group purpose="location">
@@ -6429,13 +6364,6 @@ When you will upload a video in this channel, the video support field will be au
6429 <context context-type="linenumber">1</context> 6364 <context context-type="linenumber">1</context>
6430 </context-group> 6365 </context-group>
6431 </trans-unit> 6366 </trans-unit>
6432 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa" datatype="html">
6433 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
6434 <context-group purpose="location">
6435 <context context-type="sourcefile">src/app/videos/+video-edit/video-add-components/video-upload.component.ts</context>
6436 <context context-type="linenumber">1</context>
6437 </context-group>
6438 </trans-unit>
6439 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee" datatype="html"> 6367 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee" datatype="html">
6440 <source>Your video quota is exceeded with this video (video size: &lt;x id="INTERPOLATION" equiv-text="{{videoSize}}"/&gt;, used: &lt;x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/&gt;, quota: &lt;x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/&gt;)</source> 6368 <source>Your video quota is exceeded with this video (video size: &lt;x id="INTERPOLATION" equiv-text="{{videoSize}}"/&gt;, used: &lt;x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/&gt;, quota: &lt;x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/&gt;)</source>
6441 <context-group purpose="location"> 6369 <context-group purpose="location">
@@ -6457,6 +6385,13 @@ When you will upload a video in this channel, the video support field will be au
6457 <context context-type="linenumber">1</context> 6385 <context context-type="linenumber">1</context>
6458 </context-group> 6386 </context-group>
6459 </trans-unit> 6387 </trans-unit>
6388 <trans-unit id="bfdf9de4bd9140f77feb6a5fe2b51f3f0565eaa4" datatype="html">
6389 <source>You have unsaved changes! If you leave, your changes will be lost.</source>
6390 <context-group purpose="location">
6391 <context context-type="sourcefile">src/app/videos/+video-edit/video-update.component.ts</context>
6392 <context context-type="linenumber">1</context>
6393 </context-group>
6394 </trans-unit>
6460 <trans-unit id="757e9c083c8f3d578bd74f055cc337c72417e187" datatype="html"> 6395 <trans-unit id="757e9c083c8f3d578bd74f055cc337c72417e187" datatype="html">
6461 <source>Video updated.</source> 6396 <source>Video updated.</source>
6462 <context-group purpose="location"> 6397 <context-group purpose="location">
@@ -6545,6 +6480,34 @@ When you will upload a video in this channel, the video support field will be au
6545 <context context-type="linenumber">1</context> 6480 <context context-type="linenumber">1</context>
6546 </context-group> 6481 </context-group>
6547 </trans-unit> 6482 </trans-unit>
6483 <trans-unit id="5b94148c16fa19e3db89972d11e93f790a73a054" datatype="html">
6484 <source>Trending for the last 24 hours</source>
6485 <context-group purpose="location">
6486 <context context-type="sourcefile">src/app/videos/video-list/video-trending.component.ts</context>
6487 <context context-type="linenumber">1</context>
6488 </context-group>
6489 </trans-unit>
6490 <trans-unit id="8c429645223c24afe30218fc45bb07e352bb1938" datatype="html">
6491 <source>Trending videos are those totalizing the greatest number of views during the last 24 hours.</source>
6492 <context-group purpose="location">
6493 <context context-type="sourcefile">src/app/videos/video-list/video-trending.component.ts</context>
6494 <context context-type="linenumber">1</context>
6495 </context-group>
6496 </trans-unit>
6497 <trans-unit id="6da9ddede61711ecfeaa94fc61a6b7bb844ab3df" datatype="html">
6498 <source>Trending for the last &lt;x id="INTERPOLATION" equiv-text="{{days}}"/&gt; days</source>
6499 <context-group purpose="location">
6500 <context context-type="sourcefile">src/app/videos/video-list/video-trending.component.ts</context>
6501 <context context-type="linenumber">1</context>
6502 </context-group>
6503 </trans-unit>
6504 <trans-unit id="98b98154eca3533e16b81c5b08611d19949e8661" datatype="html">
6505 <source>Trending videos are those totalizing the greatest number of views during the last &lt;x id="INTERPOLATION" equiv-text="{{days}}"/&gt; days.</source>
6506 <context-group purpose="location">
6507 <context context-type="sourcefile">src/app/videos/video-list/video-trending.component.ts</context>
6508 <context context-type="linenumber">1</context>
6509 </context-group>
6510 </trans-unit>
6548 <trans-unit id="1b157e15c434469d91e56d027b78bf69c9983165" datatype="html"> 6511 <trans-unit id="1b157e15c434469d91e56d027b78bf69c9983165" datatype="html">
6549 <source>Videos from your subscriptions</source> 6512 <source>Videos from your subscriptions</source>
6550 <context-group purpose="location"> 6513 <context-group purpose="location">
diff --git a/client/src/locale/source/server_en_US.xml b/client/src/locale/source/server_en_US.xml
index b6e62ce80..f5e125549 100644
--- a/client/src/locale/source/server_en_US.xml
+++ b/client/src/locale/source/server_en_US.xml
@@ -137,6 +137,22 @@
137 <source>Failed</source> 137 <source>Failed</source>
138 <target>undefined</target> 138 <target>undefined</target>
139 </trans-unit> 139 </trans-unit>
140 <trans-unit id="This video does not exist.">
141 <source>This video does not exist.</source>
142 <target>undefined</target>
143 </trans-unit>
144 <trans-unit id="We cannot fetch the video. Please try again later.">
145 <source>We cannot fetch the video. Please try again later.</source>
146 <target>undefined</target>
147 </trans-unit>
148 <trans-unit id="Sorry">
149 <source>Sorry</source>
150 <target>undefined</target>
151 </trans-unit>
152 <trans-unit id="This video is not available because the remote instance is not responding.">
153 <source>This video is not available because the remote instance is not responding.</source>
154 <target>undefined</target>
155 </trans-unit>
140 <trans-unit id="Misc"> 156 <trans-unit id="Misc">
141 <source>Misc</source> 157 <source>Misc</source>
142 <target>undefined</target> 158 <target>undefined</target>
diff --git a/client/src/locale/target/angular_ar_001.xml b/client/src/locale/target/angular_ar_001.xml
index 05e55793d..978f69571 100644
--- a/client/src/locale/target/angular_ar_001.xml
+++ b/client/src/locale/target/angular_ar_001.xml
@@ -430,7 +430,7 @@
430 <source>Password</source> 430 <source>Password</source>
431 <target>الكلمة السرية</target> 431 <target>الكلمة السرية</target>
432 <context-group name="null"> 432 <context-group name="null">
433 <context context-type="linenumber">12</context> 433 <context context-type="linenumber">13</context>
434 </context-group> 434 </context-group>
435 </trans-unit> 435 </trans-unit>
436 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 436 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -444,7 +444,7 @@
444 <source>Login</source> 444 <source>Login</source>
445 <target>تسجيل الدخول</target> 445 <target>تسجيل الدخول</target>
446 <context-group name="null"> 446 <context-group name="null">
447 <context context-type="linenumber">38</context> 447 <context context-type="linenumber">36</context>
448 </context-group> 448 </context-group>
449 </trans-unit> 449 </trans-unit>
450 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 450 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -472,7 +472,7 @@
472 <source>Send me an email to reset my password</source> 472 <source>Send me an email to reset my password</source>
473 <target>أرسل لي رسالة لإعادة تعيين كلمتي السرية</target> 473 <target>أرسل لي رسالة لإعادة تعيين كلمتي السرية</target>
474 <context-group name="null"> 474 <context-group name="null">
475 <context context-type="linenumber">75</context> 475 <context context-type="linenumber">80</context>
476 </context-group> 476 </context-group>
477 </trans-unit> 477 </trans-unit>
478 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 478 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -532,7 +532,7 @@
532 <source>Signup</source> 532 <source>Signup</source>
533 <target>سجل</target> 533 <target>سجل</target>
534 <context-group name="null"> 534 <context-group name="null">
535 <context context-type="linenumber">88</context> 535 <context context-type="linenumber">78</context>
536 </context-group> 536 </context-group>
537 </trans-unit> 537 </trans-unit>
538 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 538 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -576,7 +576,7 @@
576 <source>Change the language</source> 576 <source>Change the language</source>
577 <target>تغيير اللغة</target> 577 <target>تغيير اللغة</target>
578 <context-group name="null"> 578 <context-group name="null">
579 <context context-type="linenumber">88</context> 579 <context context-type="linenumber">86</context>
580 </context-group> 580 </context-group>
581 </trans-unit> 581 </trans-unit>
582 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 582 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -585,7 +585,7 @@
585 </source> 585 </source>
586 <target>صÙحتي العمومية</target> 586 <target>صÙحتي العمومية</target>
587 <context-group name="null"> 587 <context-group name="null">
588 <context context-type="linenumber">18</context> 588 <context context-type="linenumber">16</context>
589 </context-group> 589 </context-group>
590 </trans-unit> 590 </trans-unit>
591 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 591 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -594,7 +594,7 @@
594 </source> 594 </source>
595 <target>حسابي</target> 595 <target>حسابي</target>
596 <context-group name="null"> 596 <context-group name="null">
597 <context context-type="linenumber">22</context> 597 <context context-type="linenumber">20</context>
598 </context-group> 598 </context-group>
599 </trans-unit> 599 </trans-unit>
600 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 600 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -603,7 +603,7 @@
603 </source> 603 </source>
604 <target>Ùيديوهاتي</target> 604 <target>Ùيديوهاتي</target>
605 <context-group name="null"> 605 <context-group name="null">
606 <context context-type="linenumber">26</context> 606 <context context-type="linenumber">24</context>
607 </context-group> 607 </context-group>
608 </trans-unit> 608 </trans-unit>
609 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 609 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -612,14 +612,14 @@
612 </source> 612 </source>
613 <target>الخروج</target> 613 <target>الخروج</target>
614 <context-group name="null"> 614 <context-group name="null">
615 <context context-type="linenumber">30</context> 615 <context context-type="linenumber">28</context>
616 </context-group> 616 </context-group>
617 </trans-unit> 617 </trans-unit>
618 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 618 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
619 <source>Create an account</source> 619 <source>Create an account</source>
620 <target>إنشاء حساب</target> 620 <target>إنشاء حساب</target>
621 <context-group name="null"> 621 <context-group name="null">
622 <context context-type="linenumber">39</context> 622 <context context-type="linenumber">37</context>
623 </context-group> 623 </context-group>
624 </trans-unit> 624 </trans-unit>
625 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 625 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -633,49 +633,49 @@
633 <source>Subscriptions</source> 633 <source>Subscriptions</source>
634 <target>الإشتراكات</target> 634 <target>الإشتراكات</target>
635 <context-group name="null"> 635 <context-group name="null">
636 <context context-type="linenumber">47</context> 636 <context context-type="linenumber">45</context>
637 </context-group> 637 </context-group>
638 </trans-unit> 638 </trans-unit>
639 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 639 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
640 <source>Overview</source> 640 <source>Overview</source>
641 <target>نظرة شاملة</target> 641 <target>نظرة شاملة</target>
642 <context-group name="null"> 642 <context-group name="null">
643 <context context-type="linenumber">52</context> 643 <context context-type="linenumber">50</context>
644 </context-group> 644 </context-group>
645 </trans-unit> 645 </trans-unit>
646 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 646 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
647 <source>Trending</source> 647 <source>Trending</source>
648 <target>الشائعة</target> 648 <target>الشائعة</target>
649 <context-group name="null"> 649 <context-group name="null">
650 <context context-type="linenumber">57</context> 650 <context context-type="linenumber">55</context>
651 </context-group> 651 </context-group>
652 </trans-unit> 652 </trans-unit>
653 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 653 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
654 <source>Recently added</source> 654 <source>Recently added</source>
655 <target>التي تم إضاÙتها حديثًا</target> 655 <target>التي تم إضاÙتها حديثًا</target>
656 <context-group name="null"> 656 <context-group name="null">
657 <context context-type="linenumber">62</context> 657 <context context-type="linenumber">60</context>
658 </context-group> 658 </context-group>
659 </trans-unit> 659 </trans-unit>
660 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 660 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
661 <source>Local</source> 661 <source>Local</source>
662 <target>المحلية</target> 662 <target>المحلية</target>
663 <context-group name="null"> 663 <context-group name="null">
664 <context context-type="linenumber">67</context> 664 <context context-type="linenumber">65</context>
665 </context-group> 665 </context-group>
666 </trans-unit> 666 </trans-unit>
667 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 667 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
668 <source>More</source> 668 <source>More</source>
669 <target>المزيد</target> 669 <target>المزيد</target>
670 <context-group name="null"> 670 <context-group name="null">
671 <context context-type="linenumber">72</context> 671 <context context-type="linenumber">70</context>
672 </context-group> 672 </context-group>
673 </trans-unit> 673 </trans-unit>
674 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 674 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
675 <source>Administration</source> 675 <source>Administration</source>
676 <target>الإدارة</target> 676 <target>الإدارة</target>
677 <context-group name="null"> 677 <context-group name="null">
678 <context context-type="linenumber">76</context> 678 <context context-type="linenumber">74</context>
679 </context-group> 679 </context-group>
680 </trans-unit> 680 </trans-unit>
681 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 681 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -689,7 +689,7 @@
689 <source>Toggle dark interface</source> 689 <source>Toggle dark interface</source>
690 <target>الإنتقال إلى الواجهة الداكنة</target> 690 <target>الإنتقال إلى الواجهة الداكنة</target>
691 <context-group name="null"> 691 <context-group name="null">
692 <context context-type="linenumber">94</context> 692 <context context-type="linenumber">92</context>
693 </context-group> 693 </context-group>
694 </trans-unit> 694 </trans-unit>
695 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 695 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -794,7 +794,7 @@
794 <source>No results.</source> 794 <source>No results.</source>
795 <target>لا نتائج</target> 795 <target>لا نتائج</target>
796 <context-group name="null"> 796 <context-group name="null">
797 <context context-type="linenumber">17</context> 797 <context context-type="linenumber">20</context>
798 </context-group> 798 </context-group>
799 </trans-unit> 799 </trans-unit>
800 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b"> 800 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b">
@@ -811,15 +811,20 @@
811 <context context-type="linenumber">7</context> 811 <context context-type="linenumber">7</context>
812 </context-group> 812 </context-group>
813 </trans-unit> 813 </trans-unit>
814 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 814 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
815 <source> 815 <source>
816 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 816 Cancel
817</source> 817 </source>
818 <target> 818 <target>إلغاء</target>
819 حول مثيل الخدوم <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/>
820</target>
821 <context-group name="null"> 819 <context-group name="null">
822 <context context-type="linenumber">1</context> 820 <context context-type="linenumber">26</context>
821 </context-group>
822 </trans-unit>
823 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
824 <source>Submit</source>
825 <target>إرسال</target>
826 <context-group name="null">
827 <context context-type="linenumber">31</context>
823 </context-group> 828 </context-group>
824 </trans-unit> 829 </trans-unit>
825 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 830 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -833,44 +838,14 @@
833 <source>Terms</source> 838 <source>Terms</source>
834 <target>الشروط</target> 839 <target>الشروط</target>
835 <context-group name="null"> 840 <context-group name="null">
836 <context context-type="linenumber">44</context> 841 <context context-type="linenumber">39</context>
837 </context-group> 842 </context-group>
838 </trans-unit> 843 </trans-unit>
839 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 844 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
840 <source>User registration is allowed and</source> 845 <source>User registration is allowed and</source>
841 <target>التسجيل مسموح و</target> 846 <target>التسجيل مسموح و</target>
842 <context-group name="null"> 847 <context-group name="null">
843 <context context-type="linenumber">25</context> 848 <context context-type="linenumber">29</context>
844 </context-group>
845 </trans-unit>
846 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
847 <source>
848 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
849 </source>
850 <target>
851مثيل الخادوم هذا يوÙر مساحة <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> Ù„Ùيديوهات المستخدمين.</target>
852 <context-group name="null">
853 <context context-type="linenumber">27</context>
854 </context-group>
855 </trans-unit>
856 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
857 <source>
858 this instance provides unlimited space for the videos of its users.
859 </source>
860 <target>
861مثيل الخادوم هذا يوÙر مساحة غير محددة Ù„Ùيديوهات المستخدمين.</target>
862 <context-group name="null">
863 <context context-type="linenumber">31</context>
864 </context-group>
865 </trans-unit>
866 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
867 <source>
868 User registration is currently not allowed.
869 </source>
870 <target>
871التسجيل غير مسموح حاليا.</target>
872 <context-group name="null">
873 <context context-type="linenumber">36</context>
874 </context-group> 849 </context-group>
875 </trans-unit> 850 </trans-unit>
876 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 851 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1052,42 +1027,42 @@
1052 <source>Short description</source> 1027 <source>Short description</source>
1053 <target>الوص٠القصير</target> 1028 <target>الوص٠القصير</target>
1054 <context-group name="null"> 1029 <context-group name="null">
1055 <context context-type="linenumber">22</context> 1030 <context context-type="linenumber">21</context>
1056 </context-group> 1031 </context-group>
1057 </trans-unit> 1032 </trans-unit>
1058 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1033 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1059 <source>Videos Overview</source> 1034 <source>Videos Overview</source>
1060 <target>نظرة شاملة عن الÙيديوهات</target> 1035 <target>نظرة شاملة عن الÙيديوهات</target>
1061 <context-group name="null"> 1036 <context-group name="null">
1062 <context context-type="linenumber">58</context> 1037 <context context-type="linenumber">51</context>
1063 </context-group> 1038 </context-group>
1064 </trans-unit> 1039 </trans-unit>
1065 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1040 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1066 <source>Videos Trending</source> 1041 <source>Videos Trending</source>
1067 <target>الÙيديوهات الشائعة</target> 1042 <target>الÙيديوهات الشائعة</target>
1068 <context-group name="null"> 1043 <context-group name="null">
1069 <context context-type="linenumber">59</context> 1044 <context context-type="linenumber">52</context>
1070 </context-group> 1045 </context-group>
1071 </trans-unit> 1046 </trans-unit>
1072 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1047 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1073 <source>Videos Recently Added</source> 1048 <source>Videos Recently Added</source>
1074 <target>الÙيديوهات المÙضاÙØ© حديثًا</target> 1049 <target>الÙيديوهات المÙضاÙØ© حديثًا</target>
1075 <context-group name="null"> 1050 <context-group name="null">
1076 <context context-type="linenumber">60</context> 1051 <context context-type="linenumber">53</context>
1077 </context-group> 1052 </context-group>
1078 </trans-unit> 1053 </trans-unit>
1079 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1054 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1080 <source>Local videos</source> 1055 <source>Local videos</source>
1081 <target>الÙيديوهات المحلية</target> 1056 <target>الÙيديوهات المحلية</target>
1082 <context-group name="null"> 1057 <context-group name="null">
1083 <context context-type="linenumber">61</context> 1058 <context context-type="linenumber">54</context>
1084 </context-group> 1059 </context-group>
1085 </trans-unit> 1060 </trans-unit>
1086 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1061 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1087 <source>Policy on videos containing sensitive content</source> 1062 <source>Policy on videos containing sensitive content</source>
1088 <target>سياسة الÙيديوهات التي تحتوي على محتوى حساس</target> 1063 <target>سياسة الÙيديوهات التي تحتوي على محتوى حساس</target>
1089 <context-group name="null"> 1064 <context-group name="null">
1090 <context context-type="linenumber">70</context> 1065 <context context-type="linenumber">61</context>
1091 </context-group> 1066 </context-group>
1092 </trans-unit> 1067 </trans-unit>
1093 <trans-unit id="5e155c34fb3ed8159bf0a486a366cfbc6874f9fe"> 1068 <trans-unit id="5e155c34fb3ed8159bf0a486a366cfbc6874f9fe">
@@ -1108,23 +1083,44 @@
1108 <source>Signup enabled</source> 1083 <source>Signup enabled</source>
1109 <target>التسجيل Ù…ÙÙعل</target> 1084 <target>التسجيل Ù…ÙÙعل</target>
1110 <context-group name="null"> 1085 <context-group name="null">
1111 <context context-type="linenumber">93</context> 1086 <context context-type="linenumber">84</context>
1112 </context-group> 1087 </context-group>
1113 </trans-unit> 1088 </trans-unit>
1114 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1089 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1115 <source>Signup requires email verification</source> 1090 <source>Signup requires email verification</source>
1116 <target>يتطلب التسجيل رسالة تأكيد</target> 1091 <target>يتطلب التسجيل رسالة تأكيد</target>
1117 <context-group name="null"> 1092 <context-group name="null">
1118 <context context-type="linenumber">100</context> 1093 <context context-type="linenumber">91</context>
1119 </context-group> 1094 </context-group>
1120 </trans-unit> 1095 </trans-unit>
1121 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1096 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1122 <source>Signup limit</source> 1097 <source>Signup limit</source>
1123 <target>حد التسجيل</target> 1098 <target>حد التسجيل</target>
1124 <context-group name="null"> 1099 <context-group name="null">
1100 <context context-type="linenumber">96</context>
1101 </context-group>
1102 </trans-unit>
1103 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1104 <source>Users</source>
1105 <target>المستخدÙمون</target>
1106 <context-group name="null">
1125 <context context-type="linenumber">105</context> 1107 <context context-type="linenumber">105</context>
1126 </context-group> 1108 </context-group>
1127 </trans-unit> 1109 </trans-unit>
1110 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1111 <source>User default video quota</source>
1112 <target>حصة الÙيديو الاÙتراضية للمستخدم</target>
1113 <context-group name="null">
1114 <context context-type="linenumber">109</context>
1115 </context-group>
1116 </trans-unit>
1117 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1118 <source>User default daily upload limit</source>
1119 <target>حد الرÙع الإÙتراضي للمستخدÙÙ…</target>
1120 <context-group name="null">
1121 <context context-type="linenumber">121</context>
1122 </context-group>
1123 </trans-unit>
1128 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1124 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1129 <source>Import</source> 1125 <source>Import</source>
1130 <target>استيراد</target> 1126 <target>استيراد</target>
@@ -1136,35 +1132,14 @@
1136 <source>Administrator</source> 1132 <source>Administrator</source>
1137 <target>المدير</target> 1133 <target>المدير</target>
1138 <context-group name="null"> 1134 <context-group name="null">
1139 <context context-type="linenumber">131</context> 1135 <context context-type="linenumber">155</context>
1140 </context-group> 1136 </context-group>
1141 </trans-unit> 1137 </trans-unit>
1142 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1138 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1143 <source>Admin email</source> 1139 <source>Admin email</source>
1144 <target>البريد الإلكتروني للمدير</target> 1140 <target>البريد الإلكتروني للمدير</target>
1145 <context-group name="null"> 1141 <context-group name="null">
1146 <context context-type="linenumber">134</context> 1142 <context context-type="linenumber">158</context>
1147 </context-group>
1148 </trans-unit>
1149 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1150 <source>Users</source>
1151 <target>المستخدÙمون</target>
1152 <context-group name="null">
1153 <context context-type="linenumber">144</context>
1154 </context-group>
1155 </trans-unit>
1156 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1157 <source>User default video quota</source>
1158 <target>حصة الÙيديو الاÙتراضية للمستخدم</target>
1159 <context-group name="null">
1160 <context context-type="linenumber">147</context>
1161 </context-group>
1162 </trans-unit>
1163 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1164 <source>User default daily upload limit</source>
1165 <target>حد الرÙع الإÙتراضي للمستخدÙÙ…</target>
1166 <context-group name="null">
1167 <context context-type="linenumber">161</context>
1168 </context-group> 1143 </context-group>
1169 </trans-unit> 1144 </trans-unit>
1170 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1145 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1185,7 +1160,7 @@
1185 <source>Your Twitter username</source> 1160 <source>Your Twitter username</source>
1186 <target>اسم المستخدÙÙ… الخاص بك على تويتر</target> 1161 <target>اسم المستخدÙÙ… الخاص بك على تويتر</target>
1187 <context-group name="null"> 1162 <context-group name="null">
1188 <context context-type="linenumber">181</context> 1163 <context context-type="linenumber">184</context>
1189 </context-group> 1164 </context-group>
1190 </trans-unit> 1165 </trans-unit>
1191 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1166 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1199,21 +1174,21 @@
1199 <source>Customizations</source> 1174 <source>Customizations</source>
1200 <target>التخصيصات</target> 1175 <target>التخصيصات</target>
1201 <context-group name="null"> 1176 <context-group name="null">
1202 <context context-type="linenumber">275</context> 1177 <context context-type="linenumber">289</context>
1203 </context-group> 1178 </context-group>
1204 </trans-unit> 1179 </trans-unit>
1205 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1180 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1206 <source>JavaScript</source> 1181 <source>JavaScript</source>
1207 <target>الجاÙا سكريبت</target> 1182 <target>الجاÙا سكريبت</target>
1208 <context-group name="null"> 1183 <context-group name="null">
1209 <context context-type="linenumber">278</context> 1184 <context context-type="linenumber">294</context>
1210 </context-group> 1185 </context-group>
1211 </trans-unit> 1186 </trans-unit>
1212 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab"> 1187 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab">
1213 <source>Advanced configuration</source> 1188 <source>Advanced configuration</source>
1214 <target>الإعدادات المتقدمة</target> 1189 <target>الإعدادات المتقدمة</target>
1215 <context-group name="null"> 1190 <context-group name="null">
1216 <context context-type="linenumber">207</context> 1191 <context context-type="linenumber">212</context>
1217 </context-group> 1192 </context-group>
1218 </trans-unit> 1193 </trans-unit>
1219 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1194 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1391,7 +1366,7 @@
1391 <source>Ban reason:</source> 1366 <source>Ban reason:</source>
1392 <target>سبب الحظر:</target> 1367 <target>سبب الحظر:</target>
1393 <context-group name="null"> 1368 <context-group name="null">
1394 <context context-type="linenumber">92</context> 1369 <context context-type="linenumber">95</context>
1395 </context-group> 1370 </context-group>
1396 </trans-unit> 1371 </trans-unit>
1397 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 1372 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -1440,7 +1415,7 @@
1440 <source>Actions</source> 1415 <source>Actions</source>
1441 <target>الإجراءات</target> 1416 <target>الإجراءات</target>
1442 <context-group name="null"> 1417 <context-group name="null">
1443 <context context-type="linenumber">33</context> 1418 <context context-type="linenumber">35</context>
1444 </context-group> 1419 </context-group>
1445 </trans-unit> 1420 </trans-unit>
1446 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 1421 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -1468,7 +1443,7 @@
1468 <source>Blacklist reason:</source> 1443 <source>Blacklist reason:</source>
1469 <target>سبب الحجب:</target> 1444 <target>سبب الحجب:</target>
1470 <context-group name="null"> 1445 <context-group name="null">
1471 <context context-type="linenumber">41</context> 1446 <context context-type="linenumber">43</context>
1472 </context-group> 1447 </context-group>
1473 </trans-unit> 1448 </trans-unit>
1474 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 1449 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -1499,62 +1474,6 @@
1499 <context context-type="linenumber">23</context> 1474 <context context-type="linenumber">23</context>
1500 </context-group> 1475 </context-group>
1501 </trans-unit> 1476 </trans-unit>
1502 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
1503 <source>My settings</source>
1504 <target>إعداداتي</target>
1505 <context-group name="null">
1506 <context context-type="linenumber">3</context>
1507 </context-group>
1508 </trans-unit>
1509 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
1510 <source>My library</source>
1511 <target>مكتبتي</target>
1512 <context-group name="null">
1513 <context context-type="linenumber">7</context>
1514 </context-group>
1515 </trans-unit>
1516 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
1517 <source>My channels</source>
1518 <target>قنواتي</target>
1519 <context-group name="null">
1520 <context context-type="linenumber">12</context>
1521 </context-group>
1522 </trans-unit>
1523 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
1524 <source>My videos</source>
1525 <target>Ùيديوهاتي</target>
1526 <context-group name="null">
1527 <context context-type="linenumber">14</context>
1528 </context-group>
1529 </trans-unit>
1530 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
1531 <source>My subscriptions</source>
1532 <target>اشتراكاتي</target>
1533 <context-group name="null">
1534 <context context-type="linenumber">16</context>
1535 </context-group>
1536 </trans-unit>
1537 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
1538 <source>My imports</source>
1539 <target>وارداتي</target>
1540 <context-group name="null">
1541 <context context-type="linenumber">18</context>
1542 </context-group>
1543 </trans-unit>
1544 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
1545 <source>Misc</source>
1546 <target>أخرى</target>
1547 <context-group name="null">
1548 <context context-type="linenumber">24</context>
1549 </context-group>
1550 </trans-unit>
1551 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
1552 <source>Muted instances</source>
1553 <target>مثيلات الخوادم المكتومة</target>
1554 <context-group name="null">
1555 <context context-type="linenumber">2</context>
1556 </context-group>
1557 </trans-unit>
1558 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 1477 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
1559 <source>Video quota:</source> 1478 <source>Video quota:</source>
1560 <target>تقم الÙيديو:</target> 1479 <target>تقم الÙيديو:</target>
@@ -1566,21 +1485,21 @@
1566 <source>Profile</source> 1485 <source>Profile</source>
1567 <target>المل٠الشخصي</target> 1486 <target>المل٠الشخصي</target>
1568 <context-group name="null"> 1487 <context-group name="null">
1569 <context context-type="linenumber">8</context> 1488 <context context-type="linenumber">7</context>
1570 </context-group> 1489 </context-group>
1571 </trans-unit> 1490 </trans-unit>
1572 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 1491 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
1573 <source>Video settings</source> 1492 <source>Video settings</source>
1574 <target>إعدادات الÙيديو</target> 1493 <target>إعدادات الÙيديو</target>
1575 <context-group name="null"> 1494 <context-group name="null">
1576 <context context-type="linenumber">15</context> 1495 <context context-type="linenumber">16</context>
1577 </context-group> 1496 </context-group>
1578 </trans-unit> 1497 </trans-unit>
1579 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 1498 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
1580 <source>Danger zone</source> 1499 <source>Danger zone</source>
1581 <target>منطقة الخطر</target> 1500 <target>منطقة الخطر</target>
1582 <context-group name="null"> 1501 <context-group name="null">
1583 <context context-type="linenumber">18</context> 1502 <context context-type="linenumber">19</context>
1584 </context-group> 1503 </context-group>
1585 </trans-unit> 1504 </trans-unit>
1586 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 1505 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -1606,13 +1525,6 @@
1606 <context context-type="linenumber">35</context> 1525 <context context-type="linenumber">35</context>
1607 </context-group> 1526 </context-group>
1608 </trans-unit> 1527 </trans-unit>
1609 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
1610 <source>Submit</source>
1611 <target>إرسال</target>
1612 <context-group name="null">
1613 <context context-type="linenumber">24</context>
1614 </context-group>
1615 </trans-unit>
1616 <trans-unit id="4a806761798181e907e28ed1af053d466526800d"> 1528 <trans-unit id="4a806761798181e907e28ed1af053d466526800d">
1617 <source>Blacklisted</source> 1529 <source>Blacklisted</source>
1618 <target>تم حجبه</target> 1530 <target>تم حجبه</target>
@@ -1699,6 +1611,13 @@
1699 <context context-type="linenumber">47</context> 1611 <context context-type="linenumber">47</context>
1700 </context-group> 1612 </context-group>
1701 </trans-unit> 1613 </trans-unit>
1614 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
1615 <source>Muted instances</source>
1616 <target>مثيلات الخوادم المكتومة</target>
1617 <context-group name="null">
1618 <context context-type="linenumber">2</context>
1619 </context-group>
1620 </trans-unit>
1702 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 1621 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
1703 <source>Change password</source> 1622 <source>Change password</source>
1704 <target>تغيير الكلمة السرية</target> 1623 <target>تغيير الكلمة السرية</target>
@@ -1804,6 +1723,13 @@
1804 <context context-type="linenumber">159</context> 1723 <context context-type="linenumber">159</context>
1805 </context-group> 1724 </context-group>
1806 </trans-unit> 1725 </trans-unit>
1726 <trans-unit id="385811ab5a5c3e96e0db46c9ce1fc3147d8cd4c7">
1727 <source>Sorry, but something went wrong</source>
1728 <target>عذرا، لقد حدث خلل ما</target>
1729 <context-group name="null">
1730 <context context-type="linenumber">49</context>
1731 </context-group>
1732 </trans-unit>
1807 <trans-unit id="047f50bc5b5d17b5bec0196355953e1a5c590ddb"> 1733 <trans-unit id="047f50bc5b5d17b5bec0196355953e1a5c590ddb">
1808 <source>Update</source> 1734 <source>Update</source>
1809 <target>تحديث</target> 1735 <target>تحديث</target>
@@ -1811,6 +1737,13 @@
1811 <context context-type="linenumber">92</context> 1737 <context context-type="linenumber">92</context>
1812 </context-group> 1738 </context-group>
1813 </trans-unit> 1739 </trans-unit>
1740 <trans-unit id="21add64f0f3ebbedf1150ca822c6e149494ab7a9">
1741 <source>Select the file to upload</source>
1742 <target>اختر المل٠الذي تريد ارساله</target>
1743 <context-group name="null">
1744 <context context-type="linenumber">6</context>
1745 </context-group>
1746 </trans-unit>
1814 <trans-unit id="5e420747842373fa99a75a7a18df068cc81e46fb"> 1747 <trans-unit id="5e420747842373fa99a75a7a18df068cc81e46fb">
1815 <source>Scheduled</source> 1748 <source>Scheduled</source>
1816 <target>مبرمجة</target> 1749 <target>مبرمجة</target>
@@ -1822,7 +1755,7 @@
1822 <source>Publish</source> 1755 <source>Publish</source>
1823 <target>أنشر</target> 1756 <target>أنشر</target>
1824 <context-group name="null"> 1757 <context-group name="null">
1825 <context context-type="linenumber">60</context> 1758 <context context-type="linenumber">65</context>
1826 </context-group> 1759 </context-group>
1827 </trans-unit> 1760 </trans-unit>
1828 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 1761 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -1906,14 +1839,28 @@
1906 <source>Cancel create</source> 1839 <source>Cancel create</source>
1907 <target>إلغاء الإنشاء</target> 1840 <target>إلغاء الإنشاء</target>
1908 <context-group name="null"> 1841 <context-group name="null">
1909 <context context-type="linenumber">169</context> 1842 <context context-type="linenumber">170</context>
1910 </context-group> 1843 </context-group>
1911 </trans-unit> 1844 </trans-unit>
1912 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 1845 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
1913 <source>Cancel deletion</source> 1846 <source>Cancel deletion</source>
1914 <target>إلغاء الحذÙ</target> 1847 <target>إلغاء الحذÙ</target>
1915 <context-group name="null"> 1848 <context-group name="null">
1916 <context context-type="linenumber">177</context> 1849 <context context-type="linenumber">178</context>
1850 </context-group>
1851 </trans-unit>
1852 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
1853 <source>Upload thumbnail</source>
1854 <target>تحديث الصورة المصغرة</target>
1855 <context-group name="null">
1856 <context context-type="linenumber">196</context>
1857 </context-group>
1858 </trans-unit>
1859 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
1860 <source>Upload preview</source>
1861 <target>إرسال معاينة</target>
1862 <context-group name="null">
1863 <context context-type="linenumber">203</context>
1917 </context-group> 1864 </context-group>
1918 </trans-unit> 1865 </trans-unit>
1919 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 1866 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -1927,7 +1874,7 @@
1927 <source>Advanced settings</source> 1874 <source>Advanced settings</source>
1928 <target>الإعدادات المتقدمة</target> 1875 <target>الإعدادات المتقدمة</target>
1929 <context-group name="null"> 1876 <context-group name="null">
1930 <context context-type="linenumber">190</context> 1877 <context context-type="linenumber">191</context>
1931 </context-group> 1878 </context-group>
1932 </trans-unit> 1879 </trans-unit>
1933 <trans-unit id="9aafb2a928664aa7a9375fd37c533f0375f8b611"> 1880 <trans-unit id="9aafb2a928664aa7a9375fd37c533f0375f8b611">
@@ -1981,15 +1928,6 @@
1981 <context context-type="linenumber">3</context> 1928 <context context-type="linenumber">3</context>
1982 </context-group> 1929 </context-group>
1983 </trans-unit> 1930 </trans-unit>
1984 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
1985 <source>
1986 Cancel
1987 </source>
1988 <target>إلغاء</target>
1989 <context-group name="null">
1990 <context context-type="linenumber">19</context>
1991 </context-group>
1992 </trans-unit>
1993 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 1931 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
1994 <source>Share</source> 1932 <source>Share</source>
1995 <target>شارك</target> 1933 <target>شارك</target>
@@ -2032,6 +1970,13 @@
2032 <context context-type="linenumber">57</context> 1970 <context context-type="linenumber">57</context>
2033 </context-group> 1971 </context-group>
2034 </trans-unit> 1972 </trans-unit>
1973 <trans-unit id="623698f075025b2b2fc2e0c59fd95f4f4662a509">
1974 <source>Dislike this video</source>
1975 <target>إلغاء الإعجاب بهذه الÙيديو</target>
1976 <context-group name="null">
1977 <context context-type="linenumber">64</context>
1978 </context-group>
1979 </trans-unit>
2035 <trans-unit id="144fff5c40b85414d59e644d8dee7cfefba925a2"> 1980 <trans-unit id="144fff5c40b85414d59e644d8dee7cfefba925a2">
2036 <source>Download the video</source> 1981 <source>Download the video</source>
2037 <target>تنزيل الÙيديو</target> 1982 <target>تنزيل الÙيديو</target>
@@ -2060,6 +2005,13 @@
2060 <context context-type="linenumber">91</context> 2005 <context context-type="linenumber">91</context>
2061 </context-group> 2006 </context-group>
2062 </trans-unit> 2007 </trans-unit>
2008 <trans-unit id="007ab5fa2aae8a7372307d3fc45a2dbcb11ffd61">
2009 <source>Blacklist</source>
2010 <target>حجب ÙÙŠ القائمة السوداء</target>
2011 <context-group name="null">
2012 <context context-type="linenumber">96</context>
2013 </context-group>
2014 </trans-unit>
2063 <trans-unit id="803c6317abd2dbafcc93226c4e273c62932e3037"> 2015 <trans-unit id="803c6317abd2dbafcc93226c4e273c62932e3037">
2064 <source>Blacklist this video</source> 2016 <source>Blacklist this video</source>
2065 <target>حجب هذه الÙيديو</target> 2017 <target>حجب هذه الÙيديو</target>
@@ -2109,6 +2061,13 @@
2109 <context context-type="linenumber">152</context> 2061 <context context-type="linenumber">152</context>
2110 </context-group> 2062 </context-group>
2111 </trans-unit> 2063 </trans-unit>
2064 <trans-unit id="4c0ba3cde3b3c58b855ffb4beaa5804a2fc3826b">
2065 <source>Friendly Reminder: </source>
2066 <target>تذكير أخوي:</target>
2067 <context-group name="null">
2068 <context context-type="linenumber">208</context>
2069 </context-group>
2070 </trans-unit>
2112 <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e"> 2071 <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e">
2113 <source>More information</source> 2072 <source>More information</source>
2114 <target>المزيد من التÙاصيل</target> 2073 <target>المزيد من التÙاصيل</target>
@@ -2210,13 +2169,6 @@
2210 <context context-type="linenumber">1</context> 2169 <context context-type="linenumber">1</context>
2211 </context-group> 2170 </context-group>
2212 </trans-unit> 2171 </trans-unit>
2213 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
2214 <source>Error</source>
2215 <target>خطأ</target>
2216 <context-group name="null">
2217 <context context-type="linenumber">1</context>
2218 </context-group>
2219 </trans-unit>
2220 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6"> 2172 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
2221 <source>240p</source> 2173 <source>240p</source>
2222 <target>240p</target> 2174 <target>240p</target>
@@ -2252,9 +2204,9 @@
2252 <context context-type="linenumber">1</context> 2204 <context context-type="linenumber">1</context>
2253 </context-group> 2205 </context-group>
2254 </trans-unit> 2206 </trans-unit>
2255 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba"> 2207 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
2256 <source>Success</source> 2208 <source>Configuration updated.</source>
2257 <target>تم بÙجاح</target> 2209 <target>تم تحديث الإعدادات</target>
2258 <context-group name="null"> 2210 <context-group name="null">
2259 <context context-type="linenumber">1</context> 2211 <context context-type="linenumber">1</context>
2260 </context-group> 2212 </context-group>
@@ -2280,6 +2232,20 @@
2280 <context context-type="linenumber">1</context> 2232 <context context-type="linenumber">1</context>
2281 </context-group> 2233 </context-group>
2282 </trans-unit> 2234 </trans-unit>
2235 <trans-unit id="4d8f527638f3e0b518a96e07d41d886bcce01246">
2236 <source>enabled</source>
2237 <target>Ù…Ùعّل</target>
2238 <context-group name="null">
2239 <context context-type="linenumber">1</context>
2240 </context-group>
2241 </trans-unit>
2242 <trans-unit id="795733aac948794cadeb3be6386882efac2c38ad">
2243 <source>disabled</source>
2244 <target>خامل</target>
2245 <context-group name="null">
2246 <context context-type="linenumber">1</context>
2247 </context-group>
2248 </trans-unit>
2283 <trans-unit id="800cd3cdf47751b576587259ba3a1bc0a7f435b6"> 2249 <trans-unit id="800cd3cdf47751b576587259ba3a1bc0a7f435b6">
2284 <source>Comment updated.</source> 2250 <source>Comment updated.</source>
2285 <target>تم تحديث التعليق.</target> 2251 <target>تم تحديث التعليق.</target>
@@ -2336,6 +2302,13 @@
2336 <context context-type="linenumber">1</context> 2302 <context context-type="linenumber">1</context>
2337 </context-group> 2303 </context-group>
2338 </trans-unit> 2304 </trans-unit>
2305 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e">
2306 <source>Ownership accepted</source>
2307 <target>تم قبول الملكية</target>
2308 <context-group name="null">
2309 <context context-type="linenumber">1</context>
2310 </context-group>
2311 </trans-unit>
2339 <trans-unit id="19508af0dfbc685cbf10cf02061bb5a0f423b6fc"> 2312 <trans-unit id="19508af0dfbc685cbf10cf02061bb5a0f423b6fc">
2340 <source>Password updated.</source> 2313 <source>Password updated.</source>
2341 <target>تم تحديث الكلمة السرية.</target> 2314 <target>تم تحديث الكلمة السرية.</target>
@@ -2343,6 +2316,13 @@
2343 <context context-type="linenumber">1</context> 2316 <context context-type="linenumber">1</context>
2344 </context-group> 2317 </context-group>
2345 </trans-unit> 2318 </trans-unit>
2319 <trans-unit id="466fc8cf56fd4e4e90fec4b900ef083d52bec38c">
2320 <source>You current password is invalid.</source>
2321 <target>كلمتك السرية الحالية غير صالحة. </target>
2322 <context-group name="null">
2323 <context context-type="linenumber">1</context>
2324 </context-group>
2325 </trans-unit>
2346 <trans-unit id="ca8e8cf0f1686604db3b6a2ebadab7f7b426a047"> 2326 <trans-unit id="ca8e8cf0f1686604db3b6a2ebadab7f7b426a047">
2347 <source>Are you sure you want to delete your account? This will delete all you data, including channels, videos etc.</source> 2327 <source>Are you sure you want to delete your account? This will delete all you data, including channels, videos etc.</source>
2348 <target>متأكد أنك تريد حذ٠حسابك ؟هذا سيحذ٠بياناتك,قنواتك,Ùيديوهاتك الخ.</target> 2328 <target>متأكد أنك تريد حذ٠حسابك ؟هذا سيحذ٠بياناتك,قنواتك,Ùيديوهاتك الخ.</target>
@@ -2406,16 +2386,149 @@
2406 <context context-type="linenumber">1</context> 2386 <context context-type="linenumber">1</context>
2407 </context-group> 2387 </context-group>
2408 </trans-unit> 2388 </trans-unit>
2409 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e"> 2389 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2410 <source>Please type the name of the video channel to confirm</source> 2390 <source>My videos</source>
2411 <target>رجاء أدخل اسم القنات للتأكيد</target> 2391 <target>Ùيديوهاتي</target>
2392 <context-group name="null">
2393 <context context-type="linenumber">1</context>
2394 </context-group>
2395 </trans-unit>
2396 <trans-unit id="dd9f3264feed4935008861c15d81c947124e4ac3">
2397 <source>Published</source>
2398 <target>المنشورة</target>
2399 <context-group name="null">
2400 <context context-type="linenumber">1</context>
2401 </context-group>
2402 </trans-unit>
2403 <trans-unit id="289fe8342e8b7df689c75026a24a60fd7f5e9392">
2404 <source>To import</source>
2405 <target>للاستيراد</target>
2406 <context-group name="null">
2407 <context context-type="linenumber">1</context>
2408 </context-group>
2409 </trans-unit>
2410 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2411 <source>My library</source>
2412 <target>مكتبتي</target>
2412 <context-group name="null"> 2413 <context-group name="null">
2413 <context context-type="linenumber">1</context> 2414 <context context-type="linenumber">1</context>
2414 </context-group> 2415 </context-group>
2415 </trans-unit> 2416 </trans-unit>
2416 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 2417 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2417 <source>Channels</source> 2418 <source>My channels</source>
2418 <target>القنوات</target> 2419 <target>قنواتي</target>
2420 <context-group name="null">
2421 <context context-type="linenumber">1</context>
2422 </context-group>
2423 </trans-unit>
2424 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2425 <source>My subscriptions</source>
2426 <target>اشتراكاتي</target>
2427 <context-group name="null">
2428 <context context-type="linenumber">1</context>
2429 </context-group>
2430 </trans-unit>
2431 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
2432 <source>Misc</source>
2433 <target>أخرى</target>
2434 <context-group name="null">
2435 <context context-type="linenumber">1</context>
2436 </context-group>
2437 </trans-unit>
2438 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2439 <source>My settings</source>
2440 <target>إعداداتي</target>
2441 <context-group name="null">
2442 <context context-type="linenumber">1</context>
2443 </context-group>
2444 </trans-unit>
2445 <trans-unit id="ff6becacbce7fc0943b0af0df4dd67e5e11bf598">
2446 <source>Subscribe to the account</source>
2447 <target>الاشتراك ÙÙŠ الحساب</target>
2448 <context-group name="null">
2449 <context context-type="linenumber">1</context>
2450 </context-group>
2451 </trans-unit>
2452 <trans-unit id="b19ee83cbd2b735fd081b9aa483a890578019099">
2453 <source>Toggle the left menu</source>
2454 <target>الانتقال إلى القائمة اليسرى</target>
2455 <context-group name="null">
2456 <context context-type="linenumber">1</context>
2457 </context-group>
2458 </trans-unit>
2459 <trans-unit id="b54759e30f7c1983940cdacb8eb03f102a869084">
2460 <source>Go to the videos overview page</source>
2461 <target>الذهاب إلى صÙحة معاينة الÙيديوهات</target>
2462 <context-group name="null">
2463 <context context-type="linenumber">1</context>
2464 </context-group>
2465 </trans-unit>
2466 <trans-unit id="1e919c88a3f889d6659288e69d3e178da0ea7ab0">
2467 <source>Go to the trending videos page</source>
2468 <target>الذهاب إلى صÙحة الÙيديوهات الشائعة</target>
2469 <context-group name="null">
2470 <context context-type="linenumber">1</context>
2471 </context-group>
2472 </trans-unit>
2473 <trans-unit id="249618dcdd7fbdc863c0714e2eb9e8940bc9c37d">
2474 <source>Go to the recently added videos page</source>
2475 <target>الذهاب إلى صÙحةالÙيديوهات المضاÙØ© حديثا</target>
2476 <context-group name="null">
2477 <context context-type="linenumber">1</context>
2478 </context-group>
2479 </trans-unit>
2480 <trans-unit id="7e194daef3a3509128c4300d4c7c292c49ebf3f5">
2481 <source>Go to the local videos page</source>
2482 <target>الذهاب إلى صÙحة الÙيديوهات المحلية</target>
2483 <context-group name="null">
2484 <context context-type="linenumber">1</context>
2485 </context-group>
2486 </trans-unit>
2487 <trans-unit id="f1fb6204f39a7338e5110b2f113643c9288496ba">
2488 <source>Go to the videos upload page</source>
2489 <target>الذهاب إلى صÙحة إرسال الÙيديوهات</target>
2490 <context-group name="null">
2491 <context context-type="linenumber">1</context>
2492 </context-group>
2493 </trans-unit>
2494 <trans-unit id="0ed7b40c11da9d4565af9c041df20c15bc6be97e">
2495 <source>Toggle Dark theme</source>
2496 <target>التغيير إلى السمة الداكنة</target>
2497 <context-group name="null">
2498 <context context-type="linenumber">1</context>
2499 </context-group>
2500 </trans-unit>
2501 <trans-unit id="badd4b24618ccc8a34620acb9053fc654b9612b2">
2502 <source>Go to my subscriptions</source>
2503 <target>الذهاب إلى اشتراكاتي</target>
2504 <context-group name="null">
2505 <context context-type="linenumber">1</context>
2506 </context-group>
2507 </trans-unit>
2508 <trans-unit id="b7184b5a236618e8edd747529869c392ab6dace1">
2509 <source>Go to my videos</source>
2510 <target>الذهاب إلى Ùيديوهاتي</target>
2511 <context-group name="null">
2512 <context context-type="linenumber">1</context>
2513 </context-group>
2514 </trans-unit>
2515 <trans-unit id="acf985bd42886b9b3030b5f68f0e8417c39b40a7">
2516 <source>Go to my imports</source>
2517 <target>الذهاب إلى استيراداتي</target>
2518 <context-group name="null">
2519 <context context-type="linenumber">1</context>
2520 </context-group>
2521 </trans-unit>
2522 <trans-unit id="cfe3c51f0ae9385dc2ce6df740d87e5514aa9390">
2523 <source>Go to my channels</source>
2524 <target>الذهاب إلى قنواتي</target>
2525 <context-group name="null">
2526 <context context-type="linenumber">1</context>
2527 </context-group>
2528 </trans-unit>
2529 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
2530 <source>Error</source>
2531 <target>خطأ</target>
2419 <context-group name="null"> 2532 <context-group name="null">
2420 <context context-type="linenumber">1</context> 2533 <context context-type="linenumber">1</context>
2421 </context-group> 2534 </context-group>
@@ -2434,6 +2547,27 @@
2434 <context context-type="linenumber">1</context> 2547 <context context-type="linenumber">1</context>
2435 </context-group> 2548 </context-group>
2436 </trans-unit> 2549 </trans-unit>
2550 <trans-unit id="5c0c574151dc8671d9199980ee04bf65aec3b452">
2551 <source>Keyboard Shortcuts:</source>
2552 <target>اختصارات لوحة المÙاتيح:</target>
2553 <context-group name="null">
2554 <context context-type="linenumber">1</context>
2555 </context-group>
2556 </trans-unit>
2557 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
2558 <source>Info</source>
2559 <target>معلومات</target>
2560 <context-group name="null">
2561 <context context-type="linenumber">1</context>
2562 </context-group>
2563 </trans-unit>
2564 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
2565 <source>Success</source>
2566 <target>تم بنجاح</target>
2567 <context-group name="null">
2568 <context context-type="linenumber">1</context>
2569 </context-group>
2570 </trans-unit>
2437 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 2571 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
2438 <source>Incorrect username or password.</source> 2572 <source>Incorrect username or password.</source>
2439 <target>اسم المستخدم أو كلمة المرور خاطئة.</target> 2573 <target>اسم المستخدم أو كلمة المرور خاطئة.</target>
@@ -2448,6 +2582,13 @@
2448 <context context-type="linenumber">1</context> 2582 <context context-type="linenumber">1</context>
2449 </context-group> 2583 </context-group>
2450 </trans-unit> 2584 </trans-unit>
2585 <trans-unit id="b0f24b7136e551a0deba831f1525711245b31a26">
2586 <source>Your password has been successfully reset!</source>
2587 <target>لقد تم إعادة تعيين كلمتك السرية بنجاح!</target>
2588 <context-group name="null">
2589 <context context-type="linenumber">1</context>
2590 </context-group>
2591 </trans-unit>
2451 <trans-unit id="7fb1099e29660162f9154d5b2feee7743a423df6"> 2592 <trans-unit id="7fb1099e29660162f9154d5b2feee7743a423df6">
2452 <source>Today</source> 2593 <source>Today</source>
2453 <target>اليوم</target> 2594 <target>اليوم</target>
@@ -2525,6 +2666,20 @@
2525 <context context-type="linenumber">1</context> 2666 <context context-type="linenumber">1</context>
2526 </context-group> 2667 </context-group>
2527 </trans-unit> 2668 </trans-unit>
2669 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
2670 <source>Email is required.</source>
2671 <target>البريد الإلكتروني مطلوب.</target>
2672 <context-group name="null">
2673 <context context-type="linenumber">1</context>
2674 </context-group>
2675 </trans-unit>
2676 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
2677 <source>Email must be valid.</source>
2678 <target>يجب أن يكون عنوان البريد الإلكتروني عنوانًا صالحًا.</target>
2679 <context-group name="null">
2680 <context context-type="linenumber">1</context>
2681 </context-group>
2682 </trans-unit>
2528 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 2683 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
2529 <source>Username is required.</source> 2684 <source>Username is required.</source>
2530 <target>اسم المستخدم مطلوب.</target> 2685 <target>اسم المستخدم مطلوب.</target>
@@ -2546,23 +2701,58 @@
2546 <context context-type="linenumber">1</context> 2701 <context context-type="linenumber">1</context>
2547 </context-group> 2702 </context-group>
2548 </trans-unit> 2703 </trans-unit>
2549 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea"> 2704 <trans-unit id="545e77fd5d9526228a2133109447c23225ed9c85">
2550 <source>Username must be at least 3 characters long.</source> 2705 <source>User role is required.</source>
2551 <target>يجب أن يكون طول اسم المستخدÙÙأكبر Ù…ÙÙ† 3 أحرÙ. </target> 2706 <target>دور المستخدم مطÙوب.</target>
2552 <context-group name="null"> 2707 <context-group name="null">
2553 <context context-type="linenumber">1</context> 2708 <context context-type="linenumber">1</context>
2554 </context-group> 2709 </context-group>
2555 </trans-unit> 2710 </trans-unit>
2556 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0"> 2711 <trans-unit id="1c417b7aef730d6ef5d62fa8a0a7e25e3a2393e4">
2557 <source>Email is required.</source> 2712 <source>Display name is required.</source>
2558 <target>البريد الإلكتروني Ùطلوب.</target> 2713 <target>Ø¹Ø±Ø Ø§Ù„Ø§Ø³Ù… لازم.</target>
2559 <context-group name="null"> 2714 <context-group name="null">
2560 <context context-type="linenumber">1</context> 2715 <context context-type="linenumber">1</context>
2561 </context-group> 2716 </context-group>
2562 </trans-unit> 2717 </trans-unit>
2563 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1"> 2718 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
2564 <source>Email must be valid.</source> 2719 <source>Description must be at least 3 characters long.</source>
2565 <target>يجب أن يكون عنوان البريد الإلكتروني عنوانًا صالحًا.</target> 2720 <target>طول الوص٠يجب أن يتعدى 3حروÙ.</target>
2721 <context-group name="null">
2722 <context context-type="linenumber">1</context>
2723 </context-group>
2724 </trans-unit>
2725 <trans-unit id="b3cf1889d2fdd6b15e697c270c9b80772fe2cae6">
2726 <source>Report reason is required.</source>
2727 <target>سبب الإبلاغ لازم.</target>
2728 <context-group name="null">
2729 <context context-type="linenumber">1</context>
2730 </context-group>
2731 </trans-unit>
2732 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
2733 <source>Moderation comment is required.</source>
2734 <target>تعليق الإشرا٠لازم.</target>
2735 <context-group name="null">
2736 <context context-type="linenumber">1</context>
2737 </context-group>
2738 </trans-unit>
2739 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
2740 <source>The channel is required.</source>
2741 <target>القناة لازمة.</target>
2742 <context-group name="null">
2743 <context context-type="linenumber">1</context>
2744 </context-group>
2745 </trans-unit>
2746 <trans-unit id="bd7fc070c728dc6dbf3959d49fe5bb27ce15d294">
2747 <source>The username is required.</source>
2748 <target>اسم المستخدم مطلوب.</target>
2749 <context-group name="null">
2750 <context context-type="linenumber">1</context>
2751 </context-group>
2752 </trans-unit>
2753 <trans-unit id="c8465c3773699dd075e0147e264d2e232f605803">
2754 <source>You can only transfer ownership to a local account</source>
2755 <target>لا يمكن نقل الملكية إلى حساب محلي</target>
2566 <context-group name="null"> 2756 <context-group name="null">
2567 <context context-type="linenumber">1</context> 2757 <context context-type="linenumber">1</context>
2568 </context-group> 2758 </context-group>
@@ -2595,6 +2785,13 @@
2595 <context context-type="linenumber">1</context> 2785 <context context-type="linenumber">1</context>
2596 </context-group> 2786 </context-group>
2597 </trans-unit> 2787 </trans-unit>
2788 <trans-unit id="34a0811f9a2a7366cc9efcdad52ea59b105326ea">
2789 <source>A tag should be less than 30 characters long.</source>
2790 <target>طول الوسم لا يجب أن يتجاوز 30 حرÙا.</target>
2791 <context-group name="null">
2792 <context context-type="linenumber">1</context>
2793 </context-group>
2794 </trans-unit>
2598 <trans-unit id="3b7ed22d0730d03b38c254332829d855ee7256c4"> 2795 <trans-unit id="3b7ed22d0730d03b38c254332829d855ee7256c4">
2599 <source>This file is too large.</source> 2796 <source>This file is too large.</source>
2600 <target>حجم هذا المل٠كبير جدًّا.</target> 2797 <target>حجم هذا المل٠كبير جدًّا.</target>
@@ -2917,6 +3114,20 @@
2917 <context context-type="linenumber">1</context> 3114 <context context-type="linenumber">1</context>
2918 </context-group> 3115 </context-group>
2919 </trans-unit> 3116 </trans-unit>
3117 <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46">
3118 <source>Clear</source>
3119 <target>مسح</target>
3120 <context-group name="null">
3121 <context context-type="linenumber">1</context>
3122 </context-group>
3123 </trans-unit>
3124 <trans-unit id="4e231a74ad4739e7b0606e8e66d5a656f5855a5a">
3125 <source>Torrent import</source>
3126 <target>استيراد تورنت</target>
3127 <context-group name="null">
3128 <context context-type="linenumber">1</context>
3129 </context-group>
3130 </trans-unit>
2920 <trans-unit id="dc60677d5a906e69f38a5cf9da7f2eb03931bea0"> 3131 <trans-unit id="dc60677d5a906e69f38a5cf9da7f2eb03931bea0">
2921 <source>Links</source> 3132 <source>Links</source>
2922 <target>الروابط</target> 3133 <target>الروابط</target>
@@ -2980,6 +3191,20 @@
2980 <context context-type="linenumber">1</context> 3191 <context context-type="linenumber">1</context>
2981 </context-group> 3192 </context-group>
2982 </trans-unit> 3193 </trans-unit>
3194 <trans-unit id="ab783a52f2df9ff7a20139cab0da6d0764f3cc5d">
3195 <source>Too many attempts, please try again later.</source>
3196 <target>محاولات كثيرة، يرجى العودة لاحقا.</target>
3197 <context-group name="null">
3198 <context context-type="linenumber">1</context>
3199 </context-group>
3200 </trans-unit>
3201 <trans-unit id="0f286a597f0053c3578a52e044769c204ee516fc">
3202 <source>Server error. Please retry later.</source>
3203 <target>خطأ على السيرÙر. يرجى إعادة المحاولة لاحقا.</target>
3204 <context-group name="null">
3205 <context context-type="linenumber">1</context>
3206 </context-group>
3207 </trans-unit>
2983 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1"> 3208 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
2984 <source>Subscribed</source> 3209 <source>Subscribed</source>
2985 <target>مشترك</target> 3210 <target>مشترك</target>
@@ -2994,13 +3219,6 @@
2994 <context context-type="linenumber">1</context> 3219 <context context-type="linenumber">1</context>
2995 </context-group> 3220 </context-group>
2996 </trans-unit> 3221 </trans-unit>
2997 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
2998 <source>Info</source>
2999 <target>معلومات</target>
3000 <context-group name="null">
3001 <context context-type="linenumber">1</context>
3002 </context-group>
3003 </trans-unit>
3004 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 3222 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
3005 <source>Upload cancelled</source> 3223 <source>Upload cancelled</source>
3006 <target>تم إلغاء الإرسال</target> 3224 <target>تم إلغاء الإرسال</target>
@@ -3036,6 +3254,13 @@
3036 <context context-type="linenumber">1</context> 3254 <context context-type="linenumber">1</context>
3037 </context-group> 3255 </context-group>
3038 </trans-unit> 3256 </trans-unit>
3257 <trans-unit id="fa2601e52cbf5725a13d33fe14458823b882ea50">
3258 <source>Video reported.</source>
3259 <target>Ùيديو تم الإبلاغ عنها.</target>
3260 <context-group name="null">
3261 <context context-type="linenumber">1</context>
3262 </context-group>
3263 </trans-unit>
3039 <trans-unit id="0e65067fdcc9d8725a41896cb1e229d1415a45f6"> 3264 <trans-unit id="0e65067fdcc9d8725a41896cb1e229d1415a45f6">
3040 <source>Like the video</source> 3265 <source>Like the video</source>
3041 <target>الإعجاب بالÙيديو</target> 3266 <target>الإعجاب بالÙيديو</target>
diff --git a/client/src/locale/target/angular_ca_ES.xml b/client/src/locale/target/angular_ca_ES.xml
index 7444b71b0..15c1bbca0 100644
--- a/client/src/locale/target/angular_ca_ES.xml
+++ b/client/src/locale/target/angular_ca_ES.xml
@@ -116,7 +116,7 @@
116 <source>Password</source> 116 <source>Password</source>
117 <target>Contrasenya</target> 117 <target>Contrasenya</target>
118 <context-group name="null"> 118 <context-group name="null">
119 <context context-type="linenumber">12</context> 119 <context context-type="linenumber">13</context>
120 </context-group> 120 </context-group>
121 </trans-unit> 121 </trans-unit>
122 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 122 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -130,7 +130,7 @@
130 <source>Login</source> 130 <source>Login</source>
131 <target>Iniciar sessió</target> 131 <target>Iniciar sessió</target>
132 <context-group name="null"> 132 <context-group name="null">
133 <context context-type="linenumber">38</context> 133 <context context-type="linenumber">36</context>
134 </context-group> 134 </context-group>
135 </trans-unit> 135 </trans-unit>
136 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 136 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -158,7 +158,7 @@
158 <source>Send me an email to reset my password</source> 158 <source>Send me an email to reset my password</source>
159 <target>Envia'm un correu per reiniciar la meva contrasenya</target> 159 <target>Envia'm un correu per reiniciar la meva contrasenya</target>
160 <context-group name="null"> 160 <context-group name="null">
161 <context context-type="linenumber">75</context> 161 <context context-type="linenumber">80</context>
162 </context-group> 162 </context-group>
163 </trans-unit> 163 </trans-unit>
164 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 164 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -215,7 +215,7 @@
215 <source>Signup</source> 215 <source>Signup</source>
216 <target>Registra't</target> 216 <target>Registra't</target>
217 <context-group name="null"> 217 <context-group name="null">
218 <context context-type="linenumber">88</context> 218 <context context-type="linenumber">78</context>
219 </context-group> 219 </context-group>
220 </trans-unit> 220 </trans-unit>
221 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a"> 221 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a">
@@ -251,14 +251,14 @@
251 <source>Change the language</source> 251 <source>Change the language</source>
252 <target>Canvia la llengua</target> 252 <target>Canvia la llengua</target>
253 <context-group name="null"> 253 <context-group name="null">
254 <context context-type="linenumber">88</context> 254 <context context-type="linenumber">86</context>
255 </context-group> 255 </context-group>
256 </trans-unit> 256 </trans-unit>
257 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 257 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
258 <source>Create an account</source> 258 <source>Create an account</source>
259 <target>Registrar un compte</target> 259 <target>Registrar un compte</target>
260 <context-group name="null"> 260 <context-group name="null">
261 <context context-type="linenumber">39</context> 261 <context context-type="linenumber">37</context>
262 </context-group> 262 </context-group>
263 </trans-unit> 263 </trans-unit>
264 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 264 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -272,35 +272,35 @@
272 <source>Trending</source> 272 <source>Trending</source>
273 <target>Tendència</target> 273 <target>Tendència</target>
274 <context-group name="null"> 274 <context-group name="null">
275 <context context-type="linenumber">57</context> 275 <context context-type="linenumber">55</context>
276 </context-group> 276 </context-group>
277 </trans-unit> 277 </trans-unit>
278 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 278 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
279 <source>Recently added</source> 279 <source>Recently added</source>
280 <target>Afegits fa poc</target> 280 <target>Afegits fa poc</target>
281 <context-group name="null"> 281 <context-group name="null">
282 <context context-type="linenumber">62</context> 282 <context context-type="linenumber">60</context>
283 </context-group> 283 </context-group>
284 </trans-unit> 284 </trans-unit>
285 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 285 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
286 <source>Local</source> 286 <source>Local</source>
287 <target>Local</target> 287 <target>Local</target>
288 <context-group name="null"> 288 <context-group name="null">
289 <context context-type="linenumber">67</context> 289 <context context-type="linenumber">65</context>
290 </context-group> 290 </context-group>
291 </trans-unit> 291 </trans-unit>
292 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 292 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
293 <source>More</source> 293 <source>More</source>
294 <target>Més</target> 294 <target>Més</target>
295 <context-group name="null"> 295 <context-group name="null">
296 <context context-type="linenumber">72</context> 296 <context context-type="linenumber">70</context>
297 </context-group> 297 </context-group>
298 </trans-unit> 298 </trans-unit>
299 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 299 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
300 <source>Administration</source> 300 <source>Administration</source>
301 <target>Administració</target> 301 <target>Administració</target>
302 <context-group name="null"> 302 <context-group name="null">
303 <context context-type="linenumber">76</context> 303 <context context-type="linenumber">74</context>
304 </context-group> 304 </context-group>
305 </trans-unit> 305 </trans-unit>
306 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 306 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -412,7 +412,7 @@
412 <source>No results.</source> 412 <source>No results.</source>
413 <target>Sense resultats.</target> 413 <target>Sense resultats.</target>
414 <context-group name="null"> 414 <context-group name="null">
415 <context context-type="linenumber">17</context> 415 <context context-type="linenumber">20</context>
416 </context-group> 416 </context-group>
417 </trans-unit> 417 </trans-unit>
418 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b"> 418 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b">
@@ -429,15 +429,11 @@
429 <context context-type="linenumber">7</context> 429 <context context-type="linenumber">7</context>
430 </context-group> 430 </context-group>
431 </trans-unit> 431 </trans-unit>
432 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 432 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
433 <source> 433 <source>Submit</source>
434 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 434 <target>Envia</target>
435</source>
436 <target>
437 Quant a la instància <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/>
438</target>
439 <context-group name="null"> 435 <context-group name="null">
440 <context context-type="linenumber">1</context> 436 <context context-type="linenumber">31</context>
441 </context-group> 437 </context-group>
442 </trans-unit> 438 </trans-unit>
443 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 439 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -451,47 +447,14 @@
451 <source>Terms</source> 447 <source>Terms</source>
452 <target>Termes</target> 448 <target>Termes</target>
453 <context-group name="null"> 449 <context-group name="null">
454 <context context-type="linenumber">44</context> 450 <context context-type="linenumber">39</context>
455 </context-group> 451 </context-group>
456 </trans-unit> 452 </trans-unit>
457 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 453 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
458 <source>User registration is allowed and</source> 454 <source>User registration is allowed and</source>
459 <target>El registre d'usuaris és permès i</target> 455 <target>El registre d'usuaris és permès i</target>
460 <context-group name="null"> 456 <context-group name="null">
461 <context context-type="linenumber">25</context> 457 <context context-type="linenumber">29</context>
462 </context-group>
463 </trans-unit>
464 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
465 <source>
466 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
467 </source>
468 <target>
469 aquesta instància proporciona una quota bàsica de <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> d''espai per els vídeos dels seus usuaris.
470 </target>
471 <context-group name="null">
472 <context context-type="linenumber">27</context>
473 </context-group>
474 </trans-unit>
475 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
476 <source>
477 this instance provides unlimited space for the videos of its users.
478 </source>
479 <target>
480 aquesta instància proporciona espai il·limitat per els vídeos del seus usuaris.
481 </target>
482 <context-group name="null">
483 <context context-type="linenumber">31</context>
484 </context-group>
485 </trans-unit>
486 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
487 <source>
488 User registration is currently not allowed.
489 </source>
490 <target>
491 El registre d'usuaris actualment no és permès.
492 </target>
493 <context-group name="null">
494 <context context-type="linenumber">36</context>
495 </context-group> 458 </context-group>
496 </trans-unit> 459 </trans-unit>
497 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 460 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -777,42 +740,42 @@
777 <source>Short description</source> 740 <source>Short description</source>
778 <target>Descripció curta</target> 741 <target>Descripció curta</target>
779 <context-group name="null"> 742 <context-group name="null">
780 <context context-type="linenumber">22</context> 743 <context context-type="linenumber">21</context>
781 </context-group> 744 </context-group>
782 </trans-unit> 745 </trans-unit>
783 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 746 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
784 <source>Default client route</source> 747 <source>Default client route</source>
785 <target>Ruta per defecte del client</target> 748 <target>Ruta per defecte del client</target>
786 <context-group name="null"> 749 <context-group name="null">
787 <context context-type="linenumber">55</context> 750 <context context-type="linenumber">48</context>
788 </context-group> 751 </context-group>
789 </trans-unit> 752 </trans-unit>
790 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 753 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
791 <source>Videos Trending</source> 754 <source>Videos Trending</source>
792 <target>Vídeos tendència</target> 755 <target>Vídeos tendència</target>
793 <context-group name="null"> 756 <context-group name="null">
794 <context context-type="linenumber">59</context> 757 <context context-type="linenumber">52</context>
795 </context-group> 758 </context-group>
796 </trans-unit> 759 </trans-unit>
797 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 760 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
798 <source>Videos Recently Added</source> 761 <source>Videos Recently Added</source>
799 <target>Vídeos afegits fa poc</target> 762 <target>Vídeos afegits fa poc</target>
800 <context-group name="null"> 763 <context-group name="null">
801 <context context-type="linenumber">60</context> 764 <context context-type="linenumber">53</context>
802 </context-group> 765 </context-group>
803 </trans-unit> 766 </trans-unit>
804 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 767 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
805 <source>Local videos</source> 768 <source>Local videos</source>
806 <target>Vídeos locals</target> 769 <target>Vídeos locals</target>
807 <context-group name="null"> 770 <context-group name="null">
808 <context context-type="linenumber">61</context> 771 <context context-type="linenumber">54</context>
809 </context-group> 772 </context-group>
810 </trans-unit> 773 </trans-unit>
811 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 774 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
812 <source>Policy on videos containing sensitive content</source> 775 <source>Policy on videos containing sensitive content</source>
813 <target>Política sobre vídeos que contenen contingut sensible</target> 776 <target>Política sobre vídeos que contenen contingut sensible</target>
814 <context-group name="null"> 777 <context-group name="null">
815 <context context-type="linenumber">70</context> 778 <context context-type="linenumber">61</context>
816 </context-group> 779 </context-group>
817 </trans-unit> 780 </trans-unit>
818 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 781 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -847,42 +810,42 @@
847 <source>Signup enabled</source> 810 <source>Signup enabled</source>
848 <target>Registre activat</target> 811 <target>Registre activat</target>
849 <context-group name="null"> 812 <context-group name="null">
850 <context context-type="linenumber">93</context> 813 <context context-type="linenumber">84</context>
851 </context-group> 814 </context-group>
852 </trans-unit> 815 </trans-unit>
853 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 816 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
854 <source>Signup limit</source> 817 <source>Signup limit</source>
855 <target>Limit de registres</target> 818 <target>Limit de registres</target>
856 <context-group name="null"> 819 <context-group name="null">
820 <context context-type="linenumber">96</context>
821 </context-group>
822 </trans-unit>
823 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
824 <source>Users</source>
825 <target>Usuaris</target>
826 <context-group name="null">
857 <context context-type="linenumber">105</context> 827 <context context-type="linenumber">105</context>
858 </context-group> 828 </context-group>
859 </trans-unit> 829 </trans-unit>
830 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
831 <source>User default video quota</source>
832 <target>Quota de vídeo per defecte de l'usuari</target>
833 <context-group name="null">
834 <context context-type="linenumber">109</context>
835 </context-group>
836 </trans-unit>
860 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 837 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
861 <source>Administrator</source> 838 <source>Administrator</source>
862 <target>Administrador</target> 839 <target>Administrador</target>
863 <context-group name="null"> 840 <context-group name="null">
864 <context context-type="linenumber">131</context> 841 <context context-type="linenumber">155</context>
865 </context-group> 842 </context-group>
866 </trans-unit> 843 </trans-unit>
867 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 844 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
868 <source>Admin email</source> 845 <source>Admin email</source>
869 <target>Correu del Administrador</target> 846 <target>Correu del Administrador</target>
870 <context-group name="null"> 847 <context-group name="null">
871 <context context-type="linenumber">134</context> 848 <context context-type="linenumber">158</context>
872 </context-group>
873 </trans-unit>
874 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
875 <source>Users</source>
876 <target>Usuaris</target>
877 <context-group name="null">
878 <context context-type="linenumber">144</context>
879 </context-group>
880 </trans-unit>
881 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
882 <source>User default video quota</source>
883 <target>Quota de vídeo per defecte de l'usuari</target>
884 <context-group name="null">
885 <context context-type="linenumber">147</context>
886 </context-group> 849 </context-group>
887 </trans-unit> 850 </trans-unit>
888 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 851 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -903,21 +866,21 @@
903 <source>Your Twitter username</source> 866 <source>Your Twitter username</source>
904 <target>El teu nom d'usuari de Twitter</target> 867 <target>El teu nom d'usuari de Twitter</target>
905 <context-group name="null"> 868 <context-group name="null">
906 <context context-type="linenumber">181</context> 869 <context context-type="linenumber">184</context>
907 </context-group> 870 </context-group>
908 </trans-unit> 871 </trans-unit>
909 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 872 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
910 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 873 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
911 <target>Indica el compte de Twitter del lloc web o plataforma en què es va publicar el contingut.</target> 874 <target>Indica el compte de Twitter del lloc web o plataforma en què es va publicar el contingut.</target>
912 <context-group name="null"> 875 <context-group name="null">
913 <context context-type="linenumber">184</context> 876 <context context-type="linenumber">187</context>
914 </context-group> 877 </context-group>
915 </trans-unit> 878 </trans-unit>
916 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 879 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
917 <source>Instance whitelisted by Twitter</source> 880 <source>Instance whitelisted by Twitter</source>
918 <target>Instància a la llista blanca de Twitter</target> 881 <target>Instància a la llista blanca de Twitter</target>
919 <context-group name="null"> 882 <context-group name="null">
920 <context context-type="linenumber">198</context> 883 <context context-type="linenumber">199</context>
921 </context-group> 884 </context-group>
922 </trans-unit> 885 </trans-unit>
923 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 886 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -931,77 +894,77 @@
931 <source>Transcoding</source> 894 <source>Transcoding</source>
932 <target>Transcodificació</target> 895 <target>Transcodificació</target>
933 <context-group name="null"> 896 <context-group name="null">
934 <context context-type="linenumber">210</context> 897 <context context-type="linenumber">215</context>
935 </context-group> 898 </context-group>
936 </trans-unit> 899 </trans-unit>
937 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 900 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
938 <source>Transcoding enabled</source> 901 <source>Transcoding enabled</source>
939 <target>Transcodificació activada</target> 902 <target>Transcodificació activada</target>
940 <context-group name="null"> 903 <context-group name="null">
941 <context context-type="linenumber">215</context> 904 <context context-type="linenumber">221</context>
942 </context-group> 905 </context-group>
943 </trans-unit> 906 </trans-unit>
944 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 907 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
945 <source>If you disable transcoding, many videos from your users will not work!</source> 908 <source>If you disable transcoding, many videos from your users will not work!</source>
946 <target>Si desactives la transcodificació, molts vídeos dels teus usuaris no funcionaran.</target> 909 <target>Si desactives la transcodificació, molts vídeos dels teus usuaris no funcionaran.</target>
947 <context-group name="null"> 910 <context-group name="null">
948 <context context-type="linenumber">216</context> 911 <context context-type="linenumber">222</context>
949 </context-group> 912 </context-group>
950 </trans-unit> 913 </trans-unit>
951 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 914 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
952 <source>Transcoding threads</source> 915 <source>Transcoding threads</source>
953 <target>Subprocessos per la transcodificació</target> 916 <target>Subprocessos per la transcodificació</target>
954 <context-group name="null"> 917 <context-group name="null">
955 <context context-type="linenumber">223</context> 918 <context context-type="linenumber">237</context>
956 </context-group> 919 </context-group>
957 </trans-unit> 920 </trans-unit>
958 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 921 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
959 <source>Previews cache size</source> 922 <source>Previews cache size</source>
960 <target>Memòria cau per a visualitzacions prèvies</target> 923 <target>Memòria cau per a visualitzacions prèvies</target>
961 <context-group name="null"> 924 <context-group name="null">
962 <context context-type="linenumber">254</context> 925 <context context-type="linenumber">271</context>
963 </context-group> 926 </context-group>
964 </trans-unit> 927 </trans-unit>
965 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 928 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
966 <source>Customizations</source> 929 <source>Customizations</source>
967 <target>Personalitzacions</target> 930 <target>Personalitzacions</target>
968 <context-group name="null"> 931 <context-group name="null">
969 <context context-type="linenumber">275</context> 932 <context context-type="linenumber">289</context>
970 </context-group> 933 </context-group>
971 </trans-unit> 934 </trans-unit>
972 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 935 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
973 <source>JavaScript</source> 936 <source>JavaScript</source>
974 <target>JavaScript</target> 937 <target>JavaScript</target>
975 <context-group name="null"> 938 <context-group name="null">
976 <context context-type="linenumber">278</context> 939 <context context-type="linenumber">294</context>
977 </context-group> 940 </context-group>
978 </trans-unit> 941 </trans-unit>
979 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 942 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
980 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 943 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
981 <target>Escriu directament el codi JavaScript.&lt;br /&gt;Exemple: &lt;pre&gt;console.log('la meva instància és sorprenent');&lt;/pre&gt;</target> 944 <target>Escriu directament el codi JavaScript.&lt;br /&gt;Exemple: &lt;pre&gt;console.log('la meva instància és sorprenent');&lt;/pre&gt;</target>
982 <context-group name="null"> 945 <context-group name="null">
983 <context context-type="linenumber">281</context> 946 <context context-type="linenumber">297</context>
984 </context-group> 947 </context-group>
985 </trans-unit> 948 </trans-unit>
986 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab"> 949 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab">
987 <source>Advanced configuration</source> 950 <source>Advanced configuration</source>
988 <target>Configuració avançada</target> 951 <target>Configuració avançada</target>
989 <context-group name="null"> 952 <context-group name="null">
990 <context context-type="linenumber">207</context> 953 <context context-type="linenumber">212</context>
991 </context-group> 954 </context-group>
992 </trans-unit> 955 </trans-unit>
993 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 956 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
994 <source>Update configuration</source> 957 <source>Update configuration</source>
995 <target>Actualitza la configuració</target> 958 <target>Actualitza la configuració</target>
996 <context-group name="null"> 959 <context-group name="null">
997 <context context-type="linenumber">325</context> 960 <context context-type="linenumber">340</context>
998 </context-group> 961 </context-group>
999 </trans-unit> 962 </trans-unit>
1000 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 963 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1001 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 964 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1002 <target>Sembla que la configuració no és vàlida. Cerca possibles errors a les diferents pestanyes.</target> 965 <target>Sembla que la configuració no és vàlida. Cerca possibles errors a les diferents pestanyes.</target>
1003 <context-group name="null"> 966 <context-group name="null">
1004 <context context-type="linenumber">326</context> 967 <context context-type="linenumber">341</context>
1005 </context-group> 968 </context-group>
1006 </trans-unit> 969 </trans-unit>
1007 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 970 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1254,20 +1217,6 @@
1254 <context context-type="linenumber">7</context> 1217 <context context-type="linenumber">7</context>
1255 </context-group> 1218 </context-group>
1256 </trans-unit> 1219 </trans-unit>
1257 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
1258 <source>My settings</source>
1259 <target>La meva configuració</target>
1260 <context-group name="null">
1261 <context context-type="linenumber">3</context>
1262 </context-group>
1263 </trans-unit>
1264 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
1265 <source>My videos</source>
1266 <target>Els meus vídeos</target>
1267 <context-group name="null">
1268 <context context-type="linenumber">14</context>
1269 </context-group>
1270 </trans-unit>
1271 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 1220 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
1272 <source>Video quota:</source> 1221 <source>Video quota:</source>
1273 <target>Quota de vídeo:</target> 1222 <target>Quota de vídeo:</target>
@@ -1279,21 +1228,14 @@
1279 <source>Profile</source> 1228 <source>Profile</source>
1280 <target>Perfil</target> 1229 <target>Perfil</target>
1281 <context-group name="null"> 1230 <context-group name="null">
1282 <context context-type="linenumber">8</context> 1231 <context context-type="linenumber">7</context>
1283 </context-group> 1232 </context-group>
1284 </trans-unit> 1233 </trans-unit>
1285 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 1234 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
1286 <source>Video settings</source> 1235 <source>Video settings</source>
1287 <target>Ajustos de vídeo</target> 1236 <target>Ajustos de vídeo</target>
1288 <context-group name="null"> 1237 <context-group name="null">
1289 <context context-type="linenumber">15</context> 1238 <context context-type="linenumber">16</context>
1290 </context-group>
1291 </trans-unit>
1292 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
1293 <source>Submit</source>
1294 <target>Envia</target>
1295 <context-group name="null">
1296 <context context-type="linenumber">24</context>
1297 </context-group> 1239 </context-group>
1298 </trans-unit> 1240 </trans-unit>
1299 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 1241 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
@@ -1485,14 +1427,14 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
1485 <source>Publish will be available when upload is finished</source> 1427 <source>Publish will be available when upload is finished</source>
1486 <target>La publicació estarà disponible quan finalitzi la càrrega</target> 1428 <target>La publicació estarà disponible quan finalitzi la càrrega</target>
1487 <context-group name="null"> 1429 <context-group name="null">
1488 <context context-type="linenumber">53</context> 1430 <context context-type="linenumber">58</context>
1489 </context-group> 1431 </context-group>
1490 </trans-unit> 1432 </trans-unit>
1491 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 1433 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
1492 <source>Publish</source> 1434 <source>Publish</source>
1493 <target>Publica</target> 1435 <target>Publica</target>
1494 <context-group name="null"> 1436 <context-group name="null">
1495 <context context-type="linenumber">60</context> 1437 <context context-type="linenumber">65</context>
1496 </context-group> 1438 </context-group>
1497 </trans-unit> 1439 </trans-unit>
1498 <trans-unit id="fdf7cbdc140d0aab0f0b6c06065a0fd448ed6a2e"> 1440 <trans-unit id="fdf7cbdc140d0aab0f0b6c06065a0fd448ed6a2e">
@@ -1548,7 +1490,7 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
1548 <source>Wait transcoding before publishing the video</source> 1490 <source>Wait transcoding before publishing the video</source>
1549 <target>Espera la transcodificació abans de publicar el vídeo</target> 1491 <target>Espera la transcodificació abans de publicar el vídeo</target>
1550 <context-group name="null"> 1492 <context-group name="null">
1551 <context context-type="linenumber">130</context> 1493 <context context-type="linenumber">131</context>
1552 </context-group> 1494 </context-group>
1553 </trans-unit> 1495 </trans-unit>
1554 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 1496 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -1562,14 +1504,14 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
1562 <source>Upload thumbnail</source> 1504 <source>Upload thumbnail</source>
1563 <target>Puja miniatura</target> 1505 <target>Puja miniatura</target>
1564 <context-group name="null"> 1506 <context-group name="null">
1565 <context context-type="linenumber">195</context> 1507 <context context-type="linenumber">196</context>
1566 </context-group> 1508 </context-group>
1567 </trans-unit> 1509 </trans-unit>
1568 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 1510 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
1569 <source>Upload preview</source> 1511 <source>Upload preview</source>
1570 <target>Previsualitza la càrrega</target> 1512 <target>Previsualitza la càrrega</target>
1571 <context-group name="null"> 1513 <context-group name="null">
1572 <context context-type="linenumber">202</context> 1514 <context context-type="linenumber">203</context>
1573 </context-group> 1515 </context-group>
1574 </trans-unit> 1516 </trans-unit>
1575 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 1517 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -1583,14 +1525,14 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
1583 <source>Short text to tell people how they can support you (membership platform...).</source> 1525 <source>Short text to tell people how they can support you (membership platform...).</source>
1584 <target>Text breu per dir a la gent com us poden ajudar (plataforma de pertinença ...).</target> 1526 <target>Text breu per dir a la gent com us poden ajudar (plataforma de pertinença ...).</target>
1585 <context-group name="null"> 1527 <context-group name="null">
1586 <context context-type="linenumber">209</context> 1528 <context context-type="linenumber">210</context>
1587 </context-group> 1529 </context-group>
1588 </trans-unit> 1530 </trans-unit>
1589 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 1531 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
1590 <source>Advanced settings</source> 1532 <source>Advanced settings</source>
1591 <target>Ajustos avançats</target> 1533 <target>Ajustos avançats</target>
1592 <context-group name="null"> 1534 <context-group name="null">
1593 <context context-type="linenumber">190</context> 1535 <context context-type="linenumber">191</context>
1594 </context-group> 1536 </context-group>
1595 </trans-unit> 1537 </trans-unit>
1596 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 1538 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -1841,13 +1783,6 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
1841 <context context-type="linenumber">14</context> 1783 <context context-type="linenumber">14</context>
1842 </context-group> 1784 </context-group>
1843 </trans-unit> 1785 </trans-unit>
1844 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
1845 <source>Error getting about from server</source>
1846 <target>S'ha produït un error en obtenir quant a del servidor</target>
1847 <context-group name="null">
1848 <context context-type="linenumber">1</context>
1849 </context-group>
1850 </trans-unit>
1851 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 1786 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
1852 <source>No description</source> 1787 <source>No description</source>
1853 <target>Sense descripció</target> 1788 <target>Sense descripció</target>
@@ -1869,20 +1804,6 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
1869 <context context-type="linenumber">1</context> 1804 <context context-type="linenumber">1</context>
1870 </context-group> 1805 </context-group>
1871 </trans-unit> 1806 </trans-unit>
1872 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
1873 <source>Error</source>
1874 <target>Error</target>
1875 <context-group name="null">
1876 <context context-type="linenumber">1</context>
1877 </context-group>
1878 </trans-unit>
1879 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
1880 <source>Success</source>
1881 <target>Èxit</target>
1882 <context-group name="null">
1883 <context context-type="linenumber">1</context>
1884 </context-group>
1885 </trans-unit>
1886 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 1807 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
1887 <source>Configuration updated.</source> 1808 <source>Configuration updated.</source>
1888 <target>S'ha actualitzat la configuració.</target> 1809 <target>S'ha actualitzat la configuració.</target>
@@ -2044,23 +1965,16 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
2044 <context context-type="linenumber">1</context> 1965 <context context-type="linenumber">1</context>
2045 </context-group> 1966 </context-group>
2046 </trans-unit> 1967 </trans-unit>
2047 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 1968 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
2048 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 1969 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
2049 <target>Estàs segur que vols eliminar <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? També s''esborraràn tots els vídeos carregats en aquest canal.</target> 1970 <target>Canal de vídeo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> eliminat.</target>
2050 <context-group name="null">
2051 <context context-type="linenumber">1</context>
2052 </context-group>
2053 </trans-unit>
2054 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
2055 <source>Please type the name of the video channel to confirm</source>
2056 <target>Escriu el nom del canal de vídeo per confirmar</target>
2057 <context-group name="null"> 1971 <context-group name="null">
2058 <context context-type="linenumber">1</context> 1972 <context context-type="linenumber">1</context>
2059 </context-group> 1973 </context-group>
2060 </trans-unit> 1974 </trans-unit>
2061 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 1975 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2062 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 1976 <source>My videos</source>
2063 <target>Canal de vídeo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> eliminat.</target> 1977 <target>Els meus vídeos</target>
2064 <context-group name="null"> 1978 <context-group name="null">
2065 <context context-type="linenumber">1</context> 1979 <context context-type="linenumber">1</context>
2066 </context-group> 1980 </context-group>
@@ -2121,6 +2035,13 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
2121 <context context-type="linenumber">1</context> 2035 <context context-type="linenumber">1</context>
2122 </context-group> 2036 </context-group>
2123 </trans-unit> 2037 </trans-unit>
2038 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2039 <source>My settings</source>
2040 <target>La meva configuració</target>
2041 <context-group name="null">
2042 <context context-type="linenumber">1</context>
2043 </context-group>
2044 </trans-unit>
2124 <trans-unit id="ccbf0490fb6b60d21e03bb2c9003df0ce1a58752"> 2045 <trans-unit id="ccbf0490fb6b60d21e03bb2c9003df0ce1a58752">
2125 <source>Unable to find user id or verification string.</source> 2046 <source>Unable to find user id or verification string.</source>
2126 <target>No es pot trobar l'identificador d'usuari ni la cadena de verificació.</target> 2047 <target>No es pot trobar l'identificador d'usuari ni la cadena de verificació.</target>
@@ -2144,6 +2065,13 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
2144 <context context-type="linenumber">1</context> 2065 <context context-type="linenumber">1</context>
2145 </context-group> 2066 </context-group>
2146 </trans-unit> 2067 </trans-unit>
2068 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
2069 <source>Error</source>
2070 <target>Error</target>
2071 <context-group name="null">
2072 <context context-type="linenumber">1</context>
2073 </context-group>
2074 </trans-unit>
2147 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 2075 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
2148 <source>You need to reconnect.</source> 2076 <source>You need to reconnect.</source>
2149 <target>Necessites tornar a connectar.</target> 2077 <target>Necessites tornar a connectar.</target>
@@ -2158,6 +2086,20 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
2158 <context context-type="linenumber">1</context> 2086 <context context-type="linenumber">1</context>
2159 </context-group> 2087 </context-group>
2160 </trans-unit> 2088 </trans-unit>
2089 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
2090 <source>Info</source>
2091 <target>Informació</target>
2092 <context-group name="null">
2093 <context context-type="linenumber">1</context>
2094 </context-group>
2095 </trans-unit>
2096 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
2097 <source>Success</source>
2098 <target>Èxit</target>
2099 <context-group name="null">
2100 <context context-type="linenumber">1</context>
2101 </context-group>
2102 </trans-unit>
2161 <trans-unit id="b0f24b7136e551a0deba831f1525711245b31a26"> 2103 <trans-unit id="b0f24b7136e551a0deba831f1525711245b31a26">
2162 <source>Your password has been successfully reset!</source> 2104 <source>Your password has been successfully reset!</source>
2163 <target>La contrasenya s'ha restablit correctament.</target> 2105 <target>La contrasenya s'ha restablit correctament.</target>
@@ -2263,6 +2205,20 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
2263 <context context-type="linenumber">1</context> 2205 <context context-type="linenumber">1</context>
2264 </context-group> 2206 </context-group>
2265 </trans-unit> 2207 </trans-unit>
2208 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
2209 <source>Email is required.</source>
2210 <target>Es requereix un correu electrònic.</target>
2211 <context-group name="null">
2212 <context context-type="linenumber">1</context>
2213 </context-group>
2214 </trans-unit>
2215 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
2216 <source>Email must be valid.</source>
2217 <target>El correu electrònic ha de ser vàlid.</target>
2218 <context-group name="null">
2219 <context context-type="linenumber">1</context>
2220 </context-group>
2221 </trans-unit>
2266 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 2222 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
2267 <source>Username is required.</source> 2223 <source>Username is required.</source>
2268 <target>Es requereix nom d'usuari.</target> 2224 <target>Es requereix nom d'usuari.</target>
@@ -2284,41 +2240,6 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
2284 <context context-type="linenumber">1</context> 2240 <context context-type="linenumber">1</context>
2285 </context-group> 2241 </context-group>
2286 </trans-unit> 2242 </trans-unit>
2287 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
2288 <source>Username must be at least 3 characters long.</source>
2289 <target>El nom d'usuari ha de tenir com a mínim 3 caràcters.</target>
2290 <context-group name="null">
2291 <context context-type="linenumber">1</context>
2292 </context-group>
2293 </trans-unit>
2294 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
2295 <source>Username cannot be more than 20 characters long.</source>
2296 <target>El nom d'usuari no pot tenir més de 20 caràcters.</target>
2297 <context-group name="null">
2298 <context context-type="linenumber">1</context>
2299 </context-group>
2300 </trans-unit>
2301 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
2302 <source>Username should be only lowercase alphanumeric characters.</source>
2303 <target>El nom d'usuari ha de ser només caràcters alfanumèrics en minúscules.</target>
2304 <context-group name="null">
2305 <context context-type="linenumber">1</context>
2306 </context-group>
2307 </trans-unit>
2308 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
2309 <source>Email is required.</source>
2310 <target>Es requereix un correu electrònic.</target>
2311 <context-group name="null">
2312 <context context-type="linenumber">1</context>
2313 </context-group>
2314 </trans-unit>
2315 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
2316 <source>Email must be valid.</source>
2317 <target>El correu electrònic ha de ser vàlid.</target>
2318 <context-group name="null">
2319 <context context-type="linenumber">1</context>
2320 </context-group>
2321 </trans-unit>
2322 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 2243 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
2323 <source>Password must be at least 6 characters long.</source> 2244 <source>Password must be at least 6 characters long.</source>
2324 <target>La contrasenya ha de tenir com a mínim 6 caràcters.</target> 2245 <target>La contrasenya ha de tenir com a mínim 6 caràcters.</target>
@@ -2368,20 +2289,6 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
2368 <context context-type="linenumber">1</context> 2289 <context context-type="linenumber">1</context>
2369 </context-group> 2290 </context-group>
2370 </trans-unit> 2291 </trans-unit>
2371 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
2372 <source>Display name must be at least 3 characters long.</source>
2373 <target>El nom de visualització ha de tenir un mínim de 3 caràcters.</target>
2374 <context-group name="null">
2375 <context context-type="linenumber">1</context>
2376 </context-group>
2377 </trans-unit>
2378 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
2379 <source>Display name cannot be more than 120 characters long.</source>
2380 <target>El nom de visualització no pot tenir més de 120 caràcters.</target>
2381 <context-group name="null">
2382 <context context-type="linenumber">1</context>
2383 </context-group>
2384 </trans-unit>
2385 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 2292 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
2386 <source>Description must be at least 3 characters long.</source> 2293 <source>Description must be at least 3 characters long.</source>
2387 <target>La descripció ha de tenir almenys 3 caràcters de longitud.</target> 2294 <target>La descripció ha de tenir almenys 3 caràcters de longitud.</target>
@@ -2403,13 +2310,6 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
2403 <context context-type="linenumber">1</context> 2310 <context context-type="linenumber">1</context>
2404 </context-group> 2311 </context-group>
2405 </trans-unit> 2312 </trans-unit>
2406 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
2407 <source>Report reason cannot be more than 300 characters long.</source>
2408 <target>El motiu de l'informe no pot tenir més de 300 caràcters.</target>
2409 <context-group name="null">
2410 <context context-type="linenumber">1</context>
2411 </context-group>
2412 </trans-unit>
2413 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 2313 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
2414 <source>Support text must be at least 3 characters long.</source> 2314 <source>Support text must be at least 3 characters long.</source>
2415 <target>El text de suport ha de tenir un mínim de 3 caràcters.</target> 2315 <target>El text de suport ha de tenir un mínim de 3 caràcters.</target>
@@ -3054,13 +2954,6 @@ Quan pugis un vídeo en aquest canal, el camp d'assistència de vídeo s'omplirÃ
3054 <context context-type="linenumber">1</context> 2954 <context context-type="linenumber">1</context>
3055 </context-group> 2955 </context-group>
3056 </trans-unit> 2956 </trans-unit>
3057 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
3058 <source>Info</source>
3059 <target>Informació</target>
3060 <context-group name="null">
3061 <context context-type="linenumber">1</context>
3062 </context-group>
3063 </trans-unit>
3064 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 2957 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
3065 <source>Upload cancelled</source> 2958 <source>Upload cancelled</source>
3066 <target>Pujada cancel·lada</target> 2959 <target>Pujada cancel·lada</target>
diff --git a/client/src/locale/target/angular_cs_CZ.xml b/client/src/locale/target/angular_cs_CZ.xml
index 59af08639..7b6f99ddb 100644
--- a/client/src/locale/target/angular_cs_CZ.xml
+++ b/client/src/locale/target/angular_cs_CZ.xml
@@ -309,7 +309,8 @@
309 Unsubscribe 309 Unsubscribe
310 </source> 310 </source>
311 <target> 311 <target>
312Přestat odebírat</target> 312 Přestat odebírat
313 </target>
313 <context-group name="null"> 314 <context-group name="null">
314 <context context-type="linenumber">18</context> 315 <context context-type="linenumber">18</context>
315 </context-group> 316 </context-group>
@@ -337,14 +338,21 @@ Přestat odebírat</target>
337 </trans-unit> 338 </trans-unit>
338 <trans-unit id="5047522cc670b1f4a288bce07f9b1c5061e913ed"> 339 <trans-unit id="5047522cc670b1f4a288bce07f9b1c5061e913ed">
339 <source>Subscribe with a Mastodon account:</source> 340 <source>Subscribe with a Mastodon account:</source>
340 <target>Odebírat pÅ™es Mastodon úÄet</target> 341 <target>Odebírat pÅ™es úÄet na Mastodonu:</target>
341 <context-group name="null"> 342 <context-group name="null">
342 <context context-type="linenumber">43</context> 343 <context context-type="linenumber">43</context>
343 </context-group> 344 </context-group>
344 </trans-unit> 345 </trans-unit>
346 <trans-unit id="d8758664cadd6452256ca25ca0c7259074f427c1">
347 <source>Using a syndication feed</source>
348 <target>Použít syndikaÄní proud</target>
349 <context-group name="null">
350 <context context-type="linenumber">48</context>
351 </context-group>
352 </trans-unit>
345 <trans-unit id="d5e5bc7d213694fc0414a76f0ff3085bae44268a"> 353 <trans-unit id="d5e5bc7d213694fc0414a76f0ff3085bae44268a">
346 <source>Subscribe via RSS</source> 354 <source>Subscribe via RSS</source>
347 <target>Odebírat RSS</target> 355 <target>Odebírat přes RSS</target>
348 <context-group name="null"> 356 <context-group name="null">
349 <context context-type="linenumber">49</context> 357 <context context-type="linenumber">49</context>
350 </context-group> 358 </context-group>
@@ -362,6 +370,20 @@ Přestat odebírat</target>
362 <context context-type="linenumber">10</context> 370 <context context-type="linenumber">10</context>
363 </context-group> 371 </context-group>
364 </trans-unit> 372 </trans-unit>
373 <trans-unit id="319933e1af77ca2e35b75a5e9270a3c90e83dd4b">
374 <source>You can subscribe to the channel via any ActivityPub-capable fediverse instance. For instance with Mastodon or Pleroma you can type the channel URL in the search box and subscribe there.</source>
375 <target>Tento kanál můžete odebírat z jakékoliv instance na fediverse používající ActivityPub. Například u Mastodonu nebo Pleromy můžete napsat URL adresu kanálu do vyhledávacího pole a tam zaÄít odebírat.</target>
376 <context-group name="null">
377 <context context-type="linenumber">17</context>
378 </context-group>
379 </trans-unit>
380 <trans-unit id="2767d5461b6c622ccdeb868df8becf26bc16b99a">
381 <source>You can interact with this via any ActivityPub-capable fediverse instance. For instance with Mastodon or Pleroma you can type the current URL in the search box and interact with it there.</source>
382 <target>S tímto videem můžete interagovat z jakékoliv instance na fediverse používající ActivityPub. Například u Mastodonu nebo Pleromy můžete napsat aktuální URL adresu do vyhledávacího pole a odtamtud interagovat.</target>
383 <context-group name="null">
384 <context context-type="linenumber">22</context>
385 </context-group>
386 </trans-unit>
365 <trans-unit id="15f046007e4fca2e8477966745e2ec4e3e81bc3b"> 387 <trans-unit id="15f046007e4fca2e8477966745e2ec4e3e81bc3b">
366 <source>Video quota</source> 388 <source>Video quota</source>
367 <target>Limit na videa</target> 389 <target>Limit na videa</target>
@@ -438,7 +460,7 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
438 </trans-unit> 460 </trans-unit>
439 <trans-unit id="51ef29329faccb28d94369897068897d1b3d0478"> 461 <trans-unit id="51ef29329faccb28d94369897068897d1b3d0478">
440 <source>Username or email address</source> 462 <source>Username or email address</source>
441 <target>Uživatelské jméno nebo email</target> 463 <target>Uživatelské jméno nebo e-mail</target>
442 <context-group name="null"> 464 <context-group name="null">
443 <context context-type="linenumber">15</context> 465 <context context-type="linenumber">15</context>
444 </context-group> 466 </context-group>
@@ -476,7 +498,7 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
476 <source>Password</source> 498 <source>Password</source>
477 <target>Heslo</target> 499 <target>Heslo</target>
478 <context-group name="null"> 500 <context-group name="null">
479 <context context-type="linenumber">12</context> 501 <context context-type="linenumber">13</context>
480 </context-group> 502 </context-group>
481 </trans-unit> 503 </trans-unit>
482 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 504 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -490,7 +512,7 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
490 <source>Login</source> 512 <source>Login</source>
491 <target>Přihlásit</target> 513 <target>Přihlásit</target>
492 <context-group name="null"> 514 <context-group name="null">
493 <context context-type="linenumber">38</context> 515 <context context-type="linenumber">36</context>
494 </context-group> 516 </context-group>
495 </trans-unit> 517 </trans-unit>
496 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 518 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -502,23 +524,23 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
502 </trans-unit> 524 </trans-unit>
503 <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc"> 525 <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc">
504 <source>Email</source> 526 <source>Email</source>
505 <target>Email</target> 527 <target>E-mail</target>
506 <context-group name="null"> 528 <context-group name="null">
507 <context context-type="linenumber">8</context> 529 <context context-type="linenumber">8</context>
508 </context-group> 530 </context-group>
509 </trans-unit> 531 </trans-unit>
510 <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529"> 532 <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529">
511 <source>Email address</source> 533 <source>Email address</source>
512 <target>Emailová adresa</target> 534 <target>E-mailová adresa</target>
513 <context-group name="null"> 535 <context-group name="null">
514 <context context-type="linenumber">10</context> 536 <context context-type="linenumber">10</context>
515 </context-group> 537 </context-group>
516 </trans-unit> 538 </trans-unit>
517 <trans-unit id="78be69e4d26b3b654c49962839d8545e61bf8b55"> 539 <trans-unit id="78be69e4d26b3b654c49962839d8545e61bf8b55">
518 <source>Send me an email to reset my password</source> 540 <source>Send me an email to reset my password</source>
519 <target>Poslat email pro resetování hesla</target> 541 <target>Poslat e-mail pro resetování hesla</target>
520 <context-group name="null"> 542 <context-group name="null">
521 <context context-type="linenumber">75</context> 543 <context context-type="linenumber">80</context>
522 </context-group> 544 </context-group>
523 </trans-unit> 545 </trans-unit>
524 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 546 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -589,7 +611,7 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
589 <source>Signup</source> 611 <source>Signup</source>
590 <target>Registrovat</target> 612 <target>Registrovat</target>
591 <context-group name="null"> 613 <context-group name="null">
592 <context context-type="linenumber">88</context> 614 <context context-type="linenumber">78</context>
593 </context-group> 615 </context-group>
594 </trans-unit> 616 </trans-unit>
595 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 617 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -659,7 +681,7 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
659 <source>Change the language</source> 681 <source>Change the language</source>
660 <target>Změnit jazyk</target> 682 <target>Změnit jazyk</target>
661 <context-group name="null"> 683 <context-group name="null">
662 <context context-type="linenumber">88</context> 684 <context context-type="linenumber">86</context>
663 </context-group> 685 </context-group>
664 </trans-unit> 686 </trans-unit>
665 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 687 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -670,7 +692,7 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
670 Můj veřejný profil 692 Můj veřejný profil
671 </target> 693 </target>
672 <context-group name="null"> 694 <context-group name="null">
673 <context context-type="linenumber">18</context> 695 <context context-type="linenumber">16</context>
674 </context-group> 696 </context-group>
675 </trans-unit> 697 </trans-unit>
676 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 698 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -681,7 +703,7 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
681 Můj úÄet 703 Můj úÄet
682 </target> 704 </target>
683 <context-group name="null"> 705 <context-group name="null">
684 <context context-type="linenumber">22</context> 706 <context context-type="linenumber">20</context>
685 </context-group> 707 </context-group>
686 </trans-unit> 708 </trans-unit>
687 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 709 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -692,7 +714,7 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
692 Moje videa 714 Moje videa
693 </target> 715 </target>
694 <context-group name="null"> 716 <context-group name="null">
695 <context context-type="linenumber">26</context> 717 <context context-type="linenumber">24</context>
696 </context-group> 718 </context-group>
697 </trans-unit> 719 </trans-unit>
698 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 720 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -703,14 +725,14 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
703 Odhlásit 725 Odhlásit
704 </target> 726 </target>
705 <context-group name="null"> 727 <context-group name="null">
706 <context context-type="linenumber">30</context> 728 <context context-type="linenumber">28</context>
707 </context-group> 729 </context-group>
708 </trans-unit> 730 </trans-unit>
709 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 731 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
710 <source>Create an account</source> 732 <source>Create an account</source>
711 <target>VytvoÅ™it úÄet</target> 733 <target>VytvoÅ™it úÄet</target>
712 <context-group name="null"> 734 <context-group name="null">
713 <context context-type="linenumber">39</context> 735 <context context-type="linenumber">37</context>
714 </context-group> 736 </context-group>
715 </trans-unit> 737 </trans-unit>
716 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 738 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -724,49 +746,49 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
724 <source>Subscriptions</source> 746 <source>Subscriptions</source>
725 <target>Odběry</target> 747 <target>Odběry</target>
726 <context-group name="null"> 748 <context-group name="null">
727 <context context-type="linenumber">47</context> 749 <context context-type="linenumber">45</context>
728 </context-group> 750 </context-group>
729 </trans-unit> 751 </trans-unit>
730 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 752 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
731 <source>Overview</source> 753 <source>Overview</source>
732 <target>Přehled</target> 754 <target>Přehled</target>
733 <context-group name="null"> 755 <context-group name="null">
734 <context context-type="linenumber">52</context> 756 <context context-type="linenumber">50</context>
735 </context-group> 757 </context-group>
736 </trans-unit> 758 </trans-unit>
737 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 759 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
738 <source>Trending</source> 760 <source>Trending</source>
739 <target>Trendy</target> 761 <target>Trendy</target>
740 <context-group name="null"> 762 <context-group name="null">
741 <context context-type="linenumber">57</context> 763 <context context-type="linenumber">55</context>
742 </context-group> 764 </context-group>
743 </trans-unit> 765 </trans-unit>
744 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 766 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
745 <source>Recently added</source> 767 <source>Recently added</source>
746 <target>Nedávno přidané</target> 768 <target>Nedávno přidané</target>
747 <context-group name="null"> 769 <context-group name="null">
748 <context context-type="linenumber">62</context> 770 <context context-type="linenumber">60</context>
749 </context-group> 771 </context-group>
750 </trans-unit> 772 </trans-unit>
751 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 773 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
752 <source>Local</source> 774 <source>Local</source>
753 <target>Místní</target> 775 <target>Místní</target>
754 <context-group name="null"> 776 <context-group name="null">
755 <context context-type="linenumber">67</context> 777 <context context-type="linenumber">65</context>
756 </context-group> 778 </context-group>
757 </trans-unit> 779 </trans-unit>
758 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 780 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
759 <source>More</source> 781 <source>More</source>
760 <target>Další</target> 782 <target>Další</target>
761 <context-group name="null"> 783 <context-group name="null">
762 <context context-type="linenumber">72</context> 784 <context context-type="linenumber">70</context>
763 </context-group> 785 </context-group>
764 </trans-unit> 786 </trans-unit>
765 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 787 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
766 <source>Administration</source> 788 <source>Administration</source>
767 <target>Administrace</target> 789 <target>Administrace</target>
768 <context-group name="null"> 790 <context-group name="null">
769 <context context-type="linenumber">76</context> 791 <context context-type="linenumber">74</context>
770 </context-group> 792 </context-group>
771 </trans-unit> 793 </trans-unit>
772 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 794 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -776,11 +798,18 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
776 <context context-type="linenumber">25</context> 798 <context context-type="linenumber">25</context>
777 </context-group> 799 </context-group>
778 </trans-unit> 800 </trans-unit>
801 <trans-unit id="4752e5e33da1c3396d3248eb8fef59bca5d00cb3">
802 <source>Show keyboard shortcuts</source>
803 <target>Zobrazit klávesové zkratky</target>
804 <context-group name="null">
805 <context context-type="linenumber">89</context>
806 </context-group>
807 </trans-unit>
779 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 808 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
780 <source>Toggle dark interface</source> 809 <source>Toggle dark interface</source>
781 <target>Přepnout tmavé rozhraní</target> 810 <target>Přepnout tmavé rozhraní</target>
782 <context-group name="null"> 811 <context-group name="null">
783 <context context-type="linenumber">94</context> 812 <context context-type="linenumber">92</context>
784 </context-group> 813 </context-group>
785 </trans-unit> 814 </trans-unit>
786 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 815 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -811,6 +840,20 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
811 <context context-type="linenumber">15</context> 840 <context context-type="linenumber">15</context>
812 </context-group> 841 </context-group>
813 </trans-unit> 842 </trans-unit>
843 <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2">
844 <source>Duration</source>
845 <target>Trvání</target>
846 <context-group name="null">
847 <context context-type="linenumber">24</context>
848 </context-group>
849 </trans-unit>
850 <trans-unit id="dc67060f94f0f2b58549f54a5c07925dffd20238">
851 <source>Display sensitive content</source>
852 <target>Zobrazit citlivý obsah</target>
853 <context-group name="null">
854 <context context-type="linenumber">33</context>
855 </context-group>
856 </trans-unit>
814 <trans-unit id="4f20f2d5a6882190892e58b85f6ccbedfa737952"> 857 <trans-unit id="4f20f2d5a6882190892e58b85f6ccbedfa737952">
815 <source>Yes</source> 858 <source>Yes</source>
816 <target>Ano</target> 859 <target>Ano</target>
@@ -867,11 +910,18 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
867 <context context-type="linenumber">94</context> 910 <context context-type="linenumber">94</context>
868 </context-group> 911 </context-group>
869 </trans-unit> 912 </trans-unit>
913 <trans-unit id="41ed53a3f1d4dfc57011d0aba13b8b074e8b41b6">
914 <source>Display unlisted and private videos</source>
915 <target>Zobrazit neuvedená a soukromá videa</target>
916 <context-group name="null">
917 <context context-type="linenumber">14</context>
918 </context-group>
919 </trans-unit>
870 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 920 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
871 <source>No results.</source> 921 <source>No results.</source>
872 <target>Žádné výsledky.</target> 922 <target>Žádné výsledky.</target>
873 <context-group name="null"> 923 <context-group name="null">
874 <context context-type="linenumber">17</context> 924 <context context-type="linenumber">20</context>
875 </context-group> 925 </context-group>
876 </trans-unit> 926 </trans-unit>
877 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 927 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -929,15 +979,11 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
929 <context context-type="linenumber">7</context> 979 <context context-type="linenumber">7</context>
930 </context-group> 980 </context-group>
931 </trans-unit> 981 </trans-unit>
932 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 982 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
933 <source> 983 <source>Submit</source>
934 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 984 <target>Odeslat</target>
935</source>
936 <target>
937 O instanci <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/>
938</target>
939 <context-group name="null"> 985 <context-group name="null">
940 <context context-type="linenumber">1</context> 986 <context context-type="linenumber">31</context>
941 </context-group> 987 </context-group>
942 </trans-unit> 988 </trans-unit>
943 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 989 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -951,47 +997,14 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
951 <source>Terms</source> 997 <source>Terms</source>
952 <target>Podmínky</target> 998 <target>Podmínky</target>
953 <context-group name="null"> 999 <context-group name="null">
954 <context context-type="linenumber">44</context> 1000 <context context-type="linenumber">39</context>
955 </context-group> 1001 </context-group>
956 </trans-unit> 1002 </trans-unit>
957 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 1003 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
958 <source>User registration is allowed and</source> 1004 <source>User registration is allowed and</source>
959 <target>Registrace uživatelů je povolena a</target> 1005 <target>Registrace uživatelů je povolena a</target>
960 <context-group name="null"> 1006 <context-group name="null">
961 <context context-type="linenumber">25</context> 1007 <context context-type="linenumber">29</context>
962 </context-group>
963 </trans-unit>
964 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
965 <source>
966 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
967 </source>
968 <target>
969 tato instance poskytuje základní limit <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> místa pro videa svým uživatelům.
970 </target>
971 <context-group name="null">
972 <context context-type="linenumber">27</context>
973 </context-group>
974 </trans-unit>
975 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
976 <source>
977 this instance provides unlimited space for the videos of its users.
978 </source>
979 <target>
980 tato instance poskytuje neomezený prostor pro videa svých uživatelů.
981 </target>
982 <context-group name="null">
983 <context context-type="linenumber">31</context>
984 </context-group>
985 </trans-unit>
986 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
987 <source>
988 User registration is currently not allowed.
989 </source>
990 <target>
991 Registrace uživatelů není momentálně povolena.
992 </target>
993 <context-group name="null">
994 <context context-type="linenumber">36</context>
995 </context-group> 1008 </context-group>
996 </trans-unit> 1009 </trans-unit>
997 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 1010 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1126,6 +1139,21 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1126 <context context-type="linenumber">51</context> 1139 <context context-type="linenumber">51</context>
1127 </context-group> 1140 </context-group>
1128 </trans-unit> 1141 </trans-unit>
1142 <trans-unit id="b4c2ef0143270626106b26196d40baf3439aa7b0">
1143 <source>
1144 Web peers are not publicly accessible: because we use WebRTC inside the web browser (<x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>with the WebTorrent library<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>), the protocol is different from classic BitTorrent.
1145 When you are in a web browser, you send a signal containing your IP address to the tracker that will randomly choose other peers to forward the information to.
1146 See <x id="START_LINK_1" ctype="x-a" equiv-text="&lt;a&gt;"/>this document<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more information
1147 </source>
1148 <target>
1149 Webové peery nejsou veÅ™ejnÄ› dostupné: jelikož používáme WebRTC v prohlížeÄi (<x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>s knihovnou WebTorrent<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>), je protokol odliÅ¡ný od klasického BitTorrentu.
1150 Když jste ve webovém prohlížeÄi, poÅ¡lete trackeru signál obsahující vaÅ¡i IP adresu. Tracker pak náhodnÄ› vybere další peery, kterým pÅ™epoÅ¡le informace.
1151 Pro více informací si pÅ™eÄtÄ›te <x id="START_LINK_1" ctype="x-a" equiv-text="&lt;a&gt;"/>tento dokument<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
1152 </target>
1153 <context-group name="null">
1154 <context context-type="linenumber">55</context>
1155 </context-group>
1156 </trans-unit>
1129 <trans-unit id="50d8e8388f5ceab292850ed828f306c9f2cab389"> 1157 <trans-unit id="50d8e8388f5ceab292850ed828f306c9f2cab389">
1130 <source> 1158 <source>
1131 The worst-case scenario of an average person spying on their friends is quite unlikely. 1159 The worst-case scenario of an average person spying on their friends is quite unlikely.
@@ -1141,7 +1169,7 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1141 </trans-unit> 1169 </trans-unit>
1142 <trans-unit id="4bf47a1ae952bf42a4682a5ecddb0bfb8c9adfaf"> 1170 <trans-unit id="4bf47a1ae952bf42a4682a5ecddb0bfb8c9adfaf">
1143 <source>How does PeerTube compare with YouTube?</source> 1171 <source>How does PeerTube compare with YouTube?</source>
1144 <target>Jaký e PeerTube v porovnání s YouTube?</target> 1172 <target>Jaký je PeerTube v porovnání s YouTube?</target>
1145 <context-group name="null"> 1173 <context-group name="null">
1146 <context context-type="linenumber">67</context> 1174 <context context-type="linenumber">67</context>
1147 </context-group> 1175 </context-group>
@@ -1153,9 +1181,9 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1153 Moreover, YouTube is owned by Google/Alphabet, a company that tracks you across many websites (via AdSense or Google Analytics). 1181 Moreover, YouTube is owned by Google/Alphabet, a company that tracks you across many websites (via AdSense or Google Analytics).
1154 </source> 1182 </source>
1155 <target> 1183 <target>
1156 Ohrožení soukromí je na YouTube odlišné od toho na PeerTube. 1184 Ohrožení soukromí je na YouTubu odlišné od toho na PeerTubu.
1157 V případě YouTube, tato služba o vás sbírá obrovské mnžoství osobních informací (nejen vaší IP adresu), aby je poté analyzovala a sledovala vás. 1185 V případě YouTube, tato služba o vás sbírá obrovské mnžoství osobních informací (nejen vaší IP adresu), aby je poté analyzovala a sledovala vás.
1158 KromÄ› toho, YouTube je vlastnÄ›n Google/Alphabet, spoleÄností, která vás sleduje napÅ™Ã­Ä různými webovými stránkami (pÅ™es AdSense nebo Google Analytics). 1186 KromÄ› toho je YouTube vlastnÄ›n Googlem/Alphabetem, spoleÄností, která vás sleduje napÅ™Ã­Ä různými webovými stránkami (pÅ™es AdSense nebo Google Analytics).
1159 </target> 1187 </target>
1160 <context-group name="null"> 1188 <context-group name="null">
1161 <context context-type="linenumber">69</context> 1189 <context context-type="linenumber">69</context>
@@ -1190,6 +1218,19 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1190 <context context-type="linenumber">83</context> 1218 <context context-type="linenumber">83</context>
1191 </context-group> 1219 </context-group>
1192 </trans-unit> 1220 </trans-unit>
1221 <trans-unit id="b1372cb61ca791a0f7f95bf31c86c97df142adc4">
1222 <source>
1223 PeerTube is in its early stages, and want to deliver the best countermeasures possible by the time the stable is released.
1224 In the meantime, we want to test different ideas related to this issue:
1225 </source>
1226 <target>
1227 PeerTube je v rané fázi a chceme vám doruÄit ta nejlepší možná opatÅ™ení, dokud nebude vydána stabilní verze.
1228 Mezitím chceme vyzkoušet různé nápady spojené s tímto problémem:
1229 </target>
1230 <context-group name="null">
1231 <context context-type="linenumber">85</context>
1232 </context-group>
1233 </trans-unit>
1193 <trans-unit id="d32608aba08c6bb3cc4e4e8ec6223e5f4e78ca19"> 1234 <trans-unit id="d32608aba08c6bb3cc4e4e8ec6223e5f4e78ca19">
1194 <source>Set a limit to the number of peers sent by the tracker</source> 1235 <source>Set a limit to the number of peers sent by the tracker</source>
1195 <target>Nastavit limit poÄtu peerů odeslaných trackerem</target> 1236 <target>Nastavit limit poÄtu peerů odeslaných trackerem</target>
@@ -1225,6 +1266,13 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1225 <context context-type="linenumber">95</context> 1266 <context context-type="linenumber">95</context>
1226 </context-group> 1267 </context-group>
1227 </trans-unit> 1268 </trans-unit>
1269 <trans-unit id="bd2edf99dd6562385ccec19a7ab2d1898e626605">
1270 <source>Banned</source>
1271 <target>Zablokován</target>
1272 <context-group name="null">
1273 <context context-type="linenumber">12</context>
1274 </context-group>
1275 </trans-unit>
1228 <trans-unit id="a835d8a12e14eb96919245a0bbafd8069c146578"> 1276 <trans-unit id="a835d8a12e14eb96919245a0bbafd8069c146578">
1229 <source><x id="INTERPOLATION" equiv-text="{{ account.followersCount }}"/> subscribers</source> 1277 <source><x id="INTERPOLATION" equiv-text="{{ account.followersCount }}"/> subscribers</source>
1230 <target><x id="INTERPOLATION" equiv-text="{{ account.followersCount }}"/> odběratelů</target> 1278 <target><x id="INTERPOLATION" equiv-text="{{ account.followersCount }}"/> odběratelů</target>
@@ -1278,42 +1326,49 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1278 <source>Short description</source> 1326 <source>Short description</source>
1279 <target>Krátký popis</target> 1327 <target>Krátký popis</target>
1280 <context-group name="null"> 1328 <context-group name="null">
1281 <context context-type="linenumber">22</context> 1329 <context context-type="linenumber">21</context>
1282 </context-group> 1330 </context-group>
1283 </trans-unit> 1331 </trans-unit>
1284 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1332 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1285 <source>Default client route</source> 1333 <source>Default client route</source>
1286 <target>Výchozí hlavní stránka</target> 1334 <target>Výchozí hlavní stránka</target>
1287 <context-group name="null"> 1335 <context-group name="null">
1288 <context context-type="linenumber">55</context> 1336 <context context-type="linenumber">48</context>
1337 </context-group>
1338 </trans-unit>
1339 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1340 <source>Videos Overview</source>
1341 <target>Přehled videí</target>
1342 <context-group name="null">
1343 <context context-type="linenumber">51</context>
1289 </context-group> 1344 </context-group>
1290 </trans-unit> 1345 </trans-unit>
1291 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1346 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1292 <source>Videos Trending</source> 1347 <source>Videos Trending</source>
1293 <target>Trendy</target> 1348 <target>Trendy</target>
1294 <context-group name="null"> 1349 <context-group name="null">
1295 <context context-type="linenumber">59</context> 1350 <context context-type="linenumber">52</context>
1296 </context-group> 1351 </context-group>
1297 </trans-unit> 1352 </trans-unit>
1298 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1353 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1299 <source>Videos Recently Added</source> 1354 <source>Videos Recently Added</source>
1300 <target>Naposledy přidaná videa</target> 1355 <target>Naposledy přidaná videa</target>
1301 <context-group name="null"> 1356 <context-group name="null">
1302 <context context-type="linenumber">60</context> 1357 <context context-type="linenumber">53</context>
1303 </context-group> 1358 </context-group>
1304 </trans-unit> 1359 </trans-unit>
1305 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1360 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1306 <source>Local videos</source> 1361 <source>Local videos</source>
1307 <target>Místní videa</target> 1362 <target>Místní videa</target>
1308 <context-group name="null"> 1363 <context-group name="null">
1309 <context context-type="linenumber">61</context> 1364 <context context-type="linenumber">54</context>
1310 </context-group> 1365 </context-group>
1311 </trans-unit> 1366 </trans-unit>
1312 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1367 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1313 <source>Policy on videos containing sensitive content</source> 1368 <source>Policy on videos containing sensitive content</source>
1314 <target>Pravidla pro videa obsahující citlivý obsah</target> 1369 <target>Pravidla pro videa obsahující citlivý obsah</target>
1315 <context-group name="null"> 1370 <context-group name="null">
1316 <context context-type="linenumber">70</context> 1371 <context context-type="linenumber">61</context>
1317 </context-group> 1372 </context-group>
1318 </trans-unit> 1373 </trans-unit>
1319 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1374 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1348,42 +1403,63 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1348 <source>Signup enabled</source> 1403 <source>Signup enabled</source>
1349 <target>Povolit registrace</target> 1404 <target>Povolit registrace</target>
1350 <context-group name="null"> 1405 <context-group name="null">
1351 <context context-type="linenumber">93</context> 1406 <context context-type="linenumber">84</context>
1407 </context-group>
1408 </trans-unit>
1409 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1410 <source>Signup requires email verification</source>
1411 <target>Registrace vyžaduje ověření e-mailem.</target>
1412 <context-group name="null">
1413 <context context-type="linenumber">91</context>
1352 </context-group> 1414 </context-group>
1353 </trans-unit> 1415 </trans-unit>
1354 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1416 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1355 <source>Signup limit</source> 1417 <source>Signup limit</source>
1356 <target>Limit registrací</target> 1418 <target>Limit registrací</target>
1357 <context-group name="null"> 1419 <context-group name="null">
1420 <context context-type="linenumber">96</context>
1421 </context-group>
1422 </trans-unit>
1423 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1424 <source>Users</source>
1425 <target>Uživatelé</target>
1426 <context-group name="null">
1358 <context context-type="linenumber">105</context> 1427 <context context-type="linenumber">105</context>
1359 </context-group> 1428 </context-group>
1360 </trans-unit> 1429 </trans-unit>
1361 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1430 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1362 <source>Administrator</source> 1431 <source>User default video quota</source>
1363 <target>Administrátor</target> 1432 <target>Výchozí limit na uživatele</target>
1364 <context-group name="null"> 1433 <context-group name="null">
1365 <context context-type="linenumber">131</context> 1434 <context context-type="linenumber">109</context>
1366 </context-group> 1435 </context-group>
1367 </trans-unit> 1436 </trans-unit>
1368 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1437 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1369 <source>Admin email</source> 1438 <source>Import</source>
1370 <target>Email administrátora</target> 1439 <target>Import</target>
1371 <context-group name="null"> 1440 <context-group name="null">
1372 <context context-type="linenumber">134</context> 1441 <context context-type="linenumber">42</context>
1373 </context-group> 1442 </context-group>
1374 </trans-unit> 1443 </trans-unit>
1375 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be"> 1444 <trans-unit id="29aa67f13fd34a2421ff9d7de7d5142790676b9e">
1376 <source>Users</source> 1445 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1377 <target>Uživatelé</target> 1446 <target>Import videa pomocí URL HTTP (např. YouTube) povolen</target>
1378 <context-group name="null"> 1447 <context-group name="null">
1379 <context context-type="linenumber">144</context> 1448 <context context-type="linenumber">141</context>
1380 </context-group> 1449 </context-group>
1381 </trans-unit> 1450 </trans-unit>
1382 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09"> 1451 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1383 <source>User default video quota</source> 1452 <source>Administrator</source>
1384 <target>Výchozí limit na uživatele</target> 1453 <target>Administrátor</target>
1454 <context-group name="null">
1455 <context context-type="linenumber">155</context>
1456 </context-group>
1457 </trans-unit>
1458 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1459 <source>Admin email</source>
1460 <target>E-mail administrátora</target>
1385 <context-group name="null"> 1461 <context-group name="null">
1386 <context context-type="linenumber">147</context> 1462 <context context-type="linenumber">158</context>
1387 </context-group> 1463 </context-group>
1388 </trans-unit> 1464 </trans-unit>
1389 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1465 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1404,21 +1480,21 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1404 <source>Your Twitter username</source> 1480 <source>Your Twitter username</source>
1405 <target>Váš úÄet na Twitteru</target> 1481 <target>Váš úÄet na Twitteru</target>
1406 <context-group name="null"> 1482 <context-group name="null">
1407 <context context-type="linenumber">181</context> 1483 <context context-type="linenumber">184</context>
1408 </context-group> 1484 </context-group>
1409 </trans-unit> 1485 </trans-unit>
1410 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1486 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1411 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1487 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1412 <target>UveÄte Twitter úÄet stránky nebo služby, na které byl obsah publikován.</target> 1488 <target>UveÄte Twitter úÄet stránky nebo služby, na které byl obsah publikován.</target>
1413 <context-group name="null"> 1489 <context-group name="null">
1414 <context context-type="linenumber">184</context> 1490 <context context-type="linenumber">187</context>
1415 </context-group> 1491 </context-group>
1416 </trans-unit> 1492 </trans-unit>
1417 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1493 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1418 <source>Instance whitelisted by Twitter</source> 1494 <source>Instance whitelisted by Twitter</source>
1419 <target>Twitter povolil tuto instanci</target> 1495 <target>Twitter povolil tuto instanci</target>
1420 <context-group name="null"> 1496 <context-group name="null">
1421 <context context-type="linenumber">198</context> 1497 <context context-type="linenumber">199</context>
1422 </context-group> 1498 </context-group>
1423 </trans-unit> 1499 </trans-unit>
1424 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1500 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1432,77 +1508,99 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1432 <source>Transcoding</source> 1508 <source>Transcoding</source>
1433 <target>Překódování</target> 1509 <target>Překódování</target>
1434 <context-group name="null"> 1510 <context-group name="null">
1435 <context context-type="linenumber">210</context> 1511 <context context-type="linenumber">215</context>
1436 </context-group> 1512 </context-group>
1437 </trans-unit> 1513 </trans-unit>
1438 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1514 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1439 <source>Transcoding enabled</source> 1515 <source>Transcoding enabled</source>
1440 <target>Překódování povoleno</target> 1516 <target>Překódování povoleno</target>
1441 <context-group name="null"> 1517 <context-group name="null">
1442 <context context-type="linenumber">215</context> 1518 <context context-type="linenumber">221</context>
1443 </context-group> 1519 </context-group>
1444 </trans-unit> 1520 </trans-unit>
1445 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1521 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1446 <source>If you disable transcoding, many videos from your users will not work!</source> 1522 <source>If you disable transcoding, many videos from your users will not work!</source>
1447 <target>Pokud zakážete překódování, mnoho videí od vašich uživatelů nebude fungovat!</target> 1523 <target>Pokud zakážete překódování, mnoho videí od vašich uživatelů nebude fungovat!</target>
1448 <context-group name="null"> 1524 <context-group name="null">
1449 <context context-type="linenumber">216</context> 1525 <context context-type="linenumber">222</context>
1450 </context-group> 1526 </context-group>
1451 </trans-unit> 1527 </trans-unit>
1452 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1528 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1453 <source>Transcoding threads</source> 1529 <source>Transcoding threads</source>
1454 <target>Vlákna na překódování</target> 1530 <target>Vlákna na překódování</target>
1455 <context-group name="null"> 1531 <context-group name="null">
1456 <context context-type="linenumber">223</context> 1532 <context context-type="linenumber">237</context>
1533 </context-group>
1534 </trans-unit>
1535 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1536 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1537 <target>Rozlišení <x id="INTERPOLATION" equiv-text="{{resolution}}"/> povoleno</target>
1538 <context-group name="null">
1539 <context context-type="linenumber">252</context>
1540 </context-group>
1541 </trans-unit>
1542 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
1543 <source>
1544 Cache
1545
1546 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1547 </source>
1548 <target>
1549 Mezipaměť
1550
1551 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1552 </target>
1553 <context-group name="null">
1554 <context context-type="linenumber">260</context>
1457 </context-group> 1555 </context-group>
1458 </trans-unit> 1556 </trans-unit>
1459 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1557 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1460 <source>Previews cache size</source> 1558 <source>Previews cache size</source>
1461 <target>Velikost mezipaměti náhledů</target> 1559 <target>Velikost mezipaměti náhledů</target>
1462 <context-group name="null"> 1560 <context-group name="null">
1463 <context context-type="linenumber">254</context> 1561 <context context-type="linenumber">271</context>
1464 </context-group> 1562 </context-group>
1465 </trans-unit> 1563 </trans-unit>
1466 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1564 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1467 <source>Customizations</source> 1565 <source>Customizations</source>
1468 <target>Přizpůsobení</target> 1566 <target>Přizpůsobení</target>
1469 <context-group name="null"> 1567 <context-group name="null">
1470 <context context-type="linenumber">275</context> 1568 <context context-type="linenumber">289</context>
1471 </context-group> 1569 </context-group>
1472 </trans-unit> 1570 </trans-unit>
1473 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1571 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1474 <source>JavaScript</source> 1572 <source>JavaScript</source>
1475 <target>JavaScript</target> 1573 <target>JavaScript</target>
1476 <context-group name="null"> 1574 <context-group name="null">
1477 <context context-type="linenumber">278</context> 1575 <context context-type="linenumber">294</context>
1478 </context-group> 1576 </context-group>
1479 </trans-unit> 1577 </trans-unit>
1480 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1578 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1481 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1579 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1482 <target>Pište přímo JavaScript kód.&lt;br /&gt;Například: &lt;pre&gt;console.log('moje instance je úžasná');&lt;/pre&gt;</target> 1580 <target>Pište přímo JavaScript kód.&lt;br /&gt;Například: &lt;pre&gt;console.log('moje instance je úžasná');&lt;/pre&gt;</target>
1483 <context-group name="null"> 1581 <context-group name="null">
1484 <context context-type="linenumber">281</context> 1582 <context context-type="linenumber">297</context>
1485 </context-group> 1583 </context-group>
1486 </trans-unit> 1584 </trans-unit>
1487 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab"> 1585 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab">
1488 <source>Advanced configuration</source> 1586 <source>Advanced configuration</source>
1489 <target>PokroÄilá nastavení</target> 1587 <target>PokroÄilá nastavení</target>
1490 <context-group name="null"> 1588 <context-group name="null">
1491 <context context-type="linenumber">207</context> 1589 <context context-type="linenumber">212</context>
1492 </context-group> 1590 </context-group>
1493 </trans-unit> 1591 </trans-unit>
1494 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1592 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1495 <source>Update configuration</source> 1593 <source>Update configuration</source>
1496 <target>Aktualizovat nastavení</target> 1594 <target>Aktualizovat nastavení</target>
1497 <context-group name="null"> 1595 <context-group name="null">
1498 <context context-type="linenumber">325</context> 1596 <context context-type="linenumber">340</context>
1499 </context-group> 1597 </context-group>
1500 </trans-unit> 1598 </trans-unit>
1501 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1599 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1502 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1600 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1503 <target>Zdá se, že vaše konfigurace není validní. Prosím, vyhledejte potencialní chyby v jiné záložce.</target> 1601 <target>Zdá se, že vaše konfigurace není validní. Prosím, vyhledejte potencialní chyby v jiné záložce.</target>
1504 <context-group name="null"> 1602 <context-group name="null">
1505 <context context-type="linenumber">326</context> 1603 <context context-type="linenumber">341</context>
1506 </context-group> 1604 </context-group>
1507 </trans-unit> 1605 </trans-unit>
1508 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1606 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1527,6 +1625,17 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1527 <context context-type="linenumber">7</context> 1625 <context context-type="linenumber">7</context>
1528 </context-group> 1626 </context-group>
1529 </trans-unit> 1627 </trans-unit>
1628 <trans-unit id="1a5c7f9b1bec1463728f44933f0e256de9c45154">
1629 <source>
1630 Moderation
1631 </source>
1632 <target>
1633 Moderace
1634 </target>
1635 <context-group name="null">
1636 <context context-type="linenumber">11</context>
1637 </context-group>
1638 </trans-unit>
1530 <trans-unit id="7bea88c54fdccfdc9f687b0ffe9bf6a653d19368"> 1639 <trans-unit id="7bea88c54fdccfdc9f687b0ffe9bf6a653d19368">
1531 <source> 1640 <source>
1532 Jobs 1641 Jobs
@@ -1574,6 +1683,13 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1574 <context context-type="linenumber">21</context> 1683 <context context-type="linenumber">21</context>
1575 </context-group> 1684 </context-group>
1576 </trans-unit> 1685 </trans-unit>
1686 <trans-unit id="25925fc5826bc5b3eeae7c45b08b0ed74b9e2954">
1687 <source>Filter...</source>
1688 <target>Filtrovat...</target>
1689 <context-group name="null">
1690 <context context-type="linenumber">27</context>
1691 </context-group>
1692 </trans-unit>
1577 <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c"> 1693 <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c">
1578 <source>ID</source> 1694 <source>ID</source>
1579 <target>ID</target> 1695 <target>ID</target>
@@ -1713,6 +1829,13 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1713 <context context-type="linenumber">40</context> 1829 <context context-type="linenumber">40</context>
1714 </context-group> 1830 </context-group>
1715 </trans-unit> 1831 </trans-unit>
1832 <trans-unit id="adba7c8b43e42581460fbe5d08b5cb5ab60eba4b">
1833 <source>(banned)</source>
1834 <target>(zablokován)</target>
1835 <context-group name="null">
1836 <context context-type="linenumber">65</context>
1837 </context-group>
1838 </trans-unit>
1716 <trans-unit id="be73b652c2707f42b5d780d0c7b8fc5ea0b1706c"> 1839 <trans-unit id="be73b652c2707f42b5d780d0c7b8fc5ea0b1706c">
1717 <source>Go to the account page</source> 1840 <source>Go to the account page</source>
1718 <target>Přejít na stránku kanálu</target> 1841 <target>Přejít na stránku kanálu</target>
@@ -1720,6 +1843,31 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1720 <context context-type="linenumber">133</context> 1843 <context context-type="linenumber">133</context>
1721 </context-group> 1844 </context-group>
1722 </trans-unit> 1845 </trans-unit>
1846 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee">
1847 <source>Ban reason:</source>
1848 <target>Důvod zablokování:</target>
1849 <context-group name="null">
1850 <context context-type="linenumber">95</context>
1851 </context-group>
1852 </trans-unit>
1853 <trans-unit id="5731e5d5ac989bf08848b5a57a5586cf84d80964">
1854 <source>
1855 This comment can only be seen by you or the other moderators.
1856 </source>
1857 <target>
1858 Tento komentář můžete vidět pouze vy nebo ostatní moderátoři.
1859 </target>
1860 <context-group name="null">
1861 <context context-type="linenumber">17</context>
1862 </context-group>
1863 </trans-unit>
1864 <trans-unit id="0562e455c88234829f3c27a38f3039f027bfd5d2">
1865 <source>Update this comment</source>
1866 <target>Aktualizovat tento komentář</target>
1867 <context-group name="null">
1868 <context context-type="linenumber">25</context>
1869 </context-group>
1870 </trans-unit>
1723 <trans-unit id="2bf5a31043ff476ca081a4080f3f3f17518dc6f2"> 1871 <trans-unit id="2bf5a31043ff476ca081a4080f3f3f17518dc6f2">
1724 <source>Reporter</source> 1872 <source>Reporter</source>
1725 <target>Autor nahlášení</target> 1873 <target>Autor nahlášení</target>
@@ -1748,25 +1896,25 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1748 <context context-type="linenumber">33</context> 1896 <context context-type="linenumber">33</context>
1749 </context-group> 1897 </context-group>
1750 </trans-unit> 1898 </trans-unit>
1751 <trans-unit id="00ecde6001106fe7406a34cc3459cc5b88e4aec1"> 1899 <trans-unit id="030b4423b92167200e39519599f9b863b4f7c62c">
1752 <source>Blacklisted videos</source> 1900 <source>Actions</source>
1753 <target>Videa na Äerné listinÄ›</target> 1901 <target>Akce</target>
1754 <context-group name="null"> 1902 <context-group name="null">
1755 <context context-type="linenumber">7</context> 1903 <context context-type="linenumber">35</context>
1756 </context-group> 1904 </context-group>
1757 </trans-unit> 1905 </trans-unit>
1758 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6"> 1906 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
1759 <source>My settings</source> 1907 <source>Reason:</source>
1760 <target>Moje nastavení</target> 1908 <target>Důvod:</target>
1761 <context-group name="null"> 1909 <context-group name="null">
1762 <context context-type="linenumber">3</context> 1910 <context context-type="linenumber">53</context>
1763 </context-group> 1911 </context-group>
1764 </trans-unit> 1912 </trans-unit>
1765 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894"> 1913 <trans-unit id="00ecde6001106fe7406a34cc3459cc5b88e4aec1">
1766 <source>My videos</source> 1914 <source>Blacklisted videos</source>
1767 <target>Moje videa</target> 1915 <target>Videa na Äerné listinÄ›</target>
1768 <context-group name="null"> 1916 <context-group name="null">
1769 <context context-type="linenumber">14</context> 1917 <context context-type="linenumber">7</context>
1770 </context-group> 1918 </context-group>
1771 </trans-unit> 1919 </trans-unit>
1772 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 1920 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
@@ -1780,21 +1928,14 @@ Blokovaný uživatel se už nebude moci přihlásit.</target>
1780 <source>Profile</source> 1928 <source>Profile</source>
1781 <target>Profil</target> 1929 <target>Profil</target>
1782 <context-group name="null"> 1930 <context-group name="null">
1783 <context context-type="linenumber">8</context> 1931 <context context-type="linenumber">7</context>
1784 </context-group> 1932 </context-group>
1785 </trans-unit> 1933 </trans-unit>
1786 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 1934 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
1787 <source>Video settings</source> 1935 <source>Video settings</source>
1788 <target>Nastavení videí</target> 1936 <target>Nastavení videí</target>
1789 <context-group name="null"> 1937 <context-group name="null">
1790 <context context-type="linenumber">15</context> 1938 <context context-type="linenumber">16</context>
1791 </context-group>
1792 </trans-unit>
1793 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
1794 <source>Submit</source>
1795 <target>Odeslat</target>
1796 <context-group name="null">
1797 <context context-type="linenumber">24</context>
1798 </context-group> 1939 </context-group>
1799 </trans-unit> 1940 </trans-unit>
1800 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 1941 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
@@ -1915,6 +2056,13 @@ When you will upload a video in this channel, the video support field will be au
1915 <context context-type="linenumber">27</context> 2056 <context context-type="linenumber">27</context>
1916 </context-group> 2057 </context-group>
1917 </trans-unit> 2058 </trans-unit>
2059 <trans-unit id="4b50f2ef2e8b9a24e674d12012ee310f378a5503">
2060 <source><x id="INTERPOLATION" equiv-text="{{ actor.followersCount }}"/> subscribers</source>
2061 <target><x id="INTERPOLATION" equiv-text="{{ actor.followersCount }}"/> odběratelů</target>
2062 <context-group name="null">
2063 <context context-type="linenumber">10</context>
2064 </context-group>
2065 </trans-unit>
1918 <trans-unit id="c860c88df9ad58b1187084251340b232cdf0a7f9"> 2066 <trans-unit id="c860c88df9ad58b1187084251340b232cdf0a7f9">
1919 <source>(extensions: <x id="INTERPOLATION" equiv-text="{{ avatarExtensions }}"/>, max size: <x id="INTERPOLATION_1" equiv-text="{{ maxAvatarSize | bytes }}"/>)</source> 2067 <source>(extensions: <x id="INTERPOLATION" equiv-text="{{ avatarExtensions }}"/>, max size: <x id="INTERPOLATION_1" equiv-text="{{ maxAvatarSize | bytes }}"/>)</source>
1920 <target>(typ souboru: <x id="INTERPOLATION" equiv-text="{{ avatarExtensions }}"/>, maximální velikost: <x id="INTERPOLATION_1" equiv-text="{{ maxAvatarSize | bytes }}"/>)</target> 2068 <target>(typ souboru: <x id="INTERPOLATION" equiv-text="{{ avatarExtensions }}"/>, maximální velikost: <x id="INTERPOLATION_1" equiv-text="{{ maxAvatarSize | bytes }}"/>)</target>
@@ -1986,14 +2134,14 @@ When you will upload a video in this channel, the video support field will be au
1986 <source>Publish will be available when upload is finished</source> 2134 <source>Publish will be available when upload is finished</source>
1987 <target>Publikovat lze jakmile bude dokonÄeno nahrávání</target> 2135 <target>Publikovat lze jakmile bude dokonÄeno nahrávání</target>
1988 <context-group name="null"> 2136 <context-group name="null">
1989 <context context-type="linenumber">53</context> 2137 <context context-type="linenumber">58</context>
1990 </context-group> 2138 </context-group>
1991 </trans-unit> 2139 </trans-unit>
1992 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 2140 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
1993 <source>Publish</source> 2141 <source>Publish</source>
1994 <target>Publikovat</target> 2142 <target>Publikovat</target>
1995 <context-group name="null"> 2143 <context-group name="null">
1996 <context context-type="linenumber">60</context> 2144 <context context-type="linenumber">65</context>
1997 </context-group> 2145 </context-group>
1998 </trans-unit> 2146 </trans-unit>
1999 <trans-unit id="fdf7cbdc140d0aab0f0b6c06065a0fd448ed6a2e"> 2147 <trans-unit id="fdf7cbdc140d0aab0f0b6c06065a0fd448ed6a2e">
@@ -2005,11 +2153,18 @@ When you will upload a video in this channel, the video support field will be au
2005 </trans-unit> 2153 </trans-unit>
2006 <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b"> 2154 <trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b">
2007 <source>Tags</source> 2155 <source>Tags</source>
2008 <target>Tagy</target> 2156 <target>Štítky</target>
2009 <context-group name="null"> 2157 <context-group name="null">
2010 <context context-type="linenumber">191</context> 2158 <context context-type="linenumber">191</context>
2011 </context-group> 2159 </context-group>
2012 </trans-unit> 2160 </trans-unit>
2161 <trans-unit id="457b1cff4d8d7fad0c8742f69c413ecf5e443851">
2162 <source>Tags could be used to suggest relevant recommendations.&lt;/br&gt;Press Enter to add a new tag.</source>
2163 <target>Å títky mohou být použity pro navržení relevantních doporuÄení.&lt;/br&gt;Stisknutím klávesy Enter pÅ™idáte nový Å¡títek.</target>
2164 <context-group name="null">
2165 <context context-type="linenumber">18</context>
2166 </context-group>
2167 </trans-unit>
2013 <trans-unit id="50f53834157770b8205ada0e7a6e235211e4765e"> 2168 <trans-unit id="50f53834157770b8205ada0e7a6e235211e4765e">
2014 <source>Video descriptions are truncated by default and require manual action to expand them.</source> 2169 <source>Video descriptions are truncated by default and require manual action to expand them.</source>
2015 <target>Popisy videí jsou ve výchozím stavu sbaleny a rozbalují se kliknutím.</target> 2170 <target>Popisy videí jsou ve výchozím stavu sbaleny a rozbalují se kliknutím.</target>
@@ -2049,7 +2204,7 @@ When you will upload a video in this channel, the video support field will be au
2049 <source>Wait transcoding before publishing the video</source> 2204 <source>Wait transcoding before publishing the video</source>
2050 <target>Čekat na překódování před publikováním videa</target> 2205 <target>Čekat na překódování před publikováním videa</target>
2051 <context-group name="null"> 2206 <context-group name="null">
2052 <context context-type="linenumber">130</context> 2207 <context context-type="linenumber">131</context>
2053 </context-group> 2208 </context-group>
2054 </trans-unit> 2209 </trans-unit>
2055 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2210 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2063,14 +2218,14 @@ When you will upload a video in this channel, the video support field will be au
2063 <source>Upload thumbnail</source> 2218 <source>Upload thumbnail</source>
2064 <target>Nahrát miniaturu</target> 2219 <target>Nahrát miniaturu</target>
2065 <context-group name="null"> 2220 <context-group name="null">
2066 <context context-type="linenumber">195</context> 2221 <context context-type="linenumber">196</context>
2067 </context-group> 2222 </context-group>
2068 </trans-unit> 2223 </trans-unit>
2069 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 2224 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
2070 <source>Upload preview</source> 2225 <source>Upload preview</source>
2071 <target>Nahrát náhled</target> 2226 <target>Nahrát náhled</target>
2072 <context-group name="null"> 2227 <context-group name="null">
2073 <context context-type="linenumber">202</context> 2228 <context context-type="linenumber">203</context>
2074 </context-group> 2229 </context-group>
2075 </trans-unit> 2230 </trans-unit>
2076 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 2231 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -2084,14 +2239,14 @@ When you will upload a video in this channel, the video support field will be au
2084 <source>Short text to tell people how they can support you (membership platform...).</source> 2239 <source>Short text to tell people how they can support you (membership platform...).</source>
2085 <target>Krátký text, co řekne lidem, jak vás mohou podpořit.</target> 2240 <target>Krátký text, co řekne lidem, jak vás mohou podpořit.</target>
2086 <context-group name="null"> 2241 <context-group name="null">
2087 <context context-type="linenumber">209</context> 2242 <context context-type="linenumber">210</context>
2088 </context-group> 2243 </context-group>
2089 </trans-unit> 2244 </trans-unit>
2090 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 2245 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
2091 <source>Advanced settings</source> 2246 <source>Advanced settings</source>
2092 <target>Rozšířená nastavení</target> 2247 <target>Rozšířená nastavení</target>
2093 <context-group name="null"> 2248 <context-group name="null">
2094 <context context-type="linenumber">190</context> 2249 <context context-type="linenumber">191</context>
2095 </context-group> 2250 </context-group>
2096 </trans-unit> 2251 </trans-unit>
2097 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 2252 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -2342,13 +2497,6 @@ When you will upload a video in this channel, the video support field will be au
2342 <context context-type="linenumber">14</context> 2497 <context context-type="linenumber">14</context>
2343 </context-group> 2498 </context-group>
2344 </trans-unit> 2499 </trans-unit>
2345 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
2346 <source>Error getting about from server</source>
2347 <target>Chyba při získávání popisu</target>
2348 <context-group name="null">
2349 <context context-type="linenumber">1</context>
2350 </context-group>
2351 </trans-unit>
2352 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 2500 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
2353 <source>No description</source> 2501 <source>No description</source>
2354 <target>Žádný popis</target> 2502 <target>Žádný popis</target>
@@ -2370,20 +2518,6 @@ When you will upload a video in this channel, the video support field will be au
2370 <context context-type="linenumber">1</context> 2518 <context context-type="linenumber">1</context>
2371 </context-group> 2519 </context-group>
2372 </trans-unit> 2520 </trans-unit>
2373 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
2374 <source>Error</source>
2375 <target>Chyba</target>
2376 <context-group name="null">
2377 <context context-type="linenumber">1</context>
2378 </context-group>
2379 </trans-unit>
2380 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
2381 <source>Success</source>
2382 <target>Úspěšně</target>
2383 <context-group name="null">
2384 <context context-type="linenumber">1</context>
2385 </context-group>
2386 </trans-unit>
2387 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 2521 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
2388 <source>Configuration updated.</source> 2522 <source>Configuration updated.</source>
2389 <target>Nastavení aktualizováno.</target> 2523 <target>Nastavení aktualizováno.</target>
@@ -2489,6 +2623,27 @@ When you will upload a video in this channel, the video support field will be au
2489 <context context-type="linenumber">1</context> 2623 <context context-type="linenumber">1</context>
2490 </context-group> 2624 </context-group>
2491 </trans-unit> 2625 </trans-unit>
2626 <trans-unit id="50dc7afa2305131cdbdb384cfc1f2a5f0f4647d8">
2627 <source>Unban</source>
2628 <target>Odblokovat</target>
2629 <context-group name="null">
2630 <context context-type="linenumber">1</context>
2631 </context-group>
2632 </trans-unit>
2633 <trans-unit id="98119091712a8ca72905e3b4c1cf60649af7565e">
2634 <source>Do you really want to unban <x id="INTERPOLATION" equiv-text="{{num}}"/> users?</source>
2635 <target>Opravdu chcete odblokovat <x id="INTERPOLATION" equiv-text="{{num}}"/> uživatelů?</target>
2636 <context-group name="null">
2637 <context context-type="linenumber">1</context>
2638 </context-group>
2639 </trans-unit>
2640 <trans-unit id="6121be086a51c4c73bbdd8aebdddd9744c8f1ffd">
2641 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users unbanned.</source>
2642 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> uživatelů odblokováno.</target>
2643 <context-group name="null">
2644 <context context-type="linenumber">1</context>
2645 </context-group>
2646 </trans-unit>
2492 <trans-unit id="911fc197949e47aa5f0541627bc319f59edd9d11"> 2647 <trans-unit id="911fc197949e47aa5f0541627bc319f59edd9d11">
2493 <source>You cannot delete root.</source> 2648 <source>You cannot delete root.</source>
2494 <target>Uživatel root nelze odstranit.</target> 2649 <target>Uživatel root nelze odstranit.</target>
@@ -2545,23 +2700,16 @@ When you will upload a video in this channel, the video support field will be au
2545 <context context-type="linenumber">1</context> 2700 <context context-type="linenumber">1</context>
2546 </context-group> 2701 </context-group>
2547 </trans-unit> 2702 </trans-unit>
2548 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 2703 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
2549 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 2704 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
2550 <target>Opravdu chcete odstranit <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? Tato akce odstraní i veškerá videa na tomto kanálu.</target> 2705 <target>Video kanál <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> odstraněn.</target>
2551 <context-group name="null">
2552 <context context-type="linenumber">1</context>
2553 </context-group>
2554 </trans-unit>
2555 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
2556 <source>Please type the name of the video channel to confirm</source>
2557 <target>Prosím, napište název tohoto kanálu pro potvrzení</target>
2558 <context-group name="null"> 2706 <context-group name="null">
2559 <context context-type="linenumber">1</context> 2707 <context context-type="linenumber">1</context>
2560 </context-group> 2708 </context-group>
2561 </trans-unit> 2709 </trans-unit>
2562 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 2710 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2563 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 2711 <source>My videos</source>
2564 <target>Video kanál <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> odstraněn.</target> 2712 <target>Moje videa</target>
2565 <context-group name="null"> 2713 <context-group name="null">
2566 <context context-type="linenumber">1</context> 2714 <context context-type="linenumber">1</context>
2567 </context-group> 2715 </context-group>
@@ -2622,6 +2770,20 @@ When you will upload a video in this channel, the video support field will be au
2622 <context context-type="linenumber">1</context> 2770 <context context-type="linenumber">1</context>
2623 </context-group> 2771 </context-group>
2624 </trans-unit> 2772 </trans-unit>
2773 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2774 <source>My subscriptions</source>
2775 <target>Moje odběry</target>
2776 <context-group name="null">
2777 <context context-type="linenumber">1</context>
2778 </context-group>
2779 </trans-unit>
2780 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2781 <source>My settings</source>
2782 <target>Moje nastavení</target>
2783 <context-group name="null">
2784 <context context-type="linenumber">1</context>
2785 </context-group>
2786 </trans-unit>
2625 <trans-unit id="ccbf0490fb6b60d21e03bb2c9003df0ce1a58752"> 2787 <trans-unit id="ccbf0490fb6b60d21e03bb2c9003df0ce1a58752">
2626 <source>Unable to find user id or verification string.</source> 2788 <source>Unable to find user id or verification string.</source>
2627 <target>Nelze najít uživatelovo id nebo verifikaÄní Å™etÄ›zec.</target> 2789 <target>Nelze najít uživatelovo id nebo verifikaÄní Å™etÄ›zec.</target>
@@ -2629,6 +2791,13 @@ When you will upload a video in this channel, the video support field will be au
2629 <context context-type="linenumber">1</context> 2791 <context context-type="linenumber">1</context>
2630 </context-group> 2792 </context-group>
2631 </trans-unit> 2793 </trans-unit>
2794 <trans-unit id="ff6becacbce7fc0943b0af0df4dd67e5e11bf598">
2795 <source>Subscribe to the account</source>
2796 <target>Odebírat úÄet</target>
2797 <context-group name="null">
2798 <context context-type="linenumber">1</context>
2799 </context-group>
2800 </trans-unit>
2632 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7"> 2801 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7">
2633 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>. 2802 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>.
2634</source> 2803</source>
@@ -2645,6 +2814,13 @@ When you will upload a video in this channel, the video support field will be au
2645 <context context-type="linenumber">1</context> 2814 <context context-type="linenumber">1</context>
2646 </context-group> 2815 </context-group>
2647 </trans-unit> 2816 </trans-unit>
2817 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
2818 <source>Error</source>
2819 <target>Chyba</target>
2820 <context-group name="null">
2821 <context context-type="linenumber">1</context>
2822 </context-group>
2823 </trans-unit>
2648 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 2824 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
2649 <source>You need to reconnect.</source> 2825 <source>You need to reconnect.</source>
2650 <target>Musíte se znovu připojit.</target> 2826 <target>Musíte se znovu připojit.</target>
@@ -2659,6 +2835,20 @@ When you will upload a video in this channel, the video support field will be au
2659 <context context-type="linenumber">1</context> 2835 <context context-type="linenumber">1</context>
2660 </context-group> 2836 </context-group>
2661 </trans-unit> 2837 </trans-unit>
2838 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
2839 <source>Info</source>
2840 <target>Info</target>
2841 <context-group name="null">
2842 <context context-type="linenumber">1</context>
2843 </context-group>
2844 </trans-unit>
2845 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
2846 <source>Success</source>
2847 <target>Úspěšně</target>
2848 <context-group name="null">
2849 <context context-type="linenumber">1</context>
2850 </context-group>
2851 </trans-unit>
2662 <trans-unit id="b0f24b7136e551a0deba831f1525711245b31a26"> 2852 <trans-unit id="b0f24b7136e551a0deba831f1525711245b31a26">
2663 <source>Your password has been successfully reset!</source> 2853 <source>Your password has been successfully reset!</source>
2664 <target>Vaše heslo bylo úspěšně resetováno!</target> 2854 <target>Vaše heslo bylo úspěšně resetováno!</target>
@@ -2745,14 +2935,14 @@ When you will upload a video in this channel, the video support field will be au
2745 </trans-unit> 2935 </trans-unit>
2746 <trans-unit id="1245841647f9b42d3e7554903c1c50bdd80ab021"> 2936 <trans-unit id="1245841647f9b42d3e7554903c1c50bdd80ab021">
2747 <source>Admin email is required.</source> 2937 <source>Admin email is required.</source>
2748 <target>Email administrátora je vyžadován.</target> 2938 <target>E-mail administrátora je vyžadován.</target>
2749 <context-group name="null"> 2939 <context-group name="null">
2750 <context context-type="linenumber">1</context> 2940 <context context-type="linenumber">1</context>
2751 </context-group> 2941 </context-group>
2752 </trans-unit> 2942 </trans-unit>
2753 <trans-unit id="3fd2feb77dfe57fe82573e3cdf996105e2fafc66"> 2943 <trans-unit id="3fd2feb77dfe57fe82573e3cdf996105e2fafc66">
2754 <source>Admin email must be valid.</source> 2944 <source>Admin email must be valid.</source>
2755 <target>Email administrátora musí být platný.</target> 2945 <target>E-mail administrátora musí být platný.</target>
2756 <context-group name="null"> 2946 <context-group name="null">
2757 <context context-type="linenumber">1</context> 2947 <context context-type="linenumber">1</context>
2758 </context-group> 2948 </context-group>
@@ -2764,6 +2954,20 @@ When you will upload a video in this channel, the video support field will be au
2764 <context context-type="linenumber">1</context> 2954 <context context-type="linenumber">1</context>
2765 </context-group> 2955 </context-group>
2766 </trans-unit> 2956 </trans-unit>
2957 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
2958 <source>Email is required.</source>
2959 <target>E-mail je vyžadován.</target>
2960 <context-group name="null">
2961 <context context-type="linenumber">1</context>
2962 </context-group>
2963 </trans-unit>
2964 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
2965 <source>Email must be valid.</source>
2966 <target>E-mail musí být platný.</target>
2967 <context-group name="null">
2968 <context context-type="linenumber">1</context>
2969 </context-group>
2970 </trans-unit>
2767 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 2971 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
2768 <source>Username is required.</source> 2972 <source>Username is required.</source>
2769 <target>Uživatelské jméno je vyžadováno.</target> 2973 <target>Uživatelské jméno je vyžadováno.</target>
@@ -2785,41 +2989,6 @@ When you will upload a video in this channel, the video support field will be au
2785 <context context-type="linenumber">1</context> 2989 <context context-type="linenumber">1</context>
2786 </context-group> 2990 </context-group>
2787 </trans-unit> 2991 </trans-unit>
2788 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
2789 <source>Username must be at least 3 characters long.</source>
2790 <target>Uživatelské jméno musí mít délku minimálně 3 znaky.</target>
2791 <context-group name="null">
2792 <context context-type="linenumber">1</context>
2793 </context-group>
2794 </trans-unit>
2795 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
2796 <source>Username cannot be more than 20 characters long.</source>
2797 <target>Uživatelské jméno nemůže být delší než 20 znaků.</target>
2798 <context-group name="null">
2799 <context context-type="linenumber">1</context>
2800 </context-group>
2801 </trans-unit>
2802 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
2803 <source>Username should be only lowercase alphanumeric characters.</source>
2804 <target>Uživatelské jméno by mÄ›lo obsahovat pouze malá písmena a Äíslice.</target>
2805 <context-group name="null">
2806 <context context-type="linenumber">1</context>
2807 </context-group>
2808 </trans-unit>
2809 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
2810 <source>Email is required.</source>
2811 <target>Email je vyžadován.</target>
2812 <context-group name="null">
2813 <context context-type="linenumber">1</context>
2814 </context-group>
2815 </trans-unit>
2816 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
2817 <source>Email must be valid.</source>
2818 <target>Email musí být platný.</target>
2819 <context-group name="null">
2820 <context context-type="linenumber">1</context>
2821 </context-group>
2822 </trans-unit>
2823 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 2992 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
2824 <source>Password must be at least 6 characters long.</source> 2993 <source>Password must be at least 6 characters long.</source>
2825 <target>Heslo musí mít délku minimálně 6 znaků.</target> 2994 <target>Heslo musí mít délku minimálně 6 znaků.</target>
@@ -2869,20 +3038,6 @@ When you will upload a video in this channel, the video support field will be au
2869 <context context-type="linenumber">1</context> 3038 <context context-type="linenumber">1</context>
2870 </context-group> 3039 </context-group>
2871 </trans-unit> 3040 </trans-unit>
2872 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
2873 <source>Display name must be at least 3 characters long.</source>
2874 <target>Zobrazované jméno musí mít delku minimálně 3 znaky.</target>
2875 <context-group name="null">
2876 <context context-type="linenumber">1</context>
2877 </context-group>
2878 </trans-unit>
2879 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
2880 <source>Display name cannot be more than 120 characters long.</source>
2881 <target>Zobrazované jméno nesmí být delší než 120 znaků.</target>
2882 <context-group name="null">
2883 <context context-type="linenumber">1</context>
2884 </context-group>
2885 </trans-unit>
2886 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 3041 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
2887 <source>Description must be at least 3 characters long.</source> 3042 <source>Description must be at least 3 characters long.</source>
2888 <target>Popis musí mít délku minimálně 3 znaky.</target> 3043 <target>Popis musí mít délku minimálně 3 znaky.</target>
@@ -2904,13 +3059,6 @@ When you will upload a video in this channel, the video support field will be au
2904 <context context-type="linenumber">1</context> 3059 <context context-type="linenumber">1</context>
2905 </context-group> 3060 </context-group>
2906 </trans-unit> 3061 </trans-unit>
2907 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
2908 <source>Report reason cannot be more than 300 characters long.</source>
2909 <target>Důvod nahlášení nesmí být delší než 300 znaků.</target>
2910 <context-group name="null">
2911 <context context-type="linenumber">1</context>
2912 </context-group>
2913 </trans-unit>
2914 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 3062 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
2915 <source>Support text must be at least 3 characters long.</source> 3063 <source>Support text must be at least 3 characters long.</source>
2916 <target>Text pro podporu musí mít délku minimálně 3 znaky.</target> 3064 <target>Text pro podporu musí mít délku minimálně 3 znaky.</target>
@@ -3506,6 +3654,34 @@ When you will upload a video in this channel, the video support field will be au
3506 <context context-type="linenumber">1</context> 3654 <context context-type="linenumber">1</context>
3507 </context-group> 3655 </context-group>
3508 </trans-unit> 3656 </trans-unit>
3657 <trans-unit id="f9b4f2d8146c789cd40314f640ec4e88efbaf681">
3658 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users banned.</source>
3659 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> uživatelů zablokováno.</target>
3660 <context-group name="null">
3661 <context context-type="linenumber">1</context>
3662 </context-group>
3663 </trans-unit>
3664 <trans-unit id="3ab99e62550869aebc85661fca2faf46785263dd">
3665 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> banned.</source>
3666 <target>Uživatel <x id="INTERPOLATION" equiv-text="{{username}}"/> zablokován.</target>
3667 <context-group name="null">
3668 <context context-type="linenumber">1</context>
3669 </context-group>
3670 </trans-unit>
3671 <trans-unit id="faafee0c03ad25c8a43aa91bd5d98185b67ff734">
3672 <source>Do you really want to unban <x id="INTERPOLATION" equiv-text="{{username}}"/>?</source>
3673 <target>Opravdu chcete odblokovat uživatele <x id="INTERPOLATION" equiv-text="{{username}}"/>?</target>
3674 <context-group name="null">
3675 <context context-type="linenumber">1</context>
3676 </context-group>
3677 </trans-unit>
3678 <trans-unit id="925ba9946b7b256a586f0fcbe3e04fa7a0dee7bd">
3679 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> unbanned.</source>
3680 <target>Uživatel <x id="INTERPOLATION" equiv-text="{{username}}"/> odblokován.</target>
3681 <context-group name="null">
3682 <context context-type="linenumber">1</context>
3683 </context-group>
3684 </trans-unit>
3509 <trans-unit id="28220fae6799ab98ef6b41af449aa9680082357a"> 3685 <trans-unit id="28220fae6799ab98ef6b41af449aa9680082357a">
3510 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> deleted.</source> 3686 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> deleted.</source>
3511 <target>Uživatel <x id="INTERPOLATION" equiv-text="{{username}}"/> odstraněn.</target> 3687 <target>Uživatel <x id="INTERPOLATION" equiv-text="{{username}}"/> odstraněn.</target>
@@ -3541,16 +3717,51 @@ When you will upload a video in this channel, the video support field will be au
3541 <context context-type="linenumber">1</context> 3717 <context context-type="linenumber">1</context>
3542 </context-group> 3718 </context-group>
3543 </trans-unit> 3719 </trans-unit>
3720 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
3721 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
3722 <target>Odebíráte kanál <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
3723 <context-group name="null">
3724 <context context-type="linenumber">1</context>
3725 </context-group>
3726 </trans-unit>
3544 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1"> 3727 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
3545 <source>Subscribed</source> 3728 <source>Subscribed</source>
3546 <target>Odebírám</target> 3729 <target>Odebíráte</target>
3730 <context-group name="null">
3731 <context context-type="linenumber">1</context>
3732 </context-group>
3733 </trans-unit>
3734 <trans-unit id="3e7735fa326fcdc9e1188b6d9ff4b4329312fc26">
3735 <source>Unsubscribed from <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
3736 <target>Již neodebíráte kanál <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
3737 <context-group name="null">
3738 <context context-type="linenumber">1</context>
3739 </context-group>
3740 </trans-unit>
3741 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
3742 <source>Unsubscribed</source>
3743 <target>Odběr zrušen</target>
3744 <context-group name="null">
3745 <context context-type="linenumber">1</context>
3746 </context-group>
3747 </trans-unit>
3748 <trans-unit id="15be15cbdc6e960f57e801f457c19165ab39632b">
3749 <source>Anyone can see this video</source>
3750 <target>Kdokoliv může vidět toto video</target>
3751 <context-group name="null">
3752 <context context-type="linenumber">1</context>
3753 </context-group>
3754 </trans-unit>
3755 <trans-unit id="14200e26888a07633c0f177020dce8f3ec7311a6">
3756 <source>You are now logged in as <x id="INTERPOLATION" equiv-text="{{username}}"/>!</source>
3757 <target>Nyní jste přihlášen/a jako <x id="INTERPOLATION" equiv-text="{{username}}"/>!</target>
3547 <context-group name="null"> 3758 <context-group name="null">
3548 <context context-type="linenumber">1</context> 3759 <context context-type="linenumber">1</context>
3549 </context-group> 3760 </context-group>
3550 </trans-unit> 3761 </trans-unit>
3551 <trans-unit id="24840228f2826b66252cfcaab9820b1c7e0da264"> 3762 <trans-unit id="24840228f2826b66252cfcaab9820b1c7e0da264">
3552 <source>But associated data (tags, description...) will be lost, are you sure you want to leave this page?</source> 3763 <source>But associated data (tags, description...) will be lost, are you sure you want to leave this page?</source>
3553 <target>Přiřazená data (tagy, popis...) budou ztraceny, opravdu chcete opustit tuto stránku?</target> 3764 <target>Ovšem přidružená data (štítky, popis...) budou ztraceny, opravdu chcete opustit tuto stránku?</target>
3554 <context-group name="null"> 3765 <context-group name="null">
3555 <context context-type="linenumber">1</context> 3766 <context context-type="linenumber">1</context>
3556 </context-group> 3767 </context-group>
@@ -3562,13 +3773,6 @@ When you will upload a video in this channel, the video support field will be au
3562 <context context-type="linenumber">1</context> 3773 <context context-type="linenumber">1</context>
3563 </context-group> 3774 </context-group>
3564 </trans-unit> 3775 </trans-unit>
3565 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
3566 <source>Info</source>
3567 <target>Info</target>
3568 <context-group name="null">
3569 <context context-type="linenumber">1</context>
3570 </context-group>
3571 </trans-unit>
3572 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 3776 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
3573 <source>Upload cancelled</source> 3777 <source>Upload cancelled</source>
3574 <target>Nahrávání zrušeno</target> 3778 <target>Nahrávání zrušeno</target>
@@ -3611,6 +3815,20 @@ When you will upload a video in this channel, the video support field will be au
3611 <context context-type="linenumber">1</context> 3815 <context context-type="linenumber">1</context>
3612 </context-group> 3816 </context-group>
3613 </trans-unit> 3817 </trans-unit>
3818 <trans-unit id="0e65067fdcc9d8725a41896cb1e229d1415a45f6">
3819 <source>Like the video</source>
3820 <target>To se mi líbí</target>
3821 <context-group name="null">
3822 <context context-type="linenumber">1</context>
3823 </context-group>
3824 </trans-unit>
3825 <trans-unit id="1a999e06e1aca0a70cd7d0e3e5c2c63d0e1885c8">
3826 <source>Dislike the video</source>
3827 <target>To se mi nelíbí</target>
3828 <context-group name="null">
3829 <context context-type="linenumber">1</context>
3830 </context-group>
3831 </trans-unit>
3614 <trans-unit id="f1abd89c9280323209e939fa9c30f6e5cda20c95"> 3832 <trans-unit id="f1abd89c9280323209e939fa9c30f6e5cda20c95">
3615 <source>Do you really want to delete this video?</source> 3833 <source>Do you really want to delete this video?</source>
3616 <target>Opravdu chcete odstranit toto video?</target> 3834 <target>Opravdu chcete odstranit toto video?</target>
@@ -3620,7 +3838,7 @@ When you will upload a video in this channel, the video support field will be au
3620 </trans-unit> 3838 </trans-unit>
3621 <trans-unit id="d5a4811e15319ad9354e1b62e9ca0131192b489e"> 3839 <trans-unit id="d5a4811e15319ad9354e1b62e9ca0131192b489e">
3622 <source><x id="INTERPOLATION" equiv-text="{{likesNumber}}"/> likes / <x id="INTERPOLATION_1" equiv-text="{{dislikesNumber}}"/> dislikes</source> 3840 <source><x id="INTERPOLATION" equiv-text="{{likesNumber}}"/> likes / <x id="INTERPOLATION_1" equiv-text="{{dislikesNumber}}"/> dislikes</source>
3623 <target><x id="INTERPOLATION" equiv-text="{{likesNumber}}"/> se to líbí / <x id="INTERPOLATION_1" equiv-text="{{dislikesNumber}}"/> se to nelíbí</target> 3841 <target><x id="INTERPOLATION" equiv-text="{{likesNumber}}"/> se to líbí / <x id="INTERPOLATION_1" equiv-text="{{dislikesNumber}}"/> lidem se to nelíbí</target>
3624 <context-group name="null"> 3842 <context-group name="null">
3625 <context context-type="linenumber">1</context> 3843 <context context-type="linenumber">1</context>
3626 </context-group> 3844 </context-group>
@@ -3639,5 +3857,12 @@ When you will upload a video in this channel, the video support field will be au
3639 <context context-type="linenumber">1</context> 3857 <context context-type="linenumber">1</context>
3640 </context-group> 3858 </context-group>
3641 </trans-unit> 3859 </trans-unit>
3860 <trans-unit id="1b157e15c434469d91e56d027b78bf69c9983165">
3861 <source>Videos from your subscriptions</source>
3862 <target>Videa od vašich odběrů</target>
3863 <context-group name="null">
3864 <context context-type="linenumber">1</context>
3865 </context-group>
3866 </trans-unit>
3642 </body> 3867 </body>
3643 </file></xliff> \ No newline at end of file 3868 </file></xliff> \ No newline at end of file
diff --git a/client/src/locale/target/angular_de_DE.xml b/client/src/locale/target/angular_de_DE.xml
index 46e622908..39610dfdb 100644
--- a/client/src/locale/target/angular_de_DE.xml
+++ b/client/src/locale/target/angular_de_DE.xml
@@ -499,7 +499,7 @@
499 <source>Password</source> 499 <source>Password</source>
500 <target>Passwort</target> 500 <target>Passwort</target>
501 <context-group name="null"> 501 <context-group name="null">
502 <context context-type="linenumber">12</context> 502 <context context-type="linenumber">13</context>
503 </context-group> 503 </context-group>
504 </trans-unit> 504 </trans-unit>
505 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 505 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -513,7 +513,7 @@
513 <source>Login</source> 513 <source>Login</source>
514 <target>Anmelden</target> 514 <target>Anmelden</target>
515 <context-group name="null"> 515 <context-group name="null">
516 <context context-type="linenumber">38</context> 516 <context context-type="linenumber">36</context>
517 </context-group> 517 </context-group>
518 </trans-unit> 518 </trans-unit>
519 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 519 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -541,7 +541,7 @@
541 <source>Send me an email to reset my password</source> 541 <source>Send me an email to reset my password</source>
542 <target>Mir eine E-Mail schicken, um mein Passwort zurückzusetzen</target> 542 <target>Mir eine E-Mail schicken, um mein Passwort zurückzusetzen</target>
543 <context-group name="null"> 543 <context-group name="null">
544 <context context-type="linenumber">75</context> 544 <context context-type="linenumber">80</context>
545 </context-group> 545 </context-group>
546 </trans-unit> 546 </trans-unit>
547 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 547 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -600,11 +600,18 @@ Konto erstellen</target>
600 <context context-type="linenumber">17</context> 600 <context context-type="linenumber">17</context>
601 </context-group> 601 </context-group>
602 </trans-unit> 602 </trans-unit>
603 <trans-unit id="7fe213724c4c0a4112c40c673884acb98a0a3b92">
604 <source>I am at least 16 years old and agree to the &lt;a href='/about/instance#terms-section' target='_blank'rel='noopener noreferrer'&gt;Terms&lt;/a&gt; of this instance</source>
605 <target>Ich bin mindestens 16 Jahre alt und stimme den &lt;a href='/about/instance#terms-section' target='_blank'rel='noopener noreferrer'&gt;Bestimmungen&lt;/a&gt; dieser Instanz zu</target>
606 <context-group name="null">
607 <context context-type="linenumber">55</context>
608 </context-group>
609 </trans-unit>
603 <trans-unit id="717a5e3574fec754fbeb348c2d5561c4d81facc4"> 610 <trans-unit id="717a5e3574fec754fbeb348c2d5561c4d81facc4">
604 <source>Signup</source> 611 <source>Signup</source>
605 <target>Registrieren</target> 612 <target>Registrieren</target>
606 <context-group name="null"> 613 <context-group name="null">
607 <context context-type="linenumber">88</context> 614 <context context-type="linenumber">78</context>
608 </context-group> 615 </context-group>
609 </trans-unit> 616 </trans-unit>
610 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 617 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -632,6 +639,19 @@ Konto erstellen</target>
632 <context context-type="linenumber">6</context> 639 <context context-type="linenumber">6</context>
633 </context-group> 640 </context-group>
634 </trans-unit> 641 </trans-unit>
642 <trans-unit id="7c603b9ed878097782e2b8908f662e2344b46061">
643 <source>
644 Filters
645 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/><x id="INTERPOLATION" equiv-text="{{ numberOfFilters() }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
646 </source>
647 <target>
648 Filter
649 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/><x id="INTERPOLATION" equiv-text="{{ numberOfFilters() }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
650 </target>
651 <context-group name="null">
652 <context context-type="linenumber">16</context>
653 </context-group>
654 </trans-unit>
635 <trans-unit id="e2dbf0426cbb0b573faf49dffeb7d5bdf16eda5d"> 655 <trans-unit id="e2dbf0426cbb0b573faf49dffeb7d5bdf16eda5d">
636 <source> 656 <source>
637 No results found 657 No results found
@@ -661,7 +681,7 @@ Konto erstellen</target>
661 <source>Change the language</source> 681 <source>Change the language</source>
662 <target>Sprache wechseln</target> 682 <target>Sprache wechseln</target>
663 <context-group name="null"> 683 <context-group name="null">
664 <context context-type="linenumber">88</context> 684 <context context-type="linenumber">86</context>
665 </context-group> 685 </context-group>
666 </trans-unit> 686 </trans-unit>
667 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 687 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -672,7 +692,7 @@ Konto erstellen</target>
672 Mein öffentliches Profil 692 Mein öffentliches Profil
673 </target> 693 </target>
674 <context-group name="null"> 694 <context-group name="null">
675 <context context-type="linenumber">18</context> 695 <context context-type="linenumber">16</context>
676 </context-group> 696 </context-group>
677 </trans-unit> 697 </trans-unit>
678 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 698 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -683,7 +703,7 @@ Konto erstellen</target>
683 Mein Konto 703 Mein Konto
684 </target> 704 </target>
685 <context-group name="null"> 705 <context-group name="null">
686 <context context-type="linenumber">22</context> 706 <context context-type="linenumber">20</context>
687 </context-group> 707 </context-group>
688 </trans-unit> 708 </trans-unit>
689 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 709 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -694,7 +714,7 @@ Konto erstellen</target>
694 Meine Videos 714 Meine Videos
695 </target> 715 </target>
696 <context-group name="null"> 716 <context-group name="null">
697 <context context-type="linenumber">26</context> 717 <context context-type="linenumber">24</context>
698 </context-group> 718 </context-group>
699 </trans-unit> 719 </trans-unit>
700 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 720 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -705,14 +725,14 @@ Konto erstellen</target>
705 Abmelden 725 Abmelden
706 </target> 726 </target>
707 <context-group name="null"> 727 <context-group name="null">
708 <context context-type="linenumber">30</context> 728 <context context-type="linenumber">28</context>
709 </context-group> 729 </context-group>
710 </trans-unit> 730 </trans-unit>
711 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 731 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
712 <source>Create an account</source> 732 <source>Create an account</source>
713 <target>Konto erstellen</target> 733 <target>Konto erstellen</target>
714 <context-group name="null"> 734 <context-group name="null">
715 <context context-type="linenumber">39</context> 735 <context context-type="linenumber">37</context>
716 </context-group> 736 </context-group>
717 </trans-unit> 737 </trans-unit>
718 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 738 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -726,49 +746,49 @@ Konto erstellen</target>
726 <source>Subscriptions</source> 746 <source>Subscriptions</source>
727 <target>Abos</target> 747 <target>Abos</target>
728 <context-group name="null"> 748 <context-group name="null">
729 <context context-type="linenumber">47</context> 749 <context context-type="linenumber">45</context>
730 </context-group> 750 </context-group>
731 </trans-unit> 751 </trans-unit>
732 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 752 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
733 <source>Overview</source> 753 <source>Overview</source>
734 <target>Ãœbersicht</target> 754 <target>Ãœbersicht</target>
735 <context-group name="null"> 755 <context-group name="null">
736 <context context-type="linenumber">52</context> 756 <context context-type="linenumber">50</context>
737 </context-group> 757 </context-group>
738 </trans-unit> 758 </trans-unit>
739 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 759 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
740 <source>Trending</source> 760 <source>Trending</source>
741 <target>Beliebt</target> 761 <target>Beliebt</target>
742 <context-group name="null"> 762 <context-group name="null">
743 <context context-type="linenumber">57</context> 763 <context context-type="linenumber">55</context>
744 </context-group> 764 </context-group>
745 </trans-unit> 765 </trans-unit>
746 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 766 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
747 <source>Recently added</source> 767 <source>Recently added</source>
748 <target>Kürzlich hinzugefügt</target> 768 <target>Kürzlich hinzugefügt</target>
749 <context-group name="null"> 769 <context-group name="null">
750 <context context-type="linenumber">62</context> 770 <context context-type="linenumber">60</context>
751 </context-group> 771 </context-group>
752 </trans-unit> 772 </trans-unit>
753 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 773 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
754 <source>Local</source> 774 <source>Local</source>
755 <target>Lokal</target> 775 <target>Lokal</target>
756 <context-group name="null"> 776 <context-group name="null">
757 <context context-type="linenumber">67</context> 777 <context context-type="linenumber">65</context>
758 </context-group> 778 </context-group>
759 </trans-unit> 779 </trans-unit>
760 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 780 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
761 <source>More</source> 781 <source>More</source>
762 <target>Mehr</target> 782 <target>Mehr</target>
763 <context-group name="null"> 783 <context-group name="null">
764 <context context-type="linenumber">72</context> 784 <context context-type="linenumber">70</context>
765 </context-group> 785 </context-group>
766 </trans-unit> 786 </trans-unit>
767 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 787 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
768 <source>Administration</source> 788 <source>Administration</source>
769 <target>Administration</target> 789 <target>Administration</target>
770 <context-group name="null"> 790 <context-group name="null">
771 <context context-type="linenumber">76</context> 791 <context context-type="linenumber">74</context>
772 </context-group> 792 </context-group>
773 </trans-unit> 793 </trans-unit>
774 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 794 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -782,14 +802,14 @@ Konto erstellen</target>
782 <source>Show keyboard shortcuts</source> 802 <source>Show keyboard shortcuts</source>
783 <target>Zeige Tastatur-Kürzel</target> 803 <target>Zeige Tastatur-Kürzel</target>
784 <context-group name="null"> 804 <context-group name="null">
785 <context context-type="linenumber">91</context> 805 <context context-type="linenumber">89</context>
786 </context-group> 806 </context-group>
787 </trans-unit> 807 </trans-unit>
788 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 808 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
789 <source>Toggle dark interface</source> 809 <source>Toggle dark interface</source>
790 <target>Dunkle Oberfläche umschalten</target> 810 <target>Dunkle Oberfläche umschalten</target>
791 <context-group name="null"> 811 <context-group name="null">
792 <context context-type="linenumber">94</context> 812 <context context-type="linenumber">92</context>
793 </context-group> 813 </context-group>
794 </trans-unit> 814 </trans-unit>
795 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 815 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -894,14 +914,14 @@ Konto erstellen</target>
894 <source>Display unlisted and private videos</source> 914 <source>Display unlisted and private videos</source>
895 <target>Private und nicht gelisteten Videos aufzeigen</target> 915 <target>Private und nicht gelisteten Videos aufzeigen</target>
896 <context-group name="null"> 916 <context-group name="null">
897 <context context-type="linenumber">11</context> 917 <context context-type="linenumber">14</context>
898 </context-group> 918 </context-group>
899 </trans-unit> 919 </trans-unit>
900 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 920 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
901 <source>No results.</source> 921 <source>No results.</source>
902 <target>Keine Ergebnisse.</target> 922 <target>Keine Ergebnisse.</target>
903 <context-group name="null"> 923 <context-group name="null">
904 <context context-type="linenumber">17</context> 924 <context context-type="linenumber">20</context>
905 </context-group> 925 </context-group>
906 </trans-unit> 926 </trans-unit>
907 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 927 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -959,15 +979,22 @@ Konto erstellen</target>
959 <context context-type="linenumber">7</context> 979 <context context-type="linenumber">7</context>
960 </context-group> 980 </context-group>
961 </trans-unit> 981 </trans-unit>
962 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 982 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
963 <source> 983 <source>
964 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 984 Cancel
965</source> 985 </source>
966 <target> 986 <target>
967 Ãœber die Instanz <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> 987 Abbrechen
968</target> 988 </target>
969 <context-group name="null"> 989 <context-group name="null">
970 <context context-type="linenumber">1</context> 990 <context context-type="linenumber">26</context>
991 </context-group>
992 </trans-unit>
993 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
994 <source>Submit</source>
995 <target>Abschicken</target>
996 <context-group name="null">
997 <context context-type="linenumber">31</context>
971 </context-group> 998 </context-group>
972 </trans-unit> 999 </trans-unit>
973 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 1000 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -981,47 +1008,14 @@ Konto erstellen</target>
981 <source>Terms</source> 1008 <source>Terms</source>
982 <target>Bestimmungen</target> 1009 <target>Bestimmungen</target>
983 <context-group name="null"> 1010 <context-group name="null">
984 <context context-type="linenumber">44</context> 1011 <context context-type="linenumber">39</context>
985 </context-group> 1012 </context-group>
986 </trans-unit> 1013 </trans-unit>
987 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 1014 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
988 <source>User registration is allowed and</source> 1015 <source>User registration is allowed and</source>
989 <target>Benutzerregistrierung ist möglich und</target> 1016 <target>Benutzerregistrierung ist möglich und</target>
990 <context-group name="null"> 1017 <context-group name="null">
991 <context context-type="linenumber">25</context> 1018 <context context-type="linenumber">29</context>
992 </context-group>
993 </trans-unit>
994 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
995 <source>
996 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
997 </source>
998 <target>
999 für die Videos ihrer Nutzer stellt diese Instanz einen Speicherplatz von <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> zur Verfügung.
1000 </target>
1001 <context-group name="null">
1002 <context context-type="linenumber">27</context>
1003 </context-group>
1004 </trans-unit>
1005 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
1006 <source>
1007 this instance provides unlimited space for the videos of its users.
1008 </source>
1009 <target>
1010 für die Videos ihrer Nutzer stellt diese Instanz unbegrenzten Speicherplatz zur Verfügung.
1011 </target>
1012 <context-group name="null">
1013 <context context-type="linenumber">31</context>
1014 </context-group>
1015 </trans-unit>
1016 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
1017 <source>
1018 User registration is currently not allowed.
1019 </source>
1020 <target>
1021 Die Benutzerregistrierung ist zur Zeit nicht erlaubt.
1022 </target>
1023 <context-group name="null">
1024 <context context-type="linenumber">36</context>
1025 </context-group> 1019 </context-group>
1026 </trans-unit> 1020 </trans-unit>
1027 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 1021 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1037,7 +1031,7 @@ Konto erstellen</target>
1037 </trans-unit> 1031 </trans-unit>
1038 <trans-unit id="bd29138e1e17572596ce8f2fe61bcea6ac5fb0bf"> 1032 <trans-unit id="bd29138e1e17572596ce8f2fe61bcea6ac5fb0bf">
1039 <source>PeerTube is a federated (ActivityPub) video streaming platform using P2P (WebTorrent) directly in the web browser.</source> 1033 <source>PeerTube is a federated (ActivityPub) video streaming platform using P2P (WebTorrent) directly in the web browser.</source>
1040 <target>PeerTube ist eine föderierte Videostreamingplattform basierend auf dem ActivityPub-Protokoll, die mit WebTorrent P2P-Technologie direkt im Browser verwendet.</target> 1034 <target>PeerTube ist eine föderierte Videostreamingplattform basierend auf dem ActivityPub-Protokoll, die WebTorrent P2P-Technologie direkt im Browser verwendet.</target>
1041 <context-group name="null"> 1035 <context-group name="null">
1042 <context context-type="linenumber">6</context> 1036 <context context-type="linenumber">6</context>
1043 </context-group> 1037 </context-group>
@@ -1242,6 +1236,19 @@ Konto erstellen</target>
1242 <context context-type="linenumber">83</context> 1236 <context context-type="linenumber">83</context>
1243 </context-group> 1237 </context-group>
1244 </trans-unit> 1238 </trans-unit>
1239 <trans-unit id="b1372cb61ca791a0f7f95bf31c86c97df142adc4">
1240 <source>
1241 PeerTube is in its early stages, and want to deliver the best countermeasures possible by the time the stable is released.
1242 In the meantime, we want to test different ideas related to this issue:
1243 </source>
1244 <target>
1245 PeerTube ist in der frühen Entwicklungsphase und es ist geplant, die besten Gegenmaßnahmen in der nächsten stabilen Version zu implementieren.
1246 Bis dahin wollen wir verschiedene Ideen für dieses Problem testen:
1247 </target>
1248 <context-group name="null">
1249 <context context-type="linenumber">85</context>
1250 </context-group>
1251 </trans-unit>
1245 <trans-unit id="d32608aba08c6bb3cc4e4e8ec6223e5f4e78ca19"> 1252 <trans-unit id="d32608aba08c6bb3cc4e4e8ec6223e5f4e78ca19">
1246 <source>Set a limit to the number of peers sent by the tracker</source> 1253 <source>Set a limit to the number of peers sent by the tracker</source>
1247 <target>Die Zahl der Peers, die durch einen Tracker gesendet wird, begrenzen.</target> 1254 <target>Die Zahl der Peers, die durch einen Tracker gesendet wird, begrenzen.</target>
@@ -1278,27 +1285,37 @@ Konto erstellen</target>
1278 </context-group> 1285 </context-group>
1279 </trans-unit> 1286 </trans-unit>
1280 <trans-unit id="bd2edf99dd6562385ccec19a7ab2d1898e626605"> 1287 <trans-unit id="bd2edf99dd6562385ccec19a7ab2d1898e626605">
1281 <source>Banned</source><target>Banned</target><context-group name="null"> 1288 <source>Banned</source>
1289 <target>Gebannt</target>
1290 <context-group name="null">
1282 <context context-type="linenumber">12</context> 1291 <context context-type="linenumber">12</context>
1283 </context-group> 1292 </context-group>
1284 </trans-unit> 1293 </trans-unit>
1285 <trans-unit id="62a557fcfdbd25a31d1a0332294f94a466fee809"> 1294 <trans-unit id="62a557fcfdbd25a31d1a0332294f94a466fee809">
1286 <source>Muted</source><target>Muted</target><context-group name="null"> 1295 <source>Muted</source>
1296 <target>Stummgeschaltet</target>
1297 <context-group name="null">
1287 <context context-type="linenumber">13</context> 1298 <context context-type="linenumber">13</context>
1288 </context-group> 1299 </context-group>
1289 </trans-unit> 1300 </trans-unit>
1290 <trans-unit id="48bbf6dbdb22e0ef4bd257eae2ab356f2ea66c89"> 1301 <trans-unit id="48bbf6dbdb22e0ef4bd257eae2ab356f2ea66c89">
1291 <source>Muted by your instance</source><target>Muted by your instance</target><context-group name="null"> 1302 <source>Muted by your instance</source>
1303 <target>Von deiner Instanz stummgeschaltet</target>
1304 <context-group name="null">
1292 <context context-type="linenumber">14</context> 1305 <context context-type="linenumber">14</context>
1293 </context-group> 1306 </context-group>
1294 </trans-unit> 1307 </trans-unit>
1295 <trans-unit id="44bd08a7ec1e407356620967d65d8fe2d8639d0a"> 1308 <trans-unit id="44bd08a7ec1e407356620967d65d8fe2d8639d0a">
1296 <source>Instance muted</source><target>Instance muted</target><context-group name="null"> 1309 <source>Instance muted</source>
1310 <target>Instanz stummgeschaltet</target>
1311 <context-group name="null">
1297 <context context-type="linenumber">15</context> 1312 <context context-type="linenumber">15</context>
1298 </context-group> 1313 </context-group>
1299 </trans-unit> 1314 </trans-unit>
1300 <trans-unit id="1a6443bb7ed01046dd83cf78806f795f1204ffa1"> 1315 <trans-unit id="1a6443bb7ed01046dd83cf78806f795f1204ffa1">
1301 <source>Instance muted by your instance</source><target>Instance muted by your instance</target><context-group name="null"> 1316 <source>Instance muted by your instance</source>
1317 <target>Diese Instanz wurde deiner Instanz stummgeschaltet</target>
1318 <context-group name="null">
1302 <context context-type="linenumber">16</context> 1319 <context context-type="linenumber">16</context>
1303 </context-group> 1320 </context-group>
1304 </trans-unit> 1321 </trans-unit>
@@ -1355,49 +1372,49 @@ Konto erstellen</target>
1355 <source>Short description</source> 1372 <source>Short description</source>
1356 <target>Kurze Beschreibung</target> 1373 <target>Kurze Beschreibung</target>
1357 <context-group name="null"> 1374 <context-group name="null">
1358 <context context-type="linenumber">22</context> 1375 <context context-type="linenumber">21</context>
1359 </context-group> 1376 </context-group>
1360 </trans-unit> 1377 </trans-unit>
1361 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1378 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1362 <source>Default client route</source> 1379 <source>Default client route</source>
1363 <target>Standardpfad (Client)</target> 1380 <target>Standardpfad (Client)</target>
1364 <context-group name="null"> 1381 <context-group name="null">
1365 <context context-type="linenumber">55</context> 1382 <context context-type="linenumber">48</context>
1366 </context-group> 1383 </context-group>
1367 </trans-unit> 1384 </trans-unit>
1368 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1385 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1369 <source>Videos Overview</source> 1386 <source>Videos Overview</source>
1370 <target>Video-Ãœbersicht</target> 1387 <target>Video-Ãœbersicht</target>
1371 <context-group name="null"> 1388 <context-group name="null">
1372 <context context-type="linenumber">58</context> 1389 <context context-type="linenumber">51</context>
1373 </context-group> 1390 </context-group>
1374 </trans-unit> 1391 </trans-unit>
1375 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1392 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1376 <source>Videos Trending</source> 1393 <source>Videos Trending</source>
1377 <target>Beliebte Videos</target> 1394 <target>Beliebte Videos</target>
1378 <context-group name="null"> 1395 <context-group name="null">
1379 <context context-type="linenumber">59</context> 1396 <context context-type="linenumber">52</context>
1380 </context-group> 1397 </context-group>
1381 </trans-unit> 1398 </trans-unit>
1382 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1399 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1383 <source>Videos Recently Added</source> 1400 <source>Videos Recently Added</source>
1384 <target>Kürzlich hinzugefügte Videos</target> 1401 <target>Kürzlich hinzugefügte Videos</target>
1385 <context-group name="null"> 1402 <context-group name="null">
1386 <context context-type="linenumber">60</context> 1403 <context context-type="linenumber">53</context>
1387 </context-group> 1404 </context-group>
1388 </trans-unit> 1405 </trans-unit>
1389 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1406 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1390 <source>Local videos</source> 1407 <source>Local videos</source>
1391 <target>Lokale Videos</target> 1408 <target>Lokale Videos</target>
1392 <context-group name="null"> 1409 <context-group name="null">
1393 <context context-type="linenumber">61</context> 1410 <context context-type="linenumber">54</context>
1394 </context-group> 1411 </context-group>
1395 </trans-unit> 1412 </trans-unit>
1396 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1413 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1397 <source>Policy on videos containing sensitive content</source> 1414 <source>Policy on videos containing sensitive content</source>
1398 <target>Verhalten bei Videos mit anstößigen Inhalten</target> 1415 <target>Verhalten bei Videos mit anstößigen Inhalten</target>
1399 <context-group name="null"> 1416 <context-group name="null">
1400 <context context-type="linenumber">70</context> 1417 <context context-type="linenumber">61</context>
1401 </context-group> 1418 </context-group>
1402 </trans-unit> 1419 </trans-unit>
1403 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1420 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1432,23 +1449,44 @@ Konto erstellen</target>
1432 <source>Signup enabled</source> 1449 <source>Signup enabled</source>
1433 <target>Registrierung aktiviert</target> 1450 <target>Registrierung aktiviert</target>
1434 <context-group name="null"> 1451 <context-group name="null">
1435 <context context-type="linenumber">93</context> 1452 <context context-type="linenumber">84</context>
1436 </context-group> 1453 </context-group>
1437 </trans-unit> 1454 </trans-unit>
1438 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1455 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1439 <source>Signup requires email verification</source> 1456 <source>Signup requires email verification</source>
1440 <target>Registrierung erfordert eine Bestätigung der E-Mail-Adresse</target> 1457 <target>Registrierung erfordert eine Bestätigung der E-Mail-Adresse</target>
1441 <context-group name="null"> 1458 <context-group name="null">
1442 <context context-type="linenumber">100</context> 1459 <context context-type="linenumber">91</context>
1443 </context-group> 1460 </context-group>
1444 </trans-unit> 1461 </trans-unit>
1445 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1462 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1446 <source>Signup limit</source> 1463 <source>Signup limit</source>
1447 <target>Obergrenze für Registrierungen</target> 1464 <target>Obergrenze für Registrierungen</target>
1448 <context-group name="null"> 1465 <context-group name="null">
1466 <context context-type="linenumber">96</context>
1467 </context-group>
1468 </trans-unit>
1469 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1470 <source>Users</source>
1471 <target>Benutzer</target>
1472 <context-group name="null">
1449 <context context-type="linenumber">105</context> 1473 <context context-type="linenumber">105</context>
1450 </context-group> 1474 </context-group>
1451 </trans-unit> 1475 </trans-unit>
1476 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1477 <source>User default video quota</source>
1478 <target>Standardkontingent für die Videos eines Nutzers</target>
1479 <context-group name="null">
1480 <context context-type="linenumber">109</context>
1481 </context-group>
1482 </trans-unit>
1483 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1484 <source>User default daily upload limit</source>
1485 <target>Tägliches Obergrenze eines Nutzers beim Hochladen</target>
1486 <context-group name="null">
1487 <context context-type="linenumber">121</context>
1488 </context-group>
1489 </trans-unit>
1452 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1490 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1453 <source>Import</source> 1491 <source>Import</source>
1454 <target>Importieren</target> 1492 <target>Importieren</target>
@@ -1460,49 +1498,28 @@ Konto erstellen</target>
1460 <source>Video import with HTTP URL (i.e. YouTube) enabled</source> 1498 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1461 <target>Video durch HTTP URL (z.b. YouTube©) import erlaubt.</target> 1499 <target>Video durch HTTP URL (z.b. YouTube©) import erlaubt.</target>
1462 <context-group name="null"> 1500 <context-group name="null">
1463 <context context-type="linenumber">120</context> 1501 <context context-type="linenumber">141</context>
1464 </context-group> 1502 </context-group>
1465 </trans-unit> 1503 </trans-unit>
1466 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e"> 1504 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e">
1467 <source>Video import with a torrent file or a magnet URI enabled</source> 1505 <source>Video import with a torrent file or a magnet URI enabled</source>
1468 <target>Video-Import über eine Torrent-Datei oder einen Magnet-Link aktiviert</target> 1506 <target>Video-Import über eine Torrent-Datei oder einen Magnet-Link aktiviert</target>
1469 <context-group name="null"> 1507 <context-group name="null">
1470 <context context-type="linenumber">127</context> 1508 <context context-type="linenumber">148</context>
1471 </context-group> 1509 </context-group>
1472 </trans-unit> 1510 </trans-unit>
1473 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1511 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1474 <source>Administrator</source> 1512 <source>Administrator</source>
1475 <target>Administrator</target> 1513 <target>Administrator</target>
1476 <context-group name="null"> 1514 <context-group name="null">
1477 <context context-type="linenumber">131</context> 1515 <context context-type="linenumber">155</context>
1478 </context-group> 1516 </context-group>
1479 </trans-unit> 1517 </trans-unit>
1480 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1518 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1481 <source>Admin email</source> 1519 <source>Admin email</source>
1482 <target>Admin E-Mail</target> 1520 <target>Admin E-Mail</target>
1483 <context-group name="null"> 1521 <context-group name="null">
1484 <context context-type="linenumber">134</context> 1522 <context context-type="linenumber">158</context>
1485 </context-group>
1486 </trans-unit>
1487 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1488 <source>Users</source>
1489 <target>Benutzer</target>
1490 <context-group name="null">
1491 <context context-type="linenumber">144</context>
1492 </context-group>
1493 </trans-unit>
1494 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1495 <source>User default video quota</source>
1496 <target>Standardkontingent für die Videos eines Nutzers</target>
1497 <context-group name="null">
1498 <context context-type="linenumber">147</context>
1499 </context-group>
1500 </trans-unit>
1501 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1502 <source>User default daily upload limit</source>
1503 <target>Tägliches Obergrenze eines Nutzers beim Hochladen</target>
1504 <context-group name="null">
1505 <context context-type="linenumber">161</context>
1506 </context-group> 1523 </context-group>
1507 </trans-unit> 1524 </trans-unit>
1508 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1525 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1523,21 +1540,21 @@ Konto erstellen</target>
1523 <source>Your Twitter username</source> 1540 <source>Your Twitter username</source>
1524 <target>Dein Twitter-Benutzername</target> 1541 <target>Dein Twitter-Benutzername</target>
1525 <context-group name="null"> 1542 <context-group name="null">
1526 <context context-type="linenumber">181</context> 1543 <context context-type="linenumber">184</context>
1527 </context-group> 1544 </context-group>
1528 </trans-unit> 1545 </trans-unit>
1529 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1546 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1530 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1547 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1531 <target>Zeigt den Twitter-Account für die Webseite, auf der der Inhalt veröffentlicht wurde.</target> 1548 <target>Zeigt den Twitter-Account für die Webseite, auf der der Inhalt veröffentlicht wurde.</target>
1532 <context-group name="null"> 1549 <context-group name="null">
1533 <context context-type="linenumber">184</context> 1550 <context context-type="linenumber">187</context>
1534 </context-group> 1551 </context-group>
1535 </trans-unit> 1552 </trans-unit>
1536 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1553 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1537 <source>Instance whitelisted by Twitter</source> 1554 <source>Instance whitelisted by Twitter</source>
1538 <target>Instanz von Twitter vertraut</target> 1555 <target>Instanz von Twitter vertraut</target>
1539 <context-group name="null"> 1556 <context-group name="null">
1540 <context context-type="linenumber">198</context> 1557 <context context-type="linenumber">199</context>
1541 </context-group> 1558 </context-group>
1542 </trans-unit> 1559 </trans-unit>
1543 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1560 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1551,35 +1568,35 @@ Konto erstellen</target>
1551 <source>Transcoding</source> 1568 <source>Transcoding</source>
1552 <target>Transkodierung</target> 1569 <target>Transkodierung</target>
1553 <context-group name="null"> 1570 <context-group name="null">
1554 <context context-type="linenumber">210</context> 1571 <context context-type="linenumber">215</context>
1555 </context-group> 1572 </context-group>
1556 </trans-unit> 1573 </trans-unit>
1557 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1574 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1558 <source>Transcoding enabled</source> 1575 <source>Transcoding enabled</source>
1559 <target>Transkodierung an</target> 1576 <target>Transkodierung an</target>
1560 <context-group name="null"> 1577 <context-group name="null">
1561 <context context-type="linenumber">215</context> 1578 <context context-type="linenumber">221</context>
1562 </context-group> 1579 </context-group>
1563 </trans-unit> 1580 </trans-unit>
1564 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1581 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1565 <source>If you disable transcoding, many videos from your users will not work!</source> 1582 <source>If you disable transcoding, many videos from your users will not work!</source>
1566 <target>Wenn du die Transkodierung abschaltest, werden viele Videos nicht laufen!</target> 1583 <target>Wenn du die Transkodierung abschaltest, werden viele Videos nicht laufen!</target>
1567 <context-group name="null"> 1584 <context-group name="null">
1568 <context context-type="linenumber">216</context> 1585 <context context-type="linenumber">222</context>
1569 </context-group> 1586 </context-group>
1570 </trans-unit> 1587 </trans-unit>
1571 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1588 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1572 <source>Transcoding threads</source> 1589 <source>Transcoding threads</source>
1573 <target>Transcodierungsthreads</target> 1590 <target>Transcodierungsthreads</target>
1574 <context-group name="null"> 1591 <context-group name="null">
1575 <context context-type="linenumber">223</context> 1592 <context context-type="linenumber">237</context>
1576 </context-group> 1593 </context-group>
1577 </trans-unit> 1594 </trans-unit>
1578 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1595 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1579 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1596 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1580 <target>Eingestellte Auflösung: <x id="INTERPOLATION" equiv-text="{{resolution}}"/></target> 1597 <target>Eingestellte Auflösung: <x id="INTERPOLATION" equiv-text="{{resolution}}"/></target>
1581 <context-group name="null"> 1598 <context-group name="null">
1582 <context context-type="linenumber">239</context> 1599 <context context-type="linenumber">252</context>
1583 </context-group> 1600 </context-group>
1584 </trans-unit> 1601 </trans-unit>
1585 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1602 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1594,83 +1611,48 @@ Konto erstellen</target>
1594 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1611 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1595 </target> 1612 </target>
1596 <context-group name="null"> 1613 <context-group name="null">
1597 <context context-type="linenumber">244</context> 1614 <context context-type="linenumber">260</context>
1598 </context-group> 1615 </context-group>
1599 </trans-unit> 1616 </trans-unit>
1600 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1617 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1601 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1618 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1602 <target>Einige Dateien (Vorschau, Untertitel) werden nicht verteilt gespeichert. Wir laden sie direkt von der Ursprungsinstanz und speichern sie zwischen.</target> 1619 <target>Einige Dateien (Vorschau, Untertitel) werden nicht verteilt gespeichert. Wir laden sie direkt von der Ursprungsinstanz und speichern sie zwischen.</target>
1603 <context-group name="null"> 1620 <context-group name="null">
1604 <context context-type="linenumber">249</context> 1621 <context context-type="linenumber">265</context>
1605 </context-group> 1622 </context-group>
1606 </trans-unit> 1623 </trans-unit>
1607 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1624 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1608 <source>Previews cache size</source> 1625 <source>Previews cache size</source>
1609 <target>Cachegröße der Vorschau</target> 1626 <target>Cachegröße der Vorschau</target>
1610 <context-group name="null"> 1627 <context-group name="null">
1611 <context context-type="linenumber">254</context> 1628 <context context-type="linenumber">271</context>
1612 </context-group> 1629 </context-group>
1613 </trans-unit> 1630 </trans-unit>
1614 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1631 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1615 <source>Video captions cache size</source> 1632 <source>Video captions cache size</source>
1616 <target>Cachegröße der Untertitel</target> 1633 <target>Cachegröße der Untertitel</target>
1617 <context-group name="null"> 1634 <context-group name="null">
1618 <context context-type="linenumber">265</context> 1635 <context context-type="linenumber">280</context>
1619 </context-group> 1636 </context-group>
1620 </trans-unit> 1637 </trans-unit>
1621 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1638 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1622 <source>Customizations</source> 1639 <source>Customizations</source>
1623 <target>Personalisierung</target> 1640 <target>Personalisierung</target>
1624 <context-group name="null"> 1641 <context-group name="null">
1625 <context context-type="linenumber">275</context> 1642 <context context-type="linenumber">289</context>
1626 </context-group> 1643 </context-group>
1627 </trans-unit> 1644 </trans-unit>
1628 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1645 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1629 <source>JavaScript</source> 1646 <source>JavaScript</source>
1630 <target>JavaScript</target> 1647 <target>JavaScript</target>
1631 <context-group name="null"> 1648 <context-group name="null">
1632 <context context-type="linenumber">278</context> 1649 <context context-type="linenumber">294</context>
1633 </context-group> 1650 </context-group>
1634 </trans-unit> 1651 </trans-unit>
1635 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1652 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1636 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1653 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1637 <target>Füge dein JavaScript ein.&lt;br /&gt;Beispiel: &lt;pre&gt;console.log('Meine Instanz ist großartig');&lt;/pre&gt;</target> 1654 <target>Füge dein JavaScript ein.&lt;br /&gt;Beispiel: &lt;pre&gt;console.log('Meine Instanz ist großartig');&lt;/pre&gt;</target>
1638 <context-group name="null"> 1655 <context-group name="null">
1639 <context context-type="linenumber">281</context>
1640 </context-group>
1641 </trans-unit>
1642 <trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5">
1643 <source>
1644 Write directly CSS code. Example:&lt;br /&gt;
1645 &lt;pre&gt;
1646 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1647 background-color: red;
1648 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1649 &lt;/pre&gt;
1650
1651 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1652 &lt;pre&gt;
1653 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1654 color: red;
1655 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1656 &lt;/pre&gt;
1657 </source>
1658 <target>
1659 Schreibe direkt CSS-Code. Beispiel:&lt;br /&gt;
1660 &lt;pre&gt;
1661 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1662 background-color: red;
1663 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1664 &lt;/pre&gt;
1665
1666 Stelle &lt;em&gt;#custom-css&lt;/em&gt; voran, um den Stil zu überschreiben. Beispiel:
1667 &lt;pre&gt;
1668 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1669 color: red;
1670 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1671 &lt;/pre&gt;
1672 </target>
1673 <context-group name="null">
1674 <context context-type="linenumber">297</context> 1656 <context context-type="linenumber">297</context>
1675 </context-group> 1657 </context-group>
1676 </trans-unit> 1658 </trans-unit>
@@ -1678,21 +1660,21 @@ Konto erstellen</target>
1678 <source>Advanced configuration</source> 1660 <source>Advanced configuration</source>
1679 <target>Erweiterte Einstellungen</target> 1661 <target>Erweiterte Einstellungen</target>
1680 <context-group name="null"> 1662 <context-group name="null">
1681 <context context-type="linenumber">207</context> 1663 <context context-type="linenumber">212</context>
1682 </context-group> 1664 </context-group>
1683 </trans-unit> 1665 </trans-unit>
1684 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1666 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1685 <source>Update configuration</source> 1667 <source>Update configuration</source>
1686 <target>Einstellungen aktualisieren</target> 1668 <target>Einstellungen aktualisieren</target>
1687 <context-group name="null"> 1669 <context-group name="null">
1688 <context context-type="linenumber">325</context> 1670 <context context-type="linenumber">340</context>
1689 </context-group> 1671 </context-group>
1690 </trans-unit> 1672 </trans-unit>
1691 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1673 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1692 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1674 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1693 <target>Die Einstellungen sind anscheinend ungültig. Bitte suche nach potentiellen Fehlern in den verschiedenen Reitern.</target> 1675 <target>Die Einstellungen sind anscheinend ungültig. Bitte suche nach potentiellen Fehlern in den verschiedenen Reitern.</target>
1694 <context-group name="null"> 1676 <context-group name="null">
1695 <context context-type="linenumber">326</context> 1677 <context context-type="linenumber">341</context>
1696 </context-group> 1678 </context-group>
1697 </trans-unit> 1679 </trans-unit>
1698 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1680 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1963,7 +1945,9 @@ Konto erstellen</target>
1963 </context-group> 1945 </context-group>
1964 </trans-unit> 1946 </trans-unit>
1965 <trans-unit id="adba7c8b43e42581460fbe5d08b5cb5ab60eba4b"> 1947 <trans-unit id="adba7c8b43e42581460fbe5d08b5cb5ab60eba4b">
1966 <source>(banned)</source><target>(banned)</target><context-group name="null"> 1948 <source>(banned)</source>
1949 <target>(gebannt)</target>
1950 <context-group name="null">
1967 <context context-type="linenumber">65</context> 1951 <context context-type="linenumber">65</context>
1968 </context-group> 1952 </context-group>
1969 </trans-unit> 1953 </trans-unit>
@@ -1974,11 +1958,25 @@ Konto erstellen</target>
1974 <context context-type="linenumber">133</context> 1958 <context context-type="linenumber">133</context>
1975 </context-group> 1959 </context-group>
1976 </trans-unit> 1960 </trans-unit>
1961 <trans-unit id="02ba1a65db92d1d0ab4ba380086e9be61891aaa5">
1962 <source>User's email must be verified to login</source>
1963 <target>Die E-Mail-Adresse des Nutzers muss vor dem Einloggen bestätigt werden</target>
1964 <context-group name="null">
1965 <context context-type="linenumber">72</context>
1966 </context-group>
1967 </trans-unit>
1968 <trans-unit id="79cee9973620b2592ff2824c525aa8ed0b5e2b8b">
1969 <source>User's email is verified / User can login without email verification</source>
1970 <target>Die E-Mail-Addresse des Nutzers wurde bestätigt / Nutzer kann ohne E-Mail-Bestätigung einloggen</target>
1971 <context-group name="null">
1972 <context context-type="linenumber">76</context>
1973 </context-group>
1974 </trans-unit>
1977 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee"> 1975 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee">
1978 <source>Ban reason:</source> 1976 <source>Ban reason:</source>
1979 <target>Grund für die Sperrung:</target> 1977 <target>Grund für die Sperrung:</target>
1980 <context-group name="null"> 1978 <context-group name="null">
1981 <context context-type="linenumber">92</context> 1979 <context context-type="linenumber">95</context>
1982 </context-group> 1980 </context-group>
1983 </trans-unit> 1981 </trans-unit>
1984 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 1982 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -2045,7 +2043,7 @@ Konto erstellen</target>
2045 <source>Actions</source> 2043 <source>Actions</source>
2046 <target>Aktionen</target> 2044 <target>Aktionen</target>
2047 <context-group name="null"> 2045 <context-group name="null">
2048 <context context-type="linenumber">33</context> 2046 <context context-type="linenumber">35</context>
2049 </context-group> 2047 </context-group>
2050 </trans-unit> 2048 </trans-unit>
2051 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 2049 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -2080,14 +2078,14 @@ Konto erstellen</target>
2080 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 2078 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2081 <target>Datum <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 2079 <target>Datum <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2082 <context-group name="null"> 2080 <context-group name="null">
2083 <context context-type="linenumber">10</context> 2081 <context context-type="linenumber">11</context>
2084 </context-group> 2082 </context-group>
2085 </trans-unit> 2083 </trans-unit>
2086 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f"> 2084 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
2087 <source>Blacklist reason:</source> 2085 <source>Blacklist reason:</source>
2088 <target>Grund für die Sperre:</target> 2086 <target>Grund für die Sperre:</target>
2089 <context-group name="null"> 2087 <context-group name="null">
2090 <context context-type="linenumber">41</context> 2088 <context context-type="linenumber">43</context>
2091 </context-group> 2089 </context-group>
2092 </trans-unit> 2090 </trans-unit>
2093 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 2091 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -2112,12 +2110,16 @@ Konto erstellen</target>
2112 </context-group> 2110 </context-group>
2113 </trans-unit> 2111 </trans-unit>
2114 <trans-unit id="b1ff109b26ae8f08650415454b9098c43eba2e2c"> 2112 <trans-unit id="b1ff109b26ae8f08650415454b9098c43eba2e2c">
2115 <source>Muted accounts</source><target>Muted accounts</target><context-group name="null"> 2113 <source>Muted accounts</source>
2114 <target>Stummgeschaltete Accounts</target>
2115 <context-group name="null">
2116 <context context-type="linenumber">2</context> 2116 <context context-type="linenumber">2</context>
2117 </context-group> 2117 </context-group>
2118 </trans-unit> 2118 </trans-unit>
2119 <trans-unit id="bd0611346af048015e0a1275091ef68ce98832d2"> 2119 <trans-unit id="bd0611346af048015e0a1275091ef68ce98832d2">
2120 <source>Muted servers</source><target>Muted servers</target><context-group name="null"> 2120 <source>Muted servers</source>
2121 <target>Stummgeschaltete Server</target>
2122 <context-group name="null">
2121 <context context-type="linenumber">11</context> 2123 <context context-type="linenumber">11</context>
2122 </context-group> 2124 </context-group>
2123 </trans-unit> 2125 </trans-unit>
@@ -2129,67 +2131,17 @@ Konto erstellen</target>
2129 </context-group> 2131 </context-group>
2130 </trans-unit> 2132 </trans-unit>
2131 <trans-unit id="079e99cce11c87b142e80fdd14dae98a61012fc4"> 2133 <trans-unit id="079e99cce11c87b142e80fdd14dae98a61012fc4">
2132 <source>Muted at <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source><target>Muted at <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target><context-group name="null"> 2134 <source>Muted at <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2135 <target>Stummgeschaltet am <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2136 <context-group name="null">
2133 <context context-type="linenumber">13</context> 2137 <context context-type="linenumber">13</context>
2134 </context-group> 2138 </context-group>
2135 </trans-unit> 2139 </trans-unit>
2136 <trans-unit id="1f689fada9748a830117f5b429a88ef8629082a8"> 2140 <trans-unit id="1f689fada9748a830117f5b429a88ef8629082a8">
2137 <source>Unmute</source><target>Unmute</target><context-group name="null"> 2141 <source>Unmute</source>
2138 <context context-type="linenumber">23</context> 2142 <target>Stummschalten aufheben</target>
2139 </context-group>
2140 </trans-unit>
2141 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2142 <source>My settings</source>
2143 <target>Meine Einstellungen</target>
2144 <context-group name="null">
2145 <context context-type="linenumber">3</context>
2146 </context-group>
2147 </trans-unit>
2148 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2149 <source>My library</source>
2150 <target>Meine Bibliothek</target>
2151 <context-group name="null">
2152 <context context-type="linenumber">7</context>
2153 </context-group>
2154 </trans-unit>
2155 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2156 <source>My channels</source>
2157 <target>Meine Kanäle</target>
2158 <context-group name="null">
2159 <context context-type="linenumber">12</context>
2160 </context-group>
2161 </trans-unit>
2162 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2163 <source>My videos</source>
2164 <target>Meine Videos</target>
2165 <context-group name="null">
2166 <context context-type="linenumber">14</context>
2167 </context-group>
2168 </trans-unit>
2169 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2170 <source>My subscriptions</source>
2171 <target>Meine Abos</target>
2172 <context-group name="null">
2173 <context context-type="linenumber">16</context>
2174 </context-group>
2175 </trans-unit>
2176 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
2177 <source>My imports</source>
2178 <target>Meine Importe</target>
2179 <context-group name="null"> 2143 <context-group name="null">
2180 <context context-type="linenumber">18</context> 2144 <context context-type="linenumber">23</context>
2181 </context-group>
2182 </trans-unit>
2183 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2184 <source>Muted instances</source><target>Muted instances</target><context-group name="null">
2185 <context context-type="linenumber">2</context>
2186 </context-group>
2187 </trans-unit>
2188 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
2189 <source>Ownership changes</source>
2190 <target>Besitzer ändern</target>
2191 <context-group name="null">
2192 <context context-type="linenumber">33</context>
2193 </context-group> 2145 </context-group>
2194 </trans-unit> 2146 </trans-unit>
2195 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 2147 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
@@ -2203,21 +2155,21 @@ Konto erstellen</target>
2203 <source>Profile</source> 2155 <source>Profile</source>
2204 <target>Profil</target> 2156 <target>Profil</target>
2205 <context-group name="null"> 2157 <context-group name="null">
2206 <context context-type="linenumber">8</context> 2158 <context context-type="linenumber">7</context>
2207 </context-group> 2159 </context-group>
2208 </trans-unit> 2160 </trans-unit>
2209 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 2161 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
2210 <source>Video settings</source> 2162 <source>Video settings</source>
2211 <target>Videoeinstellungen</target> 2163 <target>Videoeinstellungen</target>
2212 <context-group name="null"> 2164 <context-group name="null">
2213 <context context-type="linenumber">15</context> 2165 <context context-type="linenumber">16</context>
2214 </context-group> 2166 </context-group>
2215 </trans-unit> 2167 </trans-unit>
2216 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 2168 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
2217 <source>Danger zone</source> 2169 <source>Danger zone</source>
2218 <target>Gefahrenzone</target> 2170 <target>Gefahrenzone</target>
2219 <context-group name="null"> 2171 <context-group name="null">
2220 <context context-type="linenumber">18</context> 2172 <context context-type="linenumber">19</context>
2221 </context-group> 2173 </context-group>
2222 </trans-unit> 2174 </trans-unit>
2223 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 2175 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -2245,13 +2197,6 @@ Konto erstellen</target>
2245 <context context-type="linenumber">35</context> 2197 <context context-type="linenumber">35</context>
2246 </context-group> 2198 </context-group>
2247 </trans-unit> 2199 </trans-unit>
2248 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
2249 <source>Submit</source>
2250 <target>Abschicken</target>
2251 <context-group name="null">
2252 <context context-type="linenumber">24</context>
2253 </context-group>
2254 </trans-unit>
2255 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 2200 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
2256 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 2201 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2257 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> Aufrufe</target> 2202 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> Aufrufe</target>
@@ -2411,6 +2356,13 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
2411 <context context-type="linenumber">47</context> 2356 <context context-type="linenumber">47</context>
2412 </context-group> 2357 </context-group>
2413 </trans-unit> 2358 </trans-unit>
2359 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2360 <source>Muted instances</source>
2361 <target>Stummgeschaltete Instanzen</target>
2362 <context-group name="null">
2363 <context context-type="linenumber">2</context>
2364 </context-group>
2365 </trans-unit>
2414 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 2366 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
2415 <source>Change password</source> 2367 <source>Change password</source>
2416 <target>Passwort ändern</target> 2368 <target>Passwort ändern</target>
@@ -2616,6 +2568,13 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
2616 <context context-type="linenumber">159</context> 2568 <context context-type="linenumber">159</context>
2617 </context-group> 2569 </context-group>
2618 </trans-unit> 2570 </trans-unit>
2571 <trans-unit id="385811ab5a5c3e96e0db46c9ce1fc3147d8cd4c7">
2572 <source>Sorry, but something went wrong</source>
2573 <target>Entschuldigung, etwas ist schiefgegangen</target>
2574 <context-group name="null">
2575 <context context-type="linenumber">49</context>
2576 </context-group>
2577 </trans-unit>
2619 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2"> 2578 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2">
2620 <source> 2579 <source>
2621 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video. 2580 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video.
@@ -2652,14 +2611,14 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
2652 <source>Publish will be available when upload is finished</source> 2611 <source>Publish will be available when upload is finished</source>
2653 <target>Veröffentlichung ist möglich, sobald das Hochladen abgeschlossen ist</target> 2612 <target>Veröffentlichung ist möglich, sobald das Hochladen abgeschlossen ist</target>
2654 <context-group name="null"> 2613 <context-group name="null">
2655 <context context-type="linenumber">53</context> 2614 <context context-type="linenumber">58</context>
2656 </context-group> 2615 </context-group>
2657 </trans-unit> 2616 </trans-unit>
2658 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 2617 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2659 <source>Publish</source> 2618 <source>Publish</source>
2660 <target>Veröffentlichen</target> 2619 <target>Veröffentlichen</target>
2661 <context-group name="null"> 2620 <context-group name="null">
2662 <context context-type="linenumber">60</context> 2621 <context context-type="linenumber">65</context>
2663 </context-group> 2622 </context-group>
2664 </trans-unit> 2623 </trans-unit>
2665 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 2624 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -2842,14 +2801,14 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
2842 <source>Wait transcoding before publishing the video</source> 2801 <source>Wait transcoding before publishing the video</source>
2843 <target>Transkodieren abwarten, bevor das Video veröffentlicht wird</target> 2802 <target>Transkodieren abwarten, bevor das Video veröffentlicht wird</target>
2844 <context-group name="null"> 2803 <context-group name="null">
2845 <context context-type="linenumber">130</context> 2804 <context context-type="linenumber">131</context>
2846 </context-group> 2805 </context-group>
2847 </trans-unit> 2806 </trans-unit>
2848 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 2807 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2849 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 2808 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
2850 <target>Wenn du dich entschließt, das Transkodieren nicht abzuwarten, kann das Video unabspielbar sein, bis das Transkodieren beendet ist.</target> 2809 <target>Wenn du dich entschließt, das Transkodieren nicht abzuwarten, kann das Video unabspielbar sein, bis das Transkodieren beendet ist.</target>
2851 <context-group name="null"> 2810 <context-group name="null">
2852 <context context-type="linenumber">131</context> 2811 <context context-type="linenumber">132</context>
2853 </context-group> 2812 </context-group>
2854 </trans-unit> 2813 </trans-unit>
2855 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2814 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2863,49 +2822,49 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
2863 <source>Add another caption</source> 2822 <source>Add another caption</source>
2864 <target>Weitere Untertitel hinzufügen</target> 2823 <target>Weitere Untertitel hinzufügen</target>
2865 <context-group name="null"> 2824 <context-group name="null">
2866 <context context-type="linenumber">146</context> 2825 <context context-type="linenumber">147</context>
2867 </context-group> 2826 </context-group>
2868 </trans-unit> 2827 </trans-unit>
2869 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 2828 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2870 <source>See the subtitle file</source> 2829 <source>See the subtitle file</source>
2871 <target>Siehe in der Untertiteldatei</target> 2830 <target>Siehe in der Untertiteldatei</target>
2872 <context-group name="null"> 2831 <context-group name="null">
2873 <context context-type="linenumber">155</context> 2832 <context context-type="linenumber">156</context>
2874 </context-group> 2833 </context-group>
2875 </trans-unit> 2834 </trans-unit>
2876 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee"> 2835 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee">
2877 <source>Already uploaded ✔</source> 2836 <source>Already uploaded ✔</source>
2878 <target>Fast hochgeladen ✔</target> 2837 <target>Fast hochgeladen ✔</target>
2879 <context-group name="null"> 2838 <context-group name="null">
2880 <context context-type="linenumber">159</context> 2839 <context context-type="linenumber">160</context>
2881 </context-group> 2840 </context-group>
2882 </trans-unit> 2841 </trans-unit>
2883 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad"> 2842 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad">
2884 <source>Will be created on update</source> 2843 <source>Will be created on update</source>
2885 <target>Wird bei einer Aktualisierung erstellt</target> 2844 <target>Wird bei einer Aktualisierung erstellt</target>
2886 <context-group name="null"> 2845 <context-group name="null">
2887 <context context-type="linenumber">167</context> 2846 <context context-type="linenumber">168</context>
2888 </context-group> 2847 </context-group>
2889 </trans-unit> 2848 </trans-unit>
2890 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 2849 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2891 <source>Cancel create</source> 2850 <source>Cancel create</source>
2892 <target>Erstellen abbrechen</target> 2851 <target>Erstellen abbrechen</target>
2893 <context-group name="null"> 2852 <context-group name="null">
2894 <context context-type="linenumber">169</context> 2853 <context context-type="linenumber">170</context>
2895 </context-group> 2854 </context-group>
2896 </trans-unit> 2855 </trans-unit>
2897 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393"> 2856 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393">
2898 <source>Will be deleted on update</source> 2857 <source>Will be deleted on update</source>
2899 <target>Wird bei einer Aktualisierung gelöscht</target> 2858 <target>Wird bei einer Aktualisierung gelöscht</target>
2900 <context-group name="null"> 2859 <context-group name="null">
2901 <context context-type="linenumber">175</context> 2860 <context context-type="linenumber">176</context>
2902 </context-group> 2861 </context-group>
2903 </trans-unit> 2862 </trans-unit>
2904 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 2863 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2905 <source>Cancel deletion</source> 2864 <source>Cancel deletion</source>
2906 <target>Löschen abbrechen</target> 2865 <target>Löschen abbrechen</target>
2907 <context-group name="null"> 2866 <context-group name="null">
2908 <context context-type="linenumber">177</context> 2867 <context context-type="linenumber">178</context>
2909 </context-group> 2868 </context-group>
2910 </trans-unit> 2869 </trans-unit>
2911 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0"> 2870 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0">
@@ -2916,28 +2875,28 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
2916 Bis auf Weiteres keine Untertitel. 2875 Bis auf Weiteres keine Untertitel.
2917 </target> 2876 </target>
2918 <context-group name="null"> 2877 <context-group name="null">
2919 <context context-type="linenumber">182</context> 2878 <context context-type="linenumber">183</context>
2920 </context-group> 2879 </context-group>
2921 </trans-unit> 2880 </trans-unit>
2922 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 2881 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2923 <source>Captions</source> 2882 <source>Captions</source>
2924 <target>Untertitel</target> 2883 <target>Untertitel</target>
2925 <context-group name="null"> 2884 <context-group name="null">
2926 <context context-type="linenumber">139</context> 2885 <context context-type="linenumber">140</context>
2927 </context-group> 2886 </context-group>
2928 </trans-unit> 2887 </trans-unit>
2929 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 2888 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
2930 <source>Upload thumbnail</source> 2889 <source>Upload thumbnail</source>
2931 <target>Miniaturansicht hochladen</target> 2890 <target>Miniaturansicht hochladen</target>
2932 <context-group name="null"> 2891 <context-group name="null">
2933 <context context-type="linenumber">195</context> 2892 <context context-type="linenumber">196</context>
2934 </context-group> 2893 </context-group>
2935 </trans-unit> 2894 </trans-unit>
2936 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 2895 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
2937 <source>Upload preview</source> 2896 <source>Upload preview</source>
2938 <target>Vorschau hochladen</target> 2897 <target>Vorschau hochladen</target>
2939 <context-group name="null"> 2898 <context-group name="null">
2940 <context context-type="linenumber">202</context> 2899 <context context-type="linenumber">203</context>
2941 </context-group> 2900 </context-group>
2942 </trans-unit> 2901 </trans-unit>
2943 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 2902 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -2951,14 +2910,14 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
2951 <source>Short text to tell people how they can support you (membership platform...).</source> 2910 <source>Short text to tell people how they can support you (membership platform...).</source>
2952 <target>Ein kurzer Text, der anderen erklärt, wie sie dich unterstützen können.</target> 2911 <target>Ein kurzer Text, der anderen erklärt, wie sie dich unterstützen können.</target>
2953 <context-group name="null"> 2912 <context-group name="null">
2954 <context context-type="linenumber">209</context> 2913 <context context-type="linenumber">210</context>
2955 </context-group> 2914 </context-group>
2956 </trans-unit> 2915 </trans-unit>
2957 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 2916 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
2958 <source>Advanced settings</source> 2917 <source>Advanced settings</source>
2959 <target>Erweiterte Einstellungen</target> 2918 <target>Erweiterte Einstellungen</target>
2960 <context-group name="null"> 2919 <context-group name="null">
2961 <context context-type="linenumber">190</context> 2920 <context context-type="linenumber">191</context>
2962 </context-group> 2921 </context-group>
2963 </trans-unit> 2922 </trans-unit>
2964 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 2923 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -3025,17 +2984,6 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3025 <context context-type="linenumber">3</context> 2984 <context context-type="linenumber">3</context>
3026 </context-group> 2985 </context-group>
3027 </trans-unit> 2986 </trans-unit>
3028 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
3029 <source>
3030 Cancel
3031 </source>
3032 <target>
3033 Abbrechen
3034 </target>
3035 <context-group name="null">
3036 <context context-type="linenumber">19</context>
3037 </context-group>
3038 </trans-unit>
3039 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 2987 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
3040 <source>Share</source> 2988 <source>Share</source>
3041 <target>Teilen</target> 2989 <target>Teilen</target>
@@ -3422,13 +3370,6 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3422 <context context-type="linenumber">14</context> 3370 <context context-type="linenumber">14</context>
3423 </context-group> 3371 </context-group>
3424 </trans-unit> 3372 </trans-unit>
3425 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
3426 <source>Error getting about from server</source>
3427 <target>Server-Fehler.</target>
3428 <context-group name="null">
3429 <context context-type="linenumber">1</context>
3430 </context-group>
3431 </trans-unit>
3432 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 3373 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
3433 <source>No description</source> 3374 <source>No description</source>
3434 <target>Keine Beschreibung</target> 3375 <target>Keine Beschreibung</target>
@@ -3450,13 +3391,6 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3450 <context context-type="linenumber">1</context> 3391 <context context-type="linenumber">1</context>
3451 </context-group> 3392 </context-group>
3452 </trans-unit> 3393 </trans-unit>
3453 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
3454 <source>Error</source>
3455 <target>Fehler</target>
3456 <context-group name="null">
3457 <context context-type="linenumber">1</context>
3458 </context-group>
3459 </trans-unit>
3460 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6"> 3394 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
3461 <source>240p</source> 3395 <source>240p</source>
3462 <target>240p</target> 3396 <target>240p</target>
@@ -3499,13 +3433,6 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3499 <context context-type="linenumber">1</context> 3433 <context context-type="linenumber">1</context>
3500 </context-group> 3434 </context-group>
3501 </trans-unit> 3435 </trans-unit>
3502 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
3503 <source>Success</source>
3504 <target>Erfolg</target>
3505 <context-group name="null">
3506 <context context-type="linenumber">1</context>
3507 </context-group>
3508 </trans-unit>
3509 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 3436 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
3510 <source>Configuration updated.</source> 3437 <source>Configuration updated.</source>
3511 <target>Einstellungen aktualisiert.</target> 3438 <target>Einstellungen aktualisiert.</target>
@@ -3668,7 +3595,16 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3668 </context-group> 3595 </context-group>
3669 </trans-unit> 3596 </trans-unit>
3670 <trans-unit id="53cc0f4a4566c4139c65f93b5dce2fe8302e78da"> 3597 <trans-unit id="53cc0f4a4566c4139c65f93b5dce2fe8302e78da">
3671 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by your instance.</source><target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by your instance.</target><context-group name="null"> 3598 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by your instance.</source>
3599 <target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> ist von deiner Instanz nicht mehr stummgeschatet.</target>
3600 <context-group name="null">
3601 <context context-type="linenumber">1</context>
3602 </context-group>
3603 </trans-unit>
3604 <trans-unit id="468b52e3c04fb9a3d8c8213555dfcad0cbcae330">
3605 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by your instance.</source>
3606 <target>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> ist von deiner Instanz nicht mehr stummgeschaltet.</target>
3607 <context-group name="null">
3672 <context context-type="linenumber">1</context> 3608 <context context-type="linenumber">1</context>
3673 </context-group> 3609 </context-group>
3674 </trans-unit> 3610 </trans-unit>
@@ -3679,6 +3615,13 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3679 <context context-type="linenumber">1</context> 3615 <context context-type="linenumber">1</context>
3680 </context-group> 3616 </context-group>
3681 </trans-unit> 3617 </trans-unit>
3618 <trans-unit id="586bee8c27a761611eb05661524cc7ca944b5978">
3619 <source>Delete this report</source>
3620 <target>Missbrauchsmeldung löschen</target>
3621 <context-group name="null">
3622 <context context-type="linenumber">1</context>
3623 </context-group>
3624 </trans-unit>
3682 <trans-unit id="cf3b28ba29a907b334ab0e6dccd080a60ba23321"> 3625 <trans-unit id="cf3b28ba29a907b334ab0e6dccd080a60ba23321">
3683 <source>Update moderation comment</source> 3626 <source>Update moderation comment</source>
3684 <target>Moderationskommentar aktualisieren</target> 3627 <target>Moderationskommentar aktualisieren</target>
@@ -3700,6 +3643,13 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3700 <context context-type="linenumber">1</context> 3643 <context context-type="linenumber">1</context>
3701 </context-group> 3644 </context-group>
3702 </trans-unit> 3645 </trans-unit>
3646 <trans-unit id="73b70e37cddaa6494d8a666b6cba90dc80595599">
3647 <source>Do you really want to delete this abuse report?</source>
3648 <target>Wollen Sie wirklich diese Missbrauchsmeldung löschen?</target>
3649 <context-group name="null">
3650 <context context-type="linenumber">1</context>
3651 </context-group>
3652 </trans-unit>
3703 <trans-unit id="6a7938b8780c27540ea70cc0f8f4d928c8916cf9"> 3653 <trans-unit id="6a7938b8780c27540ea70cc0f8f4d928c8916cf9">
3704 <source>Abuse deleted.</source> 3654 <source>Abuse deleted.</source>
3705 <target>Missbrauchsmeldung gelöscht.</target> 3655 <target>Missbrauchsmeldung gelöscht.</target>
@@ -3749,6 +3699,13 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3749 <context context-type="linenumber">1</context> 3699 <context context-type="linenumber">1</context>
3750 </context-group> 3700 </context-group>
3751 </trans-unit> 3701 </trans-unit>
3702 <trans-unit id="910ed85f550272401b134a40d019ab3359fe883f">
3703 <source>Set Email as Verified</source>
3704 <target>E-Mail als bestätigt setzen</target>
3705 <context-group name="null">
3706 <context context-type="linenumber">1</context>
3707 </context-group>
3708 </trans-unit>
3752 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf"> 3709 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf">
3753 <source>You cannot ban root.</source> 3710 <source>You cannot ban root.</source>
3754 <target>Du kannst root nicht sperren.</target> 3711 <target>Du kannst root nicht sperren.</target>
@@ -3756,6 +3713,20 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3756 <context context-type="linenumber">1</context> 3713 <context context-type="linenumber">1</context>
3757 </context-group> 3714 </context-group>
3758 </trans-unit> 3715 </trans-unit>
3716 <trans-unit id="98119091712a8ca72905e3b4c1cf60649af7565e">
3717 <source>Do you really want to unban <x id="INTERPOLATION" equiv-text="{{num}}"/> users?</source>
3718 <target>Willst du wirklich den Bann von <x id="INTERPOLATION" equiv-text="{{num}}"/> Benutzern aufheben?</target>
3719 <context-group name="null">
3720 <context context-type="linenumber">1</context>
3721 </context-group>
3722 </trans-unit>
3723 <trans-unit id="6121be086a51c4c73bbdd8aebdddd9744c8f1ffd">
3724 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users unbanned.</source>
3725 <target>Bann von <x id="INTERPOLATION" equiv-text="{{num}}"/> Benutzern aufgehoben.</target>
3726 <context-group name="null">
3727 <context context-type="linenumber">1</context>
3728 </context-group>
3729 </trans-unit>
3759 <trans-unit id="911fc197949e47aa5f0541627bc319f59edd9d11"> 3730 <trans-unit id="911fc197949e47aa5f0541627bc319f59edd9d11">
3760 <source>You cannot delete root.</source> 3731 <source>You cannot delete root.</source>
3761 <target>Du kannst die Wurzel nicht löschen.</target> 3732 <target>Du kannst die Wurzel nicht löschen.</target>
@@ -3764,7 +3735,37 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3764 </context-group> 3735 </context-group>
3765 </trans-unit> 3736 </trans-unit>
3766 <trans-unit id="9de914fe915cc730efc57e81c987188a24d3ac51"> 3737 <trans-unit id="9de914fe915cc730efc57e81c987188a24d3ac51">
3767 <source>If you remove these users, you will not be able to create others with the same username!</source><target>If you remove these users, you will not be able to create others with the same username!</target><context-group name="null"> 3738 <source>If you remove these users, you will not be able to create others with the same username!</source>
3739 <target>Wenn du diesen Benutzer löschst, kannst du keine neuen Benutzer mit gleichem Benutzernamen einrichten !</target>
3740 <context-group name="null">
3741 <context context-type="linenumber">1</context>
3742 </context-group>
3743 </trans-unit>
3744 <trans-unit id="b708d332e3f89b24745e749fa530210f0bdea329">
3745 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users deleted.</source>
3746 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> Benutzer gelöscht.</target>
3747 <context-group name="null">
3748 <context context-type="linenumber">1</context>
3749 </context-group>
3750 </trans-unit>
3751 <trans-unit id="f4a8f2ef1fbfc19e1e049e69f63c40063c0d0650">
3752 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users email set as verified.</source>
3753 <target>E-Mail von <x id="INTERPOLATION" equiv-text="{{num}}"/> Benutzern als bestätigt markiert.</target>
3754 <context-group name="null">
3755 <context context-type="linenumber">1</context>
3756 </context-group>
3757 </trans-unit>
3758 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de">
3759 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source>
3760 <target>Stummschaltung von Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> aufgehoben.</target>
3761 <context-group name="null">
3762 <context context-type="linenumber">1</context>
3763 </context-group>
3764 </trans-unit>
3765 <trans-unit id="c6af80b42938d4a49e6f6c4f60ce26228916994c">
3766 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted.</source>
3767 <target>Stummschaltung von Instanz <x id="INTERPOLATION" equiv-text="{{host}}"/> aufgehoben.</target>
3768 <context-group name="null">
3768 <context context-type="linenumber">1</context> 3769 <context context-type="linenumber">1</context>
3769 </context-group> 3770 </context-group>
3770 </trans-unit> 3771 </trans-unit>
@@ -3845,6 +3846,13 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3845 <context context-type="linenumber">1</context> 3846 <context context-type="linenumber">1</context>
3846 </context-group> 3847 </context-group>
3847 </trans-unit> 3848 </trans-unit>
3849 <trans-unit id="f359f6adf6cccca7770019f947ed594169ee7d47">
3850 <source>This name already exists on this instance.</source>
3851 <target>Dieser Name existiert bereits auf dieser Instanz.</target>
3852 <context-group name="null">
3853 <context context-type="linenumber">1</context>
3854 </context-group>
3855 </trans-unit>
3848 <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795"> 3856 <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795">
3849 <source>Create</source> 3857 <source>Create</source>
3850 <target>Erstellen</target> 3858 <target>Erstellen</target>
@@ -3859,23 +3867,16 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3859 <context context-type="linenumber">1</context> 3867 <context context-type="linenumber">1</context>
3860 </context-group> 3868 </context-group>
3861 </trans-unit> 3869 </trans-unit>
3862 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 3870 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
3863 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 3871 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
3864 <target>Willst du wirklich <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> löschen? Alle hochgeladenen Videos des Kanals werden dann ebenfalls unwiderruflich gelöscht.</target> 3872 <target>Videokanal <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> entfernt.</target>
3865 <context-group name="null">
3866 <context context-type="linenumber">1</context>
3867 </context-group>
3868 </trans-unit>
3869 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
3870 <source>Please type the name of the video channel to confirm</source>
3871 <target>Bitte gib zur Bestätigung den Namen des Videokanals ein</target>
3872 <context-group name="null"> 3873 <context-group name="null">
3873 <context context-type="linenumber">1</context> 3874 <context context-type="linenumber">1</context>
3874 </context-group> 3875 </context-group>
3875 </trans-unit> 3876 </trans-unit>
3876 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 3877 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
3877 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 3878 <source>My videos</source>
3878 <target>Videokanal <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> entfernt.</target> 3879 <target>Meine Videos</target>
3879 <context-group name="null"> 3880 <context-group name="null">
3880 <context context-type="linenumber">1</context> 3881 <context context-type="linenumber">1</context>
3881 </context-group> 3882 </context-group>
@@ -3950,16 +3951,44 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3950 <context context-type="linenumber">1</context> 3951 <context context-type="linenumber">1</context>
3951 </context-group> 3952 </context-group>
3952 </trans-unit> 3953 </trans-unit>
3953 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 3954 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
3954 <source>Channels</source> 3955 <source>My library</source>
3955 <target>Kanäle</target> 3956 <target>Meine Bibliothek</target>
3957 <context-group name="null">
3958 <context context-type="linenumber">1</context>
3959 </context-group>
3960 </trans-unit>
3961 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
3962 <source>My channels</source>
3963 <target>Meine Kanäle</target>
3964 <context-group name="null">
3965 <context context-type="linenumber">1</context>
3966 </context-group>
3967 </trans-unit>
3968 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
3969 <source>My subscriptions</source>
3970 <target>Meine Abos</target>
3971 <context-group name="null">
3972 <context context-type="linenumber">1</context>
3973 </context-group>
3974 </trans-unit>
3975 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
3976 <source>Misc</source>
3977 <target>Verschiedenes</target>
3978 <context-group name="null">
3979 <context context-type="linenumber">1</context>
3980 </context-group>
3981 </trans-unit>
3982 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
3983 <source>Ownership changes</source>
3984 <target>Besitzer ändern</target>
3956 <context-group name="null"> 3985 <context-group name="null">
3957 <context context-type="linenumber">1</context> 3986 <context context-type="linenumber">1</context>
3958 </context-group> 3987 </context-group>
3959 </trans-unit> 3988 </trans-unit>
3960 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d"> 3989 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
3961 <source>Video imports</source> 3990 <source>My settings</source>
3962 <target>Video-Importe</target> 3991 <target>Meine Einstellungen</target>
3963 <context-group name="null"> 3992 <context-group name="null">
3964 <context context-type="linenumber">1</context> 3993 <context context-type="linenumber">1</context>
3965 </context-group> 3994 </context-group>
@@ -3979,7 +4008,23 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
3979 </context-group> 4008 </context-group>
3980 </trans-unit> 4009 </trans-unit>
3981 <trans-unit id="ff6becacbce7fc0943b0af0df4dd67e5e11bf598"> 4010 <trans-unit id="ff6becacbce7fc0943b0af0df4dd67e5e11bf598">
3982 <source>Subscribe to the account</source><target>Subscribe to the account</target><context-group name="null"> 4011 <source>Subscribe to the account</source>
4012 <target>Diesen Account abonnieren</target>
4013 <context-group name="null">
4014 <context context-type="linenumber">1</context>
4015 </context-group>
4016 </trans-unit>
4017 <trans-unit id="1c95cc372311830f936b39f73c5d6d20c0b16013">
4018 <source>Focus the search bar</source>
4019 <target>Die Suchleiste fokussieren</target>
4020 <context-group name="null">
4021 <context context-type="linenumber">1</context>
4022 </context-group>
4023 </trans-unit>
4024 <trans-unit id="b19ee83cbd2b735fd081b9aa483a890578019099">
4025 <source>Toggle the left menu</source>
4026 <target>Linkes Menü umschalten</target>
4027 <context-group name="null">
3983 <context context-type="linenumber">1</context> 4028 <context context-type="linenumber">1</context>
3984 </context-group> 4029 </context-group>
3985 </trans-unit> 4030 </trans-unit>
@@ -4018,6 +4063,20 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4018 <context context-type="linenumber">1</context> 4063 <context context-type="linenumber">1</context>
4019 </context-group> 4064 </context-group>
4020 </trans-unit> 4065 </trans-unit>
4066 <trans-unit id="0ed7b40c11da9d4565af9c041df20c15bc6be97e">
4067 <source>Toggle Dark theme</source>
4068 <target>Dunkles Theme umschalten</target>
4069 <context-group name="null">
4070 <context context-type="linenumber">1</context>
4071 </context-group>
4072 </trans-unit>
4073 <trans-unit id="badd4b24618ccc8a34620acb9053fc654b9612b2">
4074 <source>Go to my subscriptions</source>
4075 <target>Gehe zu meinen Abos</target>
4076 <context-group name="null">
4077 <context context-type="linenumber">1</context>
4078 </context-group>
4079 </trans-unit>
4021 <trans-unit id="b7184b5a236618e8edd747529869c392ab6dace1"> 4080 <trans-unit id="b7184b5a236618e8edd747529869c392ab6dace1">
4022 <source>Go to my videos</source> 4081 <source>Go to my videos</source>
4023 <target>zur meine Videos gehen</target> 4082 <target>zur meine Videos gehen</target>
@@ -4025,6 +4084,20 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4025 <context context-type="linenumber">1</context> 4084 <context context-type="linenumber">1</context>
4026 </context-group> 4085 </context-group>
4027 </trans-unit> 4086 </trans-unit>
4087 <trans-unit id="acf985bd42886b9b3030b5f68f0e8417c39b40a7">
4088 <source>Go to my imports</source>
4089 <target>Gehe zu meinen Importen</target>
4090 <context-group name="null">
4091 <context context-type="linenumber">1</context>
4092 </context-group>
4093 </trans-unit>
4094 <trans-unit id="cfe3c51f0ae9385dc2ce6df740d87e5514aa9390">
4095 <source>Go to my channels</source>
4096 <target>Gehe zu meinen Kanälen</target>
4097 <context-group name="null">
4098 <context context-type="linenumber">1</context>
4099 </context-group>
4100 </trans-unit>
4028 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7"> 4101 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7">
4029 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>. 4102 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>.
4030</source> 4103</source>
@@ -4041,6 +4114,13 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4041 <context context-type="linenumber">1</context> 4114 <context context-type="linenumber">1</context>
4042 </context-group> 4115 </context-group>
4043 </trans-unit> 4116 </trans-unit>
4117 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
4118 <source>Error</source>
4119 <target>Fehler</target>
4120 <context-group name="null">
4121 <context context-type="linenumber">1</context>
4122 </context-group>
4123 </trans-unit>
4044 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 4124 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
4045 <source>You need to reconnect.</source> 4125 <source>You need to reconnect.</source>
4046 <target>Bitte verbinde dich erneut.</target> 4126 <target>Bitte verbinde dich erneut.</target>
@@ -4062,6 +4142,20 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4062 <context context-type="linenumber">1</context> 4142 <context context-type="linenumber">1</context>
4063 </context-group> 4143 </context-group>
4064 </trans-unit> 4144 </trans-unit>
4145 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4146 <source>Info</source>
4147 <target>Infos</target>
4148 <context-group name="null">
4149 <context context-type="linenumber">1</context>
4150 </context-group>
4151 </trans-unit>
4152 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
4153 <source>Success</source>
4154 <target>Erfolg</target>
4155 <context-group name="null">
4156 <context context-type="linenumber">1</context>
4157 </context-group>
4158 </trans-unit>
4065 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 4159 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
4066 <source>Incorrect username or password.</source> 4160 <source>Incorrect username or password.</source>
4067 <target>Falscher Benutzername oder falsches Passwort.</target> 4161 <target>Falscher Benutzername oder falsches Passwort.</target>
@@ -4279,6 +4373,20 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4279 <context context-type="linenumber">1</context> 4373 <context context-type="linenumber">1</context>
4280 </context-group> 4374 </context-group>
4281 </trans-unit> 4375 </trans-unit>
4376 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4377 <source>Email is required.</source>
4378 <target>Bitte gib eine E-Mail-Adresse ein.</target>
4379 <context-group name="null">
4380 <context context-type="linenumber">1</context>
4381 </context-group>
4382 </trans-unit>
4383 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4384 <source>Email must be valid.</source>
4385 <target>Bitte gebe eine gültige E-Mail-Adresse ein.</target>
4386 <context-group name="null">
4387 <context context-type="linenumber">1</context>
4388 </context-group>
4389 </trans-unit>
4282 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 4390 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
4283 <source>Username is required.</source> 4391 <source>Username is required.</source>
4284 <target>Bitte gib einen Benutzernamen ein.</target> 4392 <target>Bitte gib einen Benutzernamen ein.</target>
@@ -4300,41 +4408,6 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4300 <context context-type="linenumber">1</context> 4408 <context context-type="linenumber">1</context>
4301 </context-group> 4409 </context-group>
4302 </trans-unit> 4410 </trans-unit>
4303 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
4304 <source>Username must be at least 3 characters long.</source>
4305 <target>Der Benutzername muss mindestens 3 Zeichen lang sein.</target>
4306 <context-group name="null">
4307 <context context-type="linenumber">1</context>
4308 </context-group>
4309 </trans-unit>
4310 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
4311 <source>Username cannot be more than 20 characters long.</source>
4312 <target>Der Benutzername darf nicht länger als 20 Zeichen lang sein.</target>
4313 <context-group name="null">
4314 <context context-type="linenumber">1</context>
4315 </context-group>
4316 </trans-unit>
4317 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
4318 <source>Username should be only lowercase alphanumeric characters.</source>
4319 <target>Der Benutzername sollte nur kleine alphanumerische Zeichen enthalten.</target>
4320 <context-group name="null">
4321 <context context-type="linenumber">1</context>
4322 </context-group>
4323 </trans-unit>
4324 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4325 <source>Email is required.</source>
4326 <target>Bitte gib eine E-Mail-Adresse ein.</target>
4327 <context-group name="null">
4328 <context context-type="linenumber">1</context>
4329 </context-group>
4330 </trans-unit>
4331 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4332 <source>Email must be valid.</source>
4333 <target>Bitte gebe eine gültige E-Mail-Adresse ein.</target>
4334 <context-group name="null">
4335 <context context-type="linenumber">1</context>
4336 </context-group>
4337 </trans-unit>
4338 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 4411 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
4339 <source>Password must be at least 6 characters long.</source> 4412 <source>Password must be at least 6 characters long.</source>
4340 <target>Das Passwort muss mindestens 6 Zeichen lang sein.</target> 4413 <target>Das Passwort muss mindestens 6 Zeichen lang sein.</target>
@@ -4398,23 +4471,16 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4398 <context context-type="linenumber">1</context> 4471 <context context-type="linenumber">1</context>
4399 </context-group> 4472 </context-group>
4400 </trans-unit> 4473 </trans-unit>
4401 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674"> 4474 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
4402 <source>Display name must be at least 3 characters long.</source> 4475 <source>Description must be at least 3 characters long.</source>
4403 <target>Der Anzeigename muss mindestens 3 Zeichen lang sein.</target> 4476 <target>Die Beschreibung muss mindestens 3 Zeichen umfassen.</target>
4404 <context-group name="null">
4405 <context context-type="linenumber">1</context>
4406 </context-group>
4407 </trans-unit>
4408 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
4409 <source>Display name cannot be more than 120 characters long.</source>
4410 <target>Der Anzeigename darf nicht länger als 120 Zeichen lang sein.</target>
4411 <context-group name="null"> 4477 <context-group name="null">
4412 <context context-type="linenumber">1</context> 4478 <context context-type="linenumber">1</context>
4413 </context-group> 4479 </context-group>
4414 </trans-unit> 4480 </trans-unit>
4415 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 4481 <trans-unit id="a4179e366d4aa335f1ddd0a13e9109c71a9338d0">
4416 <source>Description must be at least 3 characters long.</source> 4482 <source>Description cannot be more than 1000 characters long.</source>
4417 <target>Die Beschreibung muss mindestens 3 Zeichen umfassen.</target> 4483 <target>Beschreibung kann nicht länger als 1000 Zeichen sein.</target>
4418 <context-group name="null"> 4484 <context-group name="null">
4419 <context context-type="linenumber">1</context> 4485 <context context-type="linenumber">1</context>
4420 </context-group> 4486 </context-group>
@@ -4454,13 +4520,6 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4454 <context context-type="linenumber">1</context> 4520 <context context-type="linenumber">1</context>
4455 </context-group> 4521 </context-group>
4456 </trans-unit> 4522 </trans-unit>
4457 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
4458 <source>Report reason cannot be more than 300 characters long.</source>
4459 <target>Der Grund für die Meldung darf nicht mehr als 300 Zeichen umfassen.</target>
4460 <context-group name="null">
4461 <context context-type="linenumber">1</context>
4462 </context-group>
4463 </trans-unit>
4464 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118"> 4523 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
4465 <source>Moderation comment is required.</source> 4524 <source>Moderation comment is required.</source>
4466 <target>Der Moderationskommentar muss angegeben werden.</target> 4525 <target>Der Moderationskommentar muss angegeben werden.</target>
@@ -4475,13 +4534,6 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4475 <context context-type="linenumber">1</context> 4534 <context context-type="linenumber">1</context>
4476 </context-group> 4535 </context-group>
4477 </trans-unit> 4536 </trans-unit>
4478 <trans-unit id="89d0b662dde0871cf17244e79b2cb62cd517e44f">
4479 <source>Moderation comment cannot be more than 300 characters long.</source>
4480 <target>Der Moderationskommentar darf nicht mehr als 300 Zeichen umfassen.</target>
4481 <context-group name="null">
4482 <context context-type="linenumber">1</context>
4483 </context-group>
4484 </trans-unit>
4485 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6"> 4537 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
4486 <source>The channel is required.</source> 4538 <source>The channel is required.</source>
4487 <target>Der Kanal muss angegeben werden.</target> 4539 <target>Der Kanal muss angegeben werden.</target>
@@ -4524,37 +4576,30 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4524 <context context-type="linenumber">1</context> 4576 <context context-type="linenumber">1</context>
4525 </context-group> 4577 </context-group>
4526 </trans-unit> 4578 </trans-unit>
4527 <trans-unit id="541087322c34e8b26954fd67ff4fc80d1a6c1b33"> 4579 <trans-unit id="c8465c3773699dd075e0147e264d2e232f605803">
4528 <source>Name is required.</source> 4580 <source>You can only transfer ownership to a local account</source>
4529 <target>Der Name muss angegeben werden.</target> 4581 <target>Du kannst den Besitz nur auf einen lokalen Account übertragen</target>
4530 <context-group name="null">
4531 <context context-type="linenumber">1</context>
4532 </context-group>
4533 </trans-unit>
4534 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069">
4535 <source>Name must be at least 3 characters long.</source>
4536 <target>Der Name muss mindestens 3 Zeichen umfassen.</target>
4537 <context-group name="null"> 4582 <context-group name="null">
4538 <context context-type="linenumber">1</context> 4583 <context context-type="linenumber">1</context>
4539 </context-group> 4584 </context-group>
4540 </trans-unit> 4585 </trans-unit>
4541 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482"> 4586 <trans-unit id="541087322c34e8b26954fd67ff4fc80d1a6c1b33">
4542 <source>Name cannot be more than 20 characters long.</source> 4587 <source>Name is required.</source>
4543 <target>Der Name darf nicht mehr als 20 Zeichen umfassen.</target> 4588 <target>Der Name muss angegeben werden.</target>
4544 <context-group name="null"> 4589 <context-group name="null">
4545 <context context-type="linenumber">1</context> 4590 <context context-type="linenumber">1</context>
4546 </context-group> 4591 </context-group>
4547 </trans-unit> 4592 </trans-unit>
4548 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9"> 4593 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
4549 <source>Name should be only lowercase alphanumeric characters.</source> 4594 <source>Support text must be at least 3 characters long.</source>
4550 <target>Der Name sollte nur kleine alphanumerische Zeichen enthalten.</target> 4595 <target>Die Beschreibung zur Unterstützung muss mindestens 3 Zeichen umfassen.</target>
4551 <context-group name="null"> 4596 <context-group name="null">
4552 <context context-type="linenumber">1</context> 4597 <context context-type="linenumber">1</context>
4553 </context-group> 4598 </context-group>
4554 </trans-unit> 4599 </trans-unit>
4555 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 4600 <trans-unit id="15ec53d9ee65cb930c5f5d10ae2e8dd3fd44fc85">
4556 <source>Support text must be at least 3 characters long.</source> 4601 <source>Support text cannot be more than 1000 characters long.</source>
4557 <target>Die Beschreibung zur Unterstützung muss mindestens 3 Zeichen umfassen.</target> 4602 <target>Die Beschreibung zur Unterstützung kann nicht mehr als 1000 Zeichen lang sein.</target>
4558 <context-group name="null"> 4603 <context-group name="null">
4559 <context context-type="linenumber">1</context> 4604 <context context-type="linenumber">1</context>
4560 </context-group> 4605 </context-group>
@@ -4650,6 +4695,13 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
4650 <context context-type="linenumber">1</context> 4695 <context context-type="linenumber">1</context>
4651 </context-group> 4696 </context-group>
4652 </trans-unit> 4697 </trans-unit>
4698 <trans-unit id="f17de746af56840511cae11559539b6d8b6955ad">
4699 <source>Video support cannot be more than 1000 characters long.</source>
4700 <target>Die Beschreibung zur Unterstützung darf nicht mehr als 1000 Zeichen umfassen.</target>
4701 <context-group name="null">
4702 <context context-type="linenumber">1</context>
4703 </context-group>
4704 </trans-unit>
4653 <trans-unit id="453413bf387dea681958871319bab489dd5e6ec0"> 4705 <trans-unit id="453413bf387dea681958871319bab489dd5e6ec0">
4654 <source>A date is required to schedule video update.</source> 4706 <source>A date is required to schedule video update.</source>
4655 <target>Bitte gib ein ein Datum für die geplante Veröffentlichung ein.</target> 4707 <target>Bitte gib ein ein Datum für die geplante Veröffentlichung ein.</target>
@@ -5175,6 +5227,13 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
5175 <context context-type="linenumber">1</context> 5227 <context context-type="linenumber">1</context>
5176 </context-group> 5228 </context-group>
5177 </trans-unit> 5229 </trans-unit>
5230 <trans-unit id="f9b4f2d8146c789cd40314f640ec4e88efbaf681">
5231 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users banned.</source>
5232 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> Benutzer gebannt.</target>
5233 <context-group name="null">
5234 <context context-type="linenumber">1</context>
5235 </context-group>
5236 </trans-unit>
5178 <trans-unit id="3ab99e62550869aebc85661fca2faf46785263dd"> 5237 <trans-unit id="3ab99e62550869aebc85661fca2faf46785263dd">
5179 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> banned.</source> 5238 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> banned.</source>
5180 <target>Benutzer <x id="INTERPOLATION" equiv-text="{{username}}"/> gesperrt.</target> 5239 <target>Benutzer <x id="INTERPOLATION" equiv-text="{{username}}"/> gesperrt.</target>
@@ -5210,6 +5269,111 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
5210 <context context-type="linenumber">1</context> 5269 <context context-type="linenumber">1</context>
5211 </context-group> 5270 </context-group>
5212 </trans-unit> 5271 </trans-unit>
5272 <trans-unit id="534202c90c6dcadd2989fc72c5030d5483e26096">
5273 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> email set as verified</source>
5274 <target>E-Mail des Benutzers <x id="INTERPOLATION" equiv-text="{{username}}"/> als bestätigt markiert</target>
5275 <context-group name="null">
5276 <context context-type="linenumber">1</context>
5277 </context-group>
5278 </trans-unit>
5279 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249">
5280 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source>
5281 <target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> stummgeschaltet.</target>
5282 <context-group name="null">
5283 <context context-type="linenumber">1</context>
5284 </context-group>
5285 </trans-unit>
5286 <trans-unit id="086eda792aeb1b0d131d633b50fdd1792f5f24c6">
5287 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted.</source>
5288 <target>Instanz <x id="INTERPOLATION" equiv-text="{{host}}"/> stummgeschaltet.</target>
5289 <context-group name="null">
5290 <context context-type="linenumber">1</context>
5291 </context-group>
5292 </trans-unit>
5293 <trans-unit id="bb72d6d1219e89d182e9fd09d853d83baf8d6499">
5294 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted by the instance.</source>
5295 <target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> von der Instanz stummgeschaltet.</target>
5296 <context-group name="null">
5297 <context context-type="linenumber">1</context>
5298 </context-group>
5299 </trans-unit>
5300 <trans-unit id="8686834bc4afe42c1991c6c18f0bce174a0e17a6">
5301 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by the instance.</source>
5302 <target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> nicht mehr von der Instanz stummgeschaltet.</target>
5303 <context-group name="null">
5304 <context context-type="linenumber">1</context>
5305 </context-group>
5306 </trans-unit>
5307 <trans-unit id="35d3509161861a610b0895bf084c781e56ba2830">
5308 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted by the instance.</source>
5309 <target>Instanz <x id="INTERPOLATION" equiv-text="{{host}}"/> von der Instanz stummgeschaltet.</target>
5310 <context-group name="null">
5311 <context context-type="linenumber">1</context>
5312 </context-group>
5313 </trans-unit>
5314 <trans-unit id="978aeec5613fa97e8a5336d3599cebb23ee5a90f">
5315 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by the instance.</source>
5316 <target>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> nicht mehr von der Instanz stummgeschaltet.</target>
5317 <context-group name="null">
5318 <context context-type="linenumber">1</context>
5319 </context-group>
5320 </trans-unit>
5321 <trans-unit id="4a09bf8724e7659fbb5ec33647529cdef7614bdc">
5322 <source>Mute this account</source>
5323 <target>Dieses Konto stummschalten</target>
5324 <context-group name="null">
5325 <context context-type="linenumber">1</context>
5326 </context-group>
5327 </trans-unit>
5328 <trans-unit id="d666ca3261aef72b2ddcd649d7b32af488f59952">
5329 <source>Unmute this account</source>
5330 <target>Stummschaltung für dieses Konto aufheben</target>
5331 <context-group name="null">
5332 <context context-type="linenumber">1</context>
5333 </context-group>
5334 </trans-unit>
5335 <trans-unit id="e17218983b1de76e5a920b04e1c2ecbdb6e3e06d">
5336 <source>Mute the instance</source>
5337 <target>Diese Instanz stummschalten</target>
5338 <context-group name="null">
5339 <context context-type="linenumber">1</context>
5340 </context-group>
5341 </trans-unit>
5342 <trans-unit id="a23514d8aca2f8633622dda0e86b399dc576a2b9">
5343 <source>Unmute the instance</source>
5344 <target>Stummschaltung für diese Instanz aufheben</target>
5345 <context-group name="null">
5346 <context context-type="linenumber">1</context>
5347 </context-group>
5348 </trans-unit>
5349 <trans-unit id="4e4107055b44eee44b6954c41120de1cb4d46432">
5350 <source>Mute this account by your instance</source>
5351 <target>Dieses Konto durch deine Instanz stummschalten lassen</target>
5352 <context-group name="null">
5353 <context context-type="linenumber">1</context>
5354 </context-group>
5355 </trans-unit>
5356 <trans-unit id="a51c59cb5ecb7004a6a8ddd2855b5c52266ad957">
5357 <source>Unmute this account by your instance</source>
5358 <target>Stummschaltung dieses Kontos durch deine Instanz aufheben</target>
5359 <context-group name="null">
5360 <context context-type="linenumber">1</context>
5361 </context-group>
5362 </trans-unit>
5363 <trans-unit id="588073e831cec240d6bb0db0b133e45dab69f178">
5364 <source>Mute the instance by your instance</source>
5365 <target>Diese Instanz durch deine Instanz stummschalten lassen</target>
5366 <context-group name="null">
5367 <context context-type="linenumber">1</context>
5368 </context-group>
5369 </trans-unit>
5370 <trans-unit id="676221cdabd4805901343976988c028dbf71b20a">
5371 <source>Unmute the instance by your instance</source>
5372 <target>Stummschaltung dieser Instanz durch deine Instanz aufheben</target>
5373 <context-group name="null">
5374 <context context-type="linenumber">1</context>
5375 </context-group>
5376 </trans-unit>
5213 <trans-unit id="0c0f5bbcd2386018ec057877f9d3c5c2c9880cac"> 5377 <trans-unit id="0c0f5bbcd2386018ec057877f9d3c5c2c9880cac">
5214 <source>Request is too large for the server. Please contact you administrator if you want to increase the limit size.</source> 5378 <source>Request is too large for the server. Please contact you administrator if you want to increase the limit size.</source>
5215 <target>Die Anfrage ist zu groß. Bitte kontaktiere den Administrator, um die Obergrenze für die Größe zu erhöhen.</target> 5379 <target>Die Anfrage ist zu groß. Bitte kontaktiere den Administrator, um die Obergrenze für die Größe zu erhöhen.</target>
@@ -5238,13 +5402,6 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
5238 <context context-type="linenumber">1</context> 5402 <context context-type="linenumber">1</context>
5239 </context-group> 5403 </context-group>
5240 </trans-unit> 5404 </trans-unit>
5241 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5242 <source>Subscribed</source>
5243 <target>Abonniert</target>
5244 <context-group name="null">
5245 <context context-type="linenumber">1</context>
5246 </context-group>
5247 </trans-unit>
5248 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded"> 5405 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
5249 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source> 5406 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
5250 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> abonniert</target> 5407 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> abonniert</target>
@@ -5252,9 +5409,9 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
5252 <context context-type="linenumber">1</context> 5409 <context context-type="linenumber">1</context>
5253 </context-group> 5410 </context-group>
5254 </trans-unit> 5411 </trans-unit>
5255 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471"> 5412 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5256 <source>Unsubscribed</source> 5413 <source>Subscribed</source>
5257 <target>Abo beendet</target> 5414 <target>Abonniert</target>
5258 <context-group name="null"> 5415 <context-group name="null">
5259 <context context-type="linenumber">1</context> 5416 <context context-type="linenumber">1</context>
5260 </context-group> 5417 </context-group>
@@ -5266,6 +5423,13 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
5266 <context context-type="linenumber">1</context> 5423 <context context-type="linenumber">1</context>
5267 </context-group> 5424 </context-group>
5268 </trans-unit> 5425 </trans-unit>
5426 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
5427 <source>Unsubscribed</source>
5428 <target>Abo beendet</target>
5429 <context-group name="null">
5430 <context context-type="linenumber">1</context>
5431 </context-group>
5432 </trans-unit>
5269 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf"> 5433 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf">
5270 <source>Moderator</source> 5434 <source>Moderator</source>
5271 <target>Moderator</target> 5435 <target>Moderator</target>
@@ -5294,6 +5458,20 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
5294 <context context-type="linenumber">1</context> 5458 <context context-type="linenumber">1</context>
5295 </context-group> 5459 </context-group>
5296 </trans-unit> 5460 </trans-unit>
5461 <trans-unit id="21565881ad1dff3c98738b9535b3515cec140609">
5462 <source>Welcome! Now please check your emails to verify your account and complete signup.</source>
5463 <target>Wilkommen! Bitte überprüfe deine Mails um dein Benutzerkonto zu bestätigen und die Registrierung abzuschließen.</target>
5464 <context-group name="null">
5465 <context context-type="linenumber">1</context>
5466 </context-group>
5467 </trans-unit>
5468 <trans-unit id="14200e26888a07633c0f177020dce8f3ec7311a6">
5469 <source>You are now logged in as <x id="INTERPOLATION" equiv-text="{{username}}"/>!</source>
5470 <target>Du bist jetzt eingeloggt als <x id="INTERPOLATION" equiv-text="{{username}}"/>!</target>
5471 <context-group name="null">
5472 <context context-type="linenumber">1</context>
5473 </context-group>
5474 </trans-unit>
5297 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb"> 5475 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb">
5298 <source>Video to import updated.</source> 5476 <source>Video to import updated.</source>
5299 <target>Zu importierendes Video wurde aktualisiert.</target> 5477 <target>Zu importierendes Video wurde aktualisiert.</target>
@@ -5322,13 +5500,6 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
5322 <context context-type="linenumber">1</context> 5500 <context context-type="linenumber">1</context>
5323 </context-group> 5501 </context-group>
5324 </trans-unit> 5502 </trans-unit>
5325 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
5326 <source>Info</source>
5327 <target>Infos</target>
5328 <context-group name="null">
5329 <context context-type="linenumber">1</context>
5330 </context-group>
5331 </trans-unit>
5332 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 5503 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
5333 <source>Upload cancelled</source> 5504 <source>Upload cancelled</source>
5334 <target>Hochladen abgebrochen</target> 5505 <target>Hochladen abgebrochen</target>
@@ -5336,13 +5507,6 @@ Wenn du ein Video in diesen Kanal hochlädst, wird das entsprechende Feld automa
5336 <context context-type="linenumber">1</context> 5507 <context context-type="linenumber">1</context>
5337 </context-group> 5508 </context-group>
5338 </trans-unit> 5509 </trans-unit>
5339 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa">
5340 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
5341 <target>Leider kann PeerTube keine Videos verarbeiten, die größer als 8 GB sind.</target>
5342 <context-group name="null">
5343 <context context-type="linenumber">1</context>
5344 </context-group>
5345 </trans-unit>
5346 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee"> 5510 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
5347 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source> 5511 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
5348 <target>Dein Videokontingent wird mit diesem Video überschritten (Videogröße: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, benutzt: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, Kontingent: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target> 5512 <target>Dein Videokontingent wird mit diesem Video überschritten (Videogröße: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, benutzt: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, Kontingent: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
diff --git a/client/src/locale/target/angular_eo.xml b/client/src/locale/target/angular_eo.xml
index faa52fbdb..0d54b5a5d 100644
--- a/client/src/locale/target/angular_eo.xml
+++ b/client/src/locale/target/angular_eo.xml
@@ -236,7 +236,7 @@
236 <source>Password</source> 236 <source>Password</source>
237 <target>Pasvorto</target> 237 <target>Pasvorto</target>
238 <context-group name="null"> 238 <context-group name="null">
239 <context context-type="linenumber">12</context> 239 <context context-type="linenumber">13</context>
240 </context-group> 240 </context-group>
241 </trans-unit> 241 </trans-unit>
242 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 242 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -250,7 +250,7 @@
250 <source>Login</source> 250 <source>Login</source>
251 <target>Saluti</target> 251 <target>Saluti</target>
252 <context-group name="null"> 252 <context-group name="null">
253 <context context-type="linenumber">38</context> 253 <context context-type="linenumber">36</context>
254 </context-group> 254 </context-group>
255 </trans-unit> 255 </trans-unit>
256 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 256 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -278,7 +278,7 @@
278 <source>Send me an email to reset my password</source> 278 <source>Send me an email to reset my password</source>
279 <target>Sendu al mi retleteron por restarigi mian pasvorton</target> 279 <target>Sendu al mi retleteron por restarigi mian pasvorton</target>
280 <context-group name="null"> 280 <context-group name="null">
281 <context context-type="linenumber">75</context> 281 <context context-type="linenumber">80</context>
282 </context-group> 282 </context-group>
283 </trans-unit> 283 </trans-unit>
284 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 284 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -335,7 +335,7 @@
335 <source>Signup</source> 335 <source>Signup</source>
336 <target>RegistriÄo</target> 336 <target>RegistriÄo</target>
337 <context-group name="null"> 337 <context-group name="null">
338 <context context-type="linenumber">88</context> 338 <context context-type="linenumber">78</context>
339 </context-group> 339 </context-group>
340 </trans-unit> 340 </trans-unit>
341 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a"> 341 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a">
@@ -371,7 +371,7 @@
371 <source>Change the language</source> 371 <source>Change the language</source>
372 <target>ÅœanÄi la lingvon</target> 372 <target>ÅœanÄi la lingvon</target>
373 <context-group name="null"> 373 <context-group name="null">
374 <context context-type="linenumber">88</context> 374 <context context-type="linenumber">86</context>
375 </context-group> 375 </context-group>
376 </trans-unit> 376 </trans-unit>
377 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 377 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -382,7 +382,7 @@
382 Miaj filmoj 382 Miaj filmoj
383 </target> 383 </target>
384 <context-group name="null"> 384 <context-group name="null">
385 <context context-type="linenumber">26</context> 385 <context context-type="linenumber">24</context>
386 </context-group> 386 </context-group>
387 </trans-unit> 387 </trans-unit>
388 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 388 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -393,14 +393,14 @@
393 AdiaÅ­i 393 AdiaÅ­i
394 </target> 394 </target>
395 <context-group name="null"> 395 <context-group name="null">
396 <context context-type="linenumber">30</context> 396 <context context-type="linenumber">28</context>
397 </context-group> 397 </context-group>
398 </trans-unit> 398 </trans-unit>
399 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 399 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
400 <source>Create an account</source> 400 <source>Create an account</source>
401 <target>Krei konton</target> 401 <target>Krei konton</target>
402 <context-group name="null"> 402 <context-group name="null">
403 <context context-type="linenumber">39</context> 403 <context context-type="linenumber">37</context>
404 </context-group> 404 </context-group>
405 </trans-unit> 405 </trans-unit>
406 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 406 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -414,49 +414,49 @@
414 <source>Subscriptions</source> 414 <source>Subscriptions</source>
415 <target>Abonoj</target> 415 <target>Abonoj</target>
416 <context-group name="null"> 416 <context-group name="null">
417 <context context-type="linenumber">47</context> 417 <context context-type="linenumber">45</context>
418 </context-group> 418 </context-group>
419 </trans-unit> 419 </trans-unit>
420 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 420 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
421 <source>Overview</source> 421 <source>Overview</source>
422 <target>Superrigardo</target> 422 <target>Superrigardo</target>
423 <context-group name="null"> 423 <context-group name="null">
424 <context context-type="linenumber">52</context> 424 <context context-type="linenumber">50</context>
425 </context-group> 425 </context-group>
426 </trans-unit> 426 </trans-unit>
427 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 427 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
428 <source>Trending</source> 428 <source>Trending</source>
429 <target>Furoraj</target> 429 <target>Furoraj</target>
430 <context-group name="null"> 430 <context-group name="null">
431 <context context-type="linenumber">57</context> 431 <context context-type="linenumber">55</context>
432 </context-group> 432 </context-group>
433 </trans-unit> 433 </trans-unit>
434 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 434 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
435 <source>Recently added</source> 435 <source>Recently added</source>
436 <target>FreÅe aldonitaj</target> 436 <target>FreÅe aldonitaj</target>
437 <context-group name="null"> 437 <context-group name="null">
438 <context context-type="linenumber">62</context> 438 <context context-type="linenumber">60</context>
439 </context-group> 439 </context-group>
440 </trans-unit> 440 </trans-unit>
441 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 441 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
442 <source>Local</source> 442 <source>Local</source>
443 <target>Lokaj</target> 443 <target>Lokaj</target>
444 <context-group name="null"> 444 <context-group name="null">
445 <context context-type="linenumber">67</context> 445 <context context-type="linenumber">65</context>
446 </context-group> 446 </context-group>
447 </trans-unit> 447 </trans-unit>
448 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 448 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
449 <source>More</source> 449 <source>More</source>
450 <target>Pli</target> 450 <target>Pli</target>
451 <context-group name="null"> 451 <context-group name="null">
452 <context context-type="linenumber">72</context> 452 <context context-type="linenumber">70</context>
453 </context-group> 453 </context-group>
454 </trans-unit> 454 </trans-unit>
455 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 455 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
456 <source>Administration</source> 456 <source>Administration</source>
457 <target>Administrado</target> 457 <target>Administrado</target>
458 <context-group name="null"> 458 <context-group name="null">
459 <context context-type="linenumber">76</context> 459 <context context-type="linenumber">74</context>
460 </context-group> 460 </context-group>
461 </trans-unit> 461 </trans-unit>
462 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 462 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -568,7 +568,7 @@
568 <source>No results.</source> 568 <source>No results.</source>
569 <target>Nenio troviÄis.</target> 569 <target>Nenio troviÄis.</target>
570 <context-group name="null"> 570 <context-group name="null">
571 <context context-type="linenumber">17</context> 571 <context context-type="linenumber">20</context>
572 </context-group> 572 </context-group>
573 </trans-unit> 573 </trans-unit>
574 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b"> 574 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b">
@@ -585,15 +585,11 @@
585 <context context-type="linenumber">7</context> 585 <context context-type="linenumber">7</context>
586 </context-group> 586 </context-group>
587 </trans-unit> 587 </trans-unit>
588 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 588 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
589 <source> 589 <source>Submit</source>
590 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 590 <target>Sendi</target>
591</source>
592 <target>
593 Pri la nodo « <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> »
594</target>
595 <context-group name="null"> 591 <context-group name="null">
596 <context context-type="linenumber">1</context> 592 <context context-type="linenumber">31</context>
597 </context-group> 593 </context-group>
598 </trans-unit> 594 </trans-unit>
599 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 595 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -607,47 +603,14 @@
607 <source>Terms</source> 603 <source>Terms</source>
608 <target>Kondiĉoj</target> 604 <target>Kondiĉoj</target>
609 <context-group name="null"> 605 <context-group name="null">
610 <context context-type="linenumber">44</context> 606 <context context-type="linenumber">39</context>
611 </context-group> 607 </context-group>
612 </trans-unit> 608 </trans-unit>
613 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 609 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
614 <source>User registration is allowed and</source> 610 <source>User registration is allowed and</source>
615 <target>Registrado de uzantoj estas permesata kaj</target> 611 <target>Registrado de uzantoj estas permesata kaj</target>
616 <context-group name="null"> 612 <context-group name="null">
617 <context context-type="linenumber">25</context> 613 <context context-type="linenumber">29</context>
618 </context-group>
619 </trans-unit>
620 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
621 <source>
622 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
623 </source>
624 <target>
625 ĉi tiu nodo donas bazan datumlimon de <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> da spaco por filmoj de siaj uzantoj.
626 </target>
627 <context-group name="null">
628 <context context-type="linenumber">27</context>
629 </context-group>
630 </trans-unit>
631 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
632 <source>
633 this instance provides unlimited space for the videos of its users.
634 </source>
635 <target>
636 ĉi tiu nodo donas senliman spacon por filmoj de siaj uzantoj.
637 </target>
638 <context-group name="null">
639 <context context-type="linenumber">31</context>
640 </context-group>
641 </trans-unit>
642 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
643 <source>
644 User registration is currently not allowed.
645 </source>
646 <target>
647 Registrado de novaj uzantoj nun ne estas permesata.
648 </target>
649 <context-group name="null">
650 <context context-type="linenumber">36</context>
651 </context-group> 614 </context-group>
652 </trans-unit> 615 </trans-unit>
653 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 616 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -956,49 +919,49 @@
956 <source>Short description</source> 919 <source>Short description</source>
957 <target>Mallonga priskribo</target> 920 <target>Mallonga priskribo</target>
958 <context-group name="null"> 921 <context-group name="null">
959 <context context-type="linenumber">22</context> 922 <context context-type="linenumber">21</context>
960 </context-group> 923 </context-group>
961 </trans-unit> 924 </trans-unit>
962 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 925 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
963 <source>Default client route</source> 926 <source>Default client route</source>
964 <target>Norma klienta vojo</target> 927 <target>Norma klienta vojo</target>
965 <context-group name="null"> 928 <context-group name="null">
966 <context context-type="linenumber">55</context> 929 <context context-type="linenumber">48</context>
967 </context-group> 930 </context-group>
968 </trans-unit> 931 </trans-unit>
969 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 932 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
970 <source>Videos Overview</source> 933 <source>Videos Overview</source>
971 <target>Filma superrigardo</target> 934 <target>Filma superrigardo</target>
972 <context-group name="null"> 935 <context-group name="null">
973 <context context-type="linenumber">58</context> 936 <context context-type="linenumber">51</context>
974 </context-group> 937 </context-group>
975 </trans-unit> 938 </trans-unit>
976 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 939 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
977 <source>Videos Trending</source> 940 <source>Videos Trending</source>
978 <target>Filmoj furoraj</target> 941 <target>Filmoj furoraj</target>
979 <context-group name="null"> 942 <context-group name="null">
980 <context context-type="linenumber">59</context> 943 <context context-type="linenumber">52</context>
981 </context-group> 944 </context-group>
982 </trans-unit> 945 </trans-unit>
983 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 946 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
984 <source>Videos Recently Added</source> 947 <source>Videos Recently Added</source>
985 <target>Filmoj freÅe aldonitaj</target> 948 <target>Filmoj freÅe aldonitaj</target>
986 <context-group name="null"> 949 <context-group name="null">
987 <context context-type="linenumber">60</context> 950 <context context-type="linenumber">53</context>
988 </context-group> 951 </context-group>
989 </trans-unit> 952 </trans-unit>
990 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 953 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
991 <source>Local videos</source> 954 <source>Local videos</source>
992 <target>Filmoj lokaj</target> 955 <target>Filmoj lokaj</target>
993 <context-group name="null"> 956 <context-group name="null">
994 <context context-type="linenumber">61</context> 957 <context context-type="linenumber">54</context>
995 </context-group> 958 </context-group>
996 </trans-unit> 959 </trans-unit>
997 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 960 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
998 <source>Policy on videos containing sensitive content</source> 961 <source>Policy on videos containing sensitive content</source>
999 <target>Politiko pri filmoj kun konsterna enhavo</target> 962 <target>Politiko pri filmoj kun konsterna enhavo</target>
1000 <context-group name="null"> 963 <context-group name="null">
1001 <context context-type="linenumber">70</context> 964 <context context-type="linenumber">61</context>
1002 </context-group> 965 </context-group>
1003 </trans-unit> 966 </trans-unit>
1004 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 967 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1033,23 +996,37 @@
1033 <source>Signup enabled</source> 996 <source>Signup enabled</source>
1034 <target>RegistriÄoj Åaltitaj</target> 997 <target>RegistriÄoj Åaltitaj</target>
1035 <context-group name="null"> 998 <context-group name="null">
1036 <context context-type="linenumber">93</context> 999 <context context-type="linenumber">84</context>
1037 </context-group> 1000 </context-group>
1038 </trans-unit> 1001 </trans-unit>
1039 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1002 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1040 <source>Signup requires email verification</source> 1003 <source>Signup requires email verification</source>
1041 <target>RegistriÄo bezonas kontrolon de retpoÅtadreso</target> 1004 <target>RegistriÄo bezonas kontrolon de retpoÅtadreso</target>
1042 <context-group name="null"> 1005 <context-group name="null">
1043 <context context-type="linenumber">100</context> 1006 <context context-type="linenumber">91</context>
1044 </context-group> 1007 </context-group>
1045 </trans-unit> 1008 </trans-unit>
1046 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1009 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1047 <source>Signup limit</source> 1010 <source>Signup limit</source>
1048 <target>Limo de registriÄoj</target> 1011 <target>Limo de registriÄoj</target>
1049 <context-group name="null"> 1012 <context-group name="null">
1013 <context context-type="linenumber">96</context>
1014 </context-group>
1015 </trans-unit>
1016 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1017 <source>Users</source>
1018 <target>Uzantoj</target>
1019 <context-group name="null">
1050 <context context-type="linenumber">105</context> 1020 <context context-type="linenumber">105</context>
1051 </context-group> 1021 </context-group>
1052 </trans-unit> 1022 </trans-unit>
1023 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1024 <source>User default video quota</source>
1025 <target>Norma datumlimo por filmoj de uzantoj</target>
1026 <context-group name="null">
1027 <context context-type="linenumber">109</context>
1028 </context-group>
1029 </trans-unit>
1053 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1030 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1054 <source>Import</source> 1031 <source>Import</source>
1055 <target>Enporti</target> 1032 <target>Enporti</target>
@@ -1061,35 +1038,21 @@
1061 <source>Video import with a torrent file or a magnet URI enabled</source> 1038 <source>Video import with a torrent file or a magnet URI enabled</source>
1062 <target>Enporto de filmoj per torenta dosiero aÅ­ magneta ligilo Åaltita</target> 1039 <target>Enporto de filmoj per torenta dosiero aÅ­ magneta ligilo Åaltita</target>
1063 <context-group name="null"> 1040 <context-group name="null">
1064 <context context-type="linenumber">127</context> 1041 <context context-type="linenumber">148</context>
1065 </context-group> 1042 </context-group>
1066 </trans-unit> 1043 </trans-unit>
1067 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1044 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1068 <source>Administrator</source> 1045 <source>Administrator</source>
1069 <target>Administranto</target> 1046 <target>Administranto</target>
1070 <context-group name="null"> 1047 <context-group name="null">
1071 <context context-type="linenumber">131</context> 1048 <context context-type="linenumber">155</context>
1072 </context-group> 1049 </context-group>
1073 </trans-unit> 1050 </trans-unit>
1074 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1051 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1075 <source>Admin email</source> 1052 <source>Admin email</source>
1076 <target>RetpoÅtadreso de administranto</target> 1053 <target>RetpoÅtadreso de administranto</target>
1077 <context-group name="null"> 1054 <context-group name="null">
1078 <context context-type="linenumber">134</context> 1055 <context context-type="linenumber">158</context>
1079 </context-group>
1080 </trans-unit>
1081 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1082 <source>Users</source>
1083 <target>Uzantoj</target>
1084 <context-group name="null">
1085 <context context-type="linenumber">144</context>
1086 </context-group>
1087 </trans-unit>
1088 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1089 <source>User default video quota</source>
1090 <target>Norma datumlimo por filmoj de uzantoj</target>
1091 <context-group name="null">
1092 <context context-type="linenumber">147</context>
1093 </context-group> 1056 </context-group>
1094 </trans-unit> 1057 </trans-unit>
1095 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1058 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1110,21 +1073,21 @@
1110 <source>Your Twitter username</source> 1073 <source>Your Twitter username</source>
1111 <target>Via Tvitera salutnomo</target> 1074 <target>Via Tvitera salutnomo</target>
1112 <context-group name="null"> 1075 <context-group name="null">
1113 <context context-type="linenumber">181</context> 1076 <context context-type="linenumber">184</context>
1114 </context-group> 1077 </context-group>
1115 </trans-unit> 1078 </trans-unit>
1116 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1079 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1117 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1080 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1118 <target>Indikas konton de Twitter por la retejo aÅ­ platformo, sur kiu la afero publikiÄis.</target> 1081 <target>Indikas konton de Twitter por la retejo aÅ­ platformo, sur kiu la afero publikiÄis.</target>
1119 <context-group name="null"> 1082 <context-group name="null">
1120 <context context-type="linenumber">184</context> 1083 <context context-type="linenumber">187</context>
1121 </context-group> 1084 </context-group>
1122 </trans-unit> 1085 </trans-unit>
1123 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1086 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1124 <source>Instance whitelisted by Twitter</source> 1087 <source>Instance whitelisted by Twitter</source>
1125 <target>Nodo permesata de Twitter</target> 1088 <target>Nodo permesata de Twitter</target>
1126 <context-group name="null"> 1089 <context-group name="null">
1127 <context context-type="linenumber">198</context> 1090 <context context-type="linenumber">199</context>
1128 </context-group> 1091 </context-group>
1129 </trans-unit> 1092 </trans-unit>
1130 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1093 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1138,98 +1101,98 @@
1138 <source>Transcoding</source> 1101 <source>Transcoding</source>
1139 <target>Transkodado</target> 1102 <target>Transkodado</target>
1140 <context-group name="null"> 1103 <context-group name="null">
1141 <context context-type="linenumber">210</context> 1104 <context context-type="linenumber">215</context>
1142 </context-group> 1105 </context-group>
1143 </trans-unit> 1106 </trans-unit>
1144 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1107 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1145 <source>Transcoding enabled</source> 1108 <source>Transcoding enabled</source>
1146 <target>Transkodado Åaltita</target> 1109 <target>Transkodado Åaltita</target>
1147 <context-group name="null"> 1110 <context-group name="null">
1148 <context context-type="linenumber">215</context> 1111 <context context-type="linenumber">221</context>
1149 </context-group> 1112 </context-group>
1150 </trans-unit> 1113 </trans-unit>
1151 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1114 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1152 <source>If you disable transcoding, many videos from your users will not work!</source> 1115 <source>If you disable transcoding, many videos from your users will not work!</source>
1153 <target>Se vi malÅaltos transkodadon, multaj filmoj de viaj uzantoj eble ne funkcios!</target> 1116 <target>Se vi malÅaltos transkodadon, multaj filmoj de viaj uzantoj eble ne funkcios!</target>
1154 <context-group name="null"> 1117 <context-group name="null">
1155 <context context-type="linenumber">216</context> 1118 <context context-type="linenumber">222</context>
1156 </context-group> 1119 </context-group>
1157 </trans-unit> 1120 </trans-unit>
1158 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1121 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1159 <source>Transcoding threads</source> 1122 <source>Transcoding threads</source>
1160 <target>Fadenoj por transkodado</target> 1123 <target>Fadenoj por transkodado</target>
1161 <context-group name="null"> 1124 <context-group name="null">
1162 <context context-type="linenumber">223</context> 1125 <context context-type="linenumber">237</context>
1163 </context-group> 1126 </context-group>
1164 </trans-unit> 1127 </trans-unit>
1165 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1128 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1166 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1129 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1167 <target>Distingo <x id="INTERPOLATION" equiv-text="{{resolution}}"/> Åaltita</target> 1130 <target>Distingo <x id="INTERPOLATION" equiv-text="{{resolution}}"/> Åaltita</target>
1168 <context-group name="null"> 1131 <context-group name="null">
1169 <context context-type="linenumber">239</context> 1132 <context context-type="linenumber">252</context>
1170 </context-group> 1133 </context-group>
1171 </trans-unit> 1134 </trans-unit>
1172 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1135 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1173 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1136 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1174 <target>Iuj dosieroj ne estas federataj (antaÅ­rigardoj, transskriboj). Ni prenas kaj kaÅmemoras ilin rekte el la fonta nodo.</target> 1137 <target>Iuj dosieroj ne estas federataj (antaÅ­rigardoj, transskriboj). Ni prenas kaj kaÅmemoras ilin rekte el la fonta nodo.</target>
1175 <context-group name="null"> 1138 <context-group name="null">
1176 <context context-type="linenumber">249</context> 1139 <context context-type="linenumber">265</context>
1177 </context-group> 1140 </context-group>
1178 </trans-unit> 1141 </trans-unit>
1179 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1142 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1180 <source>Previews cache size</source> 1143 <source>Previews cache size</source>
1181 <target>Grando de antaÅ­rigarda kaÅmemoro</target> 1144 <target>Grando de antaÅ­rigarda kaÅmemoro</target>
1182 <context-group name="null"> 1145 <context-group name="null">
1183 <context context-type="linenumber">254</context> 1146 <context context-type="linenumber">271</context>
1184 </context-group> 1147 </context-group>
1185 </trans-unit> 1148 </trans-unit>
1186 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1149 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1187 <source>Video captions cache size</source> 1150 <source>Video captions cache size</source>
1188 <target>Grandeco de kaÅmemoro por filmaj transskriboj.</target> 1151 <target>Grandeco de kaÅmemoro por filmaj transskriboj.</target>
1189 <context-group name="null"> 1152 <context-group name="null">
1190 <context context-type="linenumber">265</context> 1153 <context context-type="linenumber">280</context>
1191 </context-group> 1154 </context-group>
1192 </trans-unit> 1155 </trans-unit>
1193 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1156 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1194 <source>Customizations</source> 1157 <source>Customizations</source>
1195 <target>Adaptoj</target> 1158 <target>Adaptoj</target>
1196 <context-group name="null"> 1159 <context-group name="null">
1197 <context context-type="linenumber">275</context> 1160 <context context-type="linenumber">289</context>
1198 </context-group> 1161 </context-group>
1199 </trans-unit> 1162 </trans-unit>
1200 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1163 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1201 <source>JavaScript</source> 1164 <source>JavaScript</source>
1202 <target>Äœavoskripto</target> 1165 <target>Äœavoskripto</target>
1203 <context-group name="null"> 1166 <context-group name="null">
1204 <context context-type="linenumber">278</context> 1167 <context context-type="linenumber">294</context>
1205 </context-group> 1168 </context-group>
1206 </trans-unit> 1169 </trans-unit>
1207 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1170 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1208 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1171 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1209 <target>Skribu rekte Äœavoskriptan kodon.&lt;br /&gt;Ekzemple: &lt;pre&gt;console.log('mia nodo bonegas');&lt;/pre&gt;</target> 1172 <target>Skribu rekte Äœavoskriptan kodon.&lt;br /&gt;Ekzemple: &lt;pre&gt;console.log('mia nodo bonegas');&lt;/pre&gt;</target>
1210 <context-group name="null"> 1173 <context-group name="null">
1211 <context context-type="linenumber">281</context> 1174 <context context-type="linenumber">297</context>
1212 </context-group> 1175 </context-group>
1213 </trans-unit> 1176 </trans-unit>
1214 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab"> 1177 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab">
1215 <source>Advanced configuration</source> 1178 <source>Advanced configuration</source>
1216 <target>Specialaj agordoj</target> 1179 <target>Specialaj agordoj</target>
1217 <context-group name="null"> 1180 <context-group name="null">
1218 <context context-type="linenumber">207</context> 1181 <context context-type="linenumber">212</context>
1219 </context-group> 1182 </context-group>
1220 </trans-unit> 1183 </trans-unit>
1221 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1184 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1222 <source>Update configuration</source> 1185 <source>Update configuration</source>
1223 <target>Efektivigi agordojn</target> 1186 <target>Efektivigi agordojn</target>
1224 <context-group name="null"> 1187 <context-group name="null">
1225 <context context-type="linenumber">325</context> 1188 <context context-type="linenumber">340</context>
1226 </context-group> 1189 </context-group>
1227 </trans-unit> 1190 </trans-unit>
1228 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1191 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1229 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1192 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1230 <target>Ŝajnas, ke la agordo estas nevalida. Bonvolu serĉi eblajn erarojn en la langetoj.</target> 1193 <target>Ŝajnas, ke la agordo estas nevalida. Bonvolu serĉi eblajn erarojn en la langetoj.</target>
1231 <context-group name="null"> 1194 <context-group name="null">
1232 <context context-type="linenumber">326</context> 1195 <context context-type="linenumber">341</context>
1233 </context-group> 1196 </context-group>
1234 </trans-unit> 1197 </trans-unit>
1235 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1198 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1496,41 +1459,6 @@
1496 <context context-type="linenumber">7</context> 1459 <context context-type="linenumber">7</context>
1497 </context-group> 1460 </context-group>
1498 </trans-unit> 1461 </trans-unit>
1499 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
1500 <source>My settings</source>
1501 <target>Miaj agordoj</target>
1502 <context-group name="null">
1503 <context context-type="linenumber">3</context>
1504 </context-group>
1505 </trans-unit>
1506 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
1507 <source>My channels</source>
1508 <target>Miaj kanaloj</target>
1509 <context-group name="null">
1510 <context context-type="linenumber">12</context>
1511 </context-group>
1512 </trans-unit>
1513 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
1514 <source>My videos</source>
1515 <target>Miaj filmoj</target>
1516 <context-group name="null">
1517 <context context-type="linenumber">14</context>
1518 </context-group>
1519 </trans-unit>
1520 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
1521 <source>My subscriptions</source>
1522 <target>Miaj abonoj</target>
1523 <context-group name="null">
1524 <context context-type="linenumber">16</context>
1525 </context-group>
1526 </trans-unit>
1527 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
1528 <source>My imports</source>
1529 <target>Miaj enportoj</target>
1530 <context-group name="null">
1531 <context context-type="linenumber">18</context>
1532 </context-group>
1533 </trans-unit>
1534 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 1462 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
1535 <source>Video quota:</source> 1463 <source>Video quota:</source>
1536 <target>Datumlimo por filmoj:</target> 1464 <target>Datumlimo por filmoj:</target>
@@ -1542,28 +1470,21 @@
1542 <source>Profile</source> 1470 <source>Profile</source>
1543 <target>Profilo</target> 1471 <target>Profilo</target>
1544 <context-group name="null"> 1472 <context-group name="null">
1545 <context context-type="linenumber">8</context> 1473 <context context-type="linenumber">7</context>
1546 </context-group> 1474 </context-group>
1547 </trans-unit> 1475 </trans-unit>
1548 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 1476 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
1549 <source>Video settings</source> 1477 <source>Video settings</source>
1550 <target>Filmaj agordoj:</target> 1478 <target>Filmaj agordoj:</target>
1551 <context-group name="null"> 1479 <context-group name="null">
1552 <context context-type="linenumber">15</context> 1480 <context context-type="linenumber">16</context>
1553 </context-group> 1481 </context-group>
1554 </trans-unit> 1482 </trans-unit>
1555 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 1483 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
1556 <source>Danger zone</source> 1484 <source>Danger zone</source>
1557 <target>DanÄera areo</target> 1485 <target>DanÄera areo</target>
1558 <context-group name="null"> 1486 <context-group name="null">
1559 <context context-type="linenumber">18</context> 1487 <context context-type="linenumber">19</context>
1560 </context-group>
1561 </trans-unit>
1562 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
1563 <source>Submit</source>
1564 <target>Sendi</target>
1565 <context-group name="null">
1566 <context context-type="linenumber">24</context>
1567 </context-group> 1488 </context-group>
1568 </trans-unit> 1489 </trans-unit>
1569 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 1490 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
@@ -1801,14 +1722,14 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
1801 <source>Publish will be available when upload is finished</source> 1722 <source>Publish will be available when upload is finished</source>
1802 <target>Eldono eblos post fino de alÅuto</target> 1723 <target>Eldono eblos post fino de alÅuto</target>
1803 <context-group name="null"> 1724 <context-group name="null">
1804 <context context-type="linenumber">53</context> 1725 <context context-type="linenumber">58</context>
1805 </context-group> 1726 </context-group>
1806 </trans-unit> 1727 </trans-unit>
1807 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 1728 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
1808 <source>Publish</source> 1729 <source>Publish</source>
1809 <target>Eldoni</target> 1730 <target>Eldoni</target>
1810 <context-group name="null"> 1731 <context-group name="null">
1811 <context context-type="linenumber">60</context> 1732 <context context-type="linenumber">65</context>
1812 </context-group> 1733 </context-group>
1813 </trans-unit> 1734 </trans-unit>
1814 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 1735 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -1952,14 +1873,14 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
1952 <source>Wait transcoding before publishing the video</source> 1873 <source>Wait transcoding before publishing the video</source>
1953 <target>Atendi transkodadon antaÅ­ publikigi la filmon</target> 1874 <target>Atendi transkodadon antaÅ­ publikigi la filmon</target>
1954 <context-group name="null"> 1875 <context-group name="null">
1955 <context context-type="linenumber">130</context> 1876 <context context-type="linenumber">131</context>
1956 </context-group> 1877 </context-group>
1957 </trans-unit> 1878 </trans-unit>
1958 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 1879 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
1959 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 1880 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
1960 <target>Se vi decidos ne atendi finon de transkodado antaÅ­ publikigo, Äi povus esti neludebla Äis la transkodo finiÄos.</target> 1881 <target>Se vi decidos ne atendi finon de transkodado antaÅ­ publikigo, Äi povus esti neludebla Äis la transkodo finiÄos.</target>
1961 <context-group name="null"> 1882 <context-group name="null">
1962 <context context-type="linenumber">131</context> 1883 <context context-type="linenumber">132</context>
1963 </context-group> 1884 </context-group>
1964 </trans-unit> 1885 </trans-unit>
1965 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 1886 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -1973,49 +1894,49 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
1973 <source>Add another caption</source> 1894 <source>Add another caption</source>
1974 <target>Aldoni alian transskribon</target> 1895 <target>Aldoni alian transskribon</target>
1975 <context-group name="null"> 1896 <context-group name="null">
1976 <context context-type="linenumber">146</context> 1897 <context context-type="linenumber">147</context>
1977 </context-group> 1898 </context-group>
1978 </trans-unit> 1899 </trans-unit>
1979 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 1900 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
1980 <source>See the subtitle file</source> 1901 <source>See the subtitle file</source>
1981 <target>Rigardi la dosieron kun subtekstoj</target> 1902 <target>Rigardi la dosieron kun subtekstoj</target>
1982 <context-group name="null"> 1903 <context-group name="null">
1983 <context context-type="linenumber">155</context> 1904 <context context-type="linenumber">156</context>
1984 </context-group> 1905 </context-group>
1985 </trans-unit> 1906 </trans-unit>
1986 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 1907 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
1987 <source>Cancel create</source> 1908 <source>Cancel create</source>
1988 <target>Nuligi kreon</target> 1909 <target>Nuligi kreon</target>
1989 <context-group name="null"> 1910 <context-group name="null">
1990 <context context-type="linenumber">169</context> 1911 <context context-type="linenumber">170</context>
1991 </context-group> 1912 </context-group>
1992 </trans-unit> 1913 </trans-unit>
1993 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 1914 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
1994 <source>Cancel deletion</source> 1915 <source>Cancel deletion</source>
1995 <target>Nuligi forigon</target> 1916 <target>Nuligi forigon</target>
1996 <context-group name="null"> 1917 <context-group name="null">
1997 <context context-type="linenumber">177</context> 1918 <context context-type="linenumber">178</context>
1998 </context-group> 1919 </context-group>
1999 </trans-unit> 1920 </trans-unit>
2000 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 1921 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2001 <source>Captions</source> 1922 <source>Captions</source>
2002 <target>Transskriboj</target> 1923 <target>Transskriboj</target>
2003 <context-group name="null"> 1924 <context-group name="null">
2004 <context context-type="linenumber">139</context> 1925 <context context-type="linenumber">140</context>
2005 </context-group> 1926 </context-group>
2006 </trans-unit> 1927 </trans-unit>
2007 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 1928 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
2008 <source>Upload thumbnail</source> 1929 <source>Upload thumbnail</source>
2009 <target>AlÅuti miniaturon</target> 1930 <target>AlÅuti miniaturon</target>
2010 <context-group name="null"> 1931 <context-group name="null">
2011 <context context-type="linenumber">195</context> 1932 <context context-type="linenumber">196</context>
2012 </context-group> 1933 </context-group>
2013 </trans-unit> 1934 </trans-unit>
2014 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 1935 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
2015 <source>Upload preview</source> 1936 <source>Upload preview</source>
2016 <target>AlÅuti antaÅ­rigardon</target> 1937 <target>AlÅuti antaÅ­rigardon</target>
2017 <context-group name="null"> 1938 <context-group name="null">
2018 <context context-type="linenumber">202</context> 1939 <context context-type="linenumber">203</context>
2019 </context-group> 1940 </context-group>
2020 </trans-unit> 1941 </trans-unit>
2021 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 1942 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -2029,14 +1950,14 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
2029 <source>Short text to tell people how they can support you (membership platform...).</source> 1950 <source>Short text to tell people how they can support you (membership platform...).</source>
2030 <target>Mallonga teksto por sciigi homojn, kiel ili povas subteni vin.</target> 1951 <target>Mallonga teksto por sciigi homojn, kiel ili povas subteni vin.</target>
2031 <context-group name="null"> 1952 <context-group name="null">
2032 <context context-type="linenumber">209</context> 1953 <context context-type="linenumber">210</context>
2033 </context-group> 1954 </context-group>
2034 </trans-unit> 1955 </trans-unit>
2035 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 1956 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
2036 <source>Advanced settings</source> 1957 <source>Advanced settings</source>
2037 <target>Specialaj agordoj</target> 1958 <target>Specialaj agordoj</target>
2038 <context-group name="null"> 1959 <context-group name="null">
2039 <context context-type="linenumber">190</context> 1960 <context context-type="linenumber">191</context>
2040 </context-group> 1961 </context-group>
2041 </trans-unit> 1962 </trans-unit>
2042 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 1963 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -2319,13 +2240,6 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
2319 <context context-type="linenumber">14</context> 2240 <context context-type="linenumber">14</context>
2320 </context-group> 2241 </context-group>
2321 </trans-unit> 2242 </trans-unit>
2322 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
2323 <source>Error getting about from server</source>
2324 <target>Eraro ricevante prion de la servilo</target>
2325 <context-group name="null">
2326 <context context-type="linenumber">1</context>
2327 </context-group>
2328 </trans-unit>
2329 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 2243 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
2330 <source>No description</source> 2244 <source>No description</source>
2331 <target>Neniu priskribo</target> 2245 <target>Neniu priskribo</target>
@@ -2347,20 +2261,6 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
2347 <context context-type="linenumber">1</context> 2261 <context context-type="linenumber">1</context>
2348 </context-group> 2262 </context-group>
2349 </trans-unit> 2263 </trans-unit>
2350 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
2351 <source>Error</source>
2352 <target>Eraro</target>
2353 <context-group name="null">
2354 <context context-type="linenumber">1</context>
2355 </context-group>
2356 </trans-unit>
2357 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
2358 <source>Success</source>
2359 <target>Sukceso</target>
2360 <context-group name="null">
2361 <context context-type="linenumber">1</context>
2362 </context-group>
2363 </trans-unit>
2364 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 2264 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
2365 <source>Configuration updated.</source> 2265 <source>Configuration updated.</source>
2366 <target>Agordo Äisdatigita</target> 2266 <target>Agordo Äisdatigita</target>
@@ -2550,23 +2450,16 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
2550 <context context-type="linenumber">1</context> 2450 <context context-type="linenumber">1</context>
2551 </context-group> 2451 </context-group>
2552 </trans-unit> 2452 </trans-unit>
2553 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 2453 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
2554 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 2454 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
2555 <target>Ĉu vi certe volas forigi kanalon <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? Tiel vi ankaÅ­ forigos ĉiujn filmojn alÅutitajn al tiu ĉi kanalo.</target> 2455 <target>Filma kanalo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> forigita.</target>
2556 <context-group name="null">
2557 <context context-type="linenumber">1</context>
2558 </context-group>
2559 </trans-unit>
2560 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
2561 <source>Please type the name of the video channel to confirm</source>
2562 <target>Bonvolu tajpi nomon de la filma kanalo por konfirmi</target>
2563 <context-group name="null"> 2456 <context-group name="null">
2564 <context context-type="linenumber">1</context> 2457 <context context-type="linenumber">1</context>
2565 </context-group> 2458 </context-group>
2566 </trans-unit> 2459 </trans-unit>
2567 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 2460 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2568 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 2461 <source>My videos</source>
2569 <target>Filma kanalo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> forigita.</target> 2462 <target>Miaj filmoj</target>
2570 <context-group name="null"> 2463 <context-group name="null">
2571 <context context-type="linenumber">1</context> 2464 <context context-type="linenumber">1</context>
2572 </context-group> 2465 </context-group>
@@ -2627,6 +2520,27 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
2627 <context context-type="linenumber">1</context> 2520 <context context-type="linenumber">1</context>
2628 </context-group> 2521 </context-group>
2629 </trans-unit> 2522 </trans-unit>
2523 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2524 <source>My channels</source>
2525 <target>Miaj kanaloj</target>
2526 <context-group name="null">
2527 <context context-type="linenumber">1</context>
2528 </context-group>
2529 </trans-unit>
2530 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2531 <source>My subscriptions</source>
2532 <target>Miaj abonoj</target>
2533 <context-group name="null">
2534 <context context-type="linenumber">1</context>
2535 </context-group>
2536 </trans-unit>
2537 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2538 <source>My settings</source>
2539 <target>Miaj agordoj</target>
2540 <context-group name="null">
2541 <context context-type="linenumber">1</context>
2542 </context-group>
2543 </trans-unit>
2630 <trans-unit id="ccbf0490fb6b60d21e03bb2c9003df0ce1a58752"> 2544 <trans-unit id="ccbf0490fb6b60d21e03bb2c9003df0ce1a58752">
2631 <source>Unable to find user id or verification string.</source> 2545 <source>Unable to find user id or verification string.</source>
2632 <target>Ne povas trovi identigilon aŭ kontrolan ĉenon de uzanto</target> 2546 <target>Ne povas trovi identigilon aŭ kontrolan ĉenon de uzanto</target>
@@ -2650,6 +2564,13 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
2650 <context context-type="linenumber">1</context> 2564 <context context-type="linenumber">1</context>
2651 </context-group> 2565 </context-group>
2652 </trans-unit> 2566 </trans-unit>
2567 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
2568 <source>Error</source>
2569 <target>Eraro</target>
2570 <context-group name="null">
2571 <context context-type="linenumber">1</context>
2572 </context-group>
2573 </trans-unit>
2653 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 2574 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
2654 <source>You need to reconnect.</source> 2575 <source>You need to reconnect.</source>
2655 <target>Vi devas rekonektiÄi</target> 2576 <target>Vi devas rekonektiÄi</target>
@@ -2664,6 +2585,20 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
2664 <context context-type="linenumber">1</context> 2585 <context context-type="linenumber">1</context>
2665 </context-group> 2586 </context-group>
2666 </trans-unit> 2587 </trans-unit>
2588 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
2589 <source>Info</source>
2590 <target>Informoj</target>
2591 <context-group name="null">
2592 <context context-type="linenumber">1</context>
2593 </context-group>
2594 </trans-unit>
2595 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
2596 <source>Success</source>
2597 <target>Sukceso</target>
2598 <context-group name="null">
2599 <context context-type="linenumber">1</context>
2600 </context-group>
2601 </trans-unit>
2667 <trans-unit id="7701e3762dc4a2b2e302c24f17820bc8dd7cacc1"> 2602 <trans-unit id="7701e3762dc4a2b2e302c24f17820bc8dd7cacc1">
2668 <source>An email with the reset password instructions will be sent to <x id="INTERPOLATION" equiv-text="{{email}}"/>.</source> 2603 <source>An email with the reset password instructions will be sent to <x id="INTERPOLATION" equiv-text="{{email}}"/>.</source>
2669 <target>Retletero kun instrukcioj por restarigi la pasvorton sendiÄos al <x id="INTERPOLATION" equiv-text="{{email}}"/>.</target> 2604 <target>Retletero kun instrukcioj por restarigi la pasvorton sendiÄos al <x id="INTERPOLATION" equiv-text="{{email}}"/>.</target>
@@ -2860,6 +2795,20 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
2860 <context context-type="linenumber">1</context> 2795 <context context-type="linenumber">1</context>
2861 </context-group> 2796 </context-group>
2862 </trans-unit> 2797 </trans-unit>
2798 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
2799 <source>Email is required.</source>
2800 <target>Necesas retpoÅtadreso.</target>
2801 <context-group name="null">
2802 <context context-type="linenumber">1</context>
2803 </context-group>
2804 </trans-unit>
2805 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
2806 <source>Email must be valid.</source>
2807 <target>RetpoÅtadreso devas esti valida.</target>
2808 <context-group name="null">
2809 <context context-type="linenumber">1</context>
2810 </context-group>
2811 </trans-unit>
2863 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 2812 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
2864 <source>Username is required.</source> 2813 <source>Username is required.</source>
2865 <target>Necesas salutnomo.</target> 2814 <target>Necesas salutnomo.</target>
@@ -2881,41 +2830,6 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
2881 <context context-type="linenumber">1</context> 2830 <context context-type="linenumber">1</context>
2882 </context-group> 2831 </context-group>
2883 </trans-unit> 2832 </trans-unit>
2884 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
2885 <source>Username must be at least 3 characters long.</source>
2886 <target>Salutnomo devas havi almenaÅ­ 3 signojn.</target>
2887 <context-group name="null">
2888 <context context-type="linenumber">1</context>
2889 </context-group>
2890 </trans-unit>
2891 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
2892 <source>Username cannot be more than 20 characters long.</source>
2893 <target>Salutnomo ne povas havi pli ol 20 signojn.</target>
2894 <context-group name="null">
2895 <context context-type="linenumber">1</context>
2896 </context-group>
2897 </trans-unit>
2898 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
2899 <source>Username should be only lowercase alphanumeric characters.</source>
2900 <target>Salutnomo havu nur ciferojn kaj minusklajn literojn.</target>
2901 <context-group name="null">
2902 <context context-type="linenumber">1</context>
2903 </context-group>
2904 </trans-unit>
2905 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
2906 <source>Email is required.</source>
2907 <target>Necesas retpoÅtadreso.</target>
2908 <context-group name="null">
2909 <context context-type="linenumber">1</context>
2910 </context-group>
2911 </trans-unit>
2912 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
2913 <source>Email must be valid.</source>
2914 <target>RetpoÅtadreso devas esti valida.</target>
2915 <context-group name="null">
2916 <context context-type="linenumber">1</context>
2917 </context-group>
2918 </trans-unit>
2919 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 2833 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
2920 <source>Password must be at least 6 characters long.</source> 2834 <source>Password must be at least 6 characters long.</source>
2921 <target>Pasvorto devas havi almenaÅ­ 6 signojn.</target> 2835 <target>Pasvorto devas havi almenaÅ­ 6 signojn.</target>
@@ -2965,20 +2879,6 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
2965 <context context-type="linenumber">1</context> 2879 <context context-type="linenumber">1</context>
2966 </context-group> 2880 </context-group>
2967 </trans-unit> 2881 </trans-unit>
2968 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
2969 <source>Display name must be at least 3 characters long.</source>
2970 <target>Prezenta nomo devas havi almenaÅ­ 3 signojn.</target>
2971 <context-group name="null">
2972 <context context-type="linenumber">1</context>
2973 </context-group>
2974 </trans-unit>
2975 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
2976 <source>Display name cannot be more than 120 characters long.</source>
2977 <target>Prezenta nomo ne povas havi pli ol 120 signojn.</target>
2978 <context-group name="null">
2979 <context context-type="linenumber">1</context>
2980 </context-group>
2981 </trans-unit>
2982 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 2882 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
2983 <source>Description must be at least 3 characters long.</source> 2883 <source>Description must be at least 3 characters long.</source>
2984 <target>Priskribo havu almenaÅ­ 3 signojn.</target> 2884 <target>Priskribo havu almenaÅ­ 3 signojn.</target>
@@ -3007,13 +2907,6 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
3007 <context context-type="linenumber">1</context> 2907 <context context-type="linenumber">1</context>
3008 </context-group> 2908 </context-group>
3009 </trans-unit> 2909 </trans-unit>
3010 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
3011 <source>Report reason cannot be more than 300 characters long.</source>
3012 <target>Kialo de raporto maldevas havi pli ol 300 signojn.</target>
3013 <context-group name="null">
3014 <context context-type="linenumber">1</context>
3015 </context-group>
3016 </trans-unit>
3017 <trans-unit id="c9eadf8830b3bc09bd444d739af86414eed9bd9e"> 2910 <trans-unit id="c9eadf8830b3bc09bd444d739af86414eed9bd9e">
3018 <source>Video caption language is required.</source> 2911 <source>Video caption language is required.</source>
3019 <target>Necesas lingvo de filma transskribo.</target> 2912 <target>Necesas lingvo de filma transskribo.</target>
@@ -3686,13 +3579,6 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
3686 <context context-type="linenumber">1</context> 3579 <context context-type="linenumber">1</context>
3687 </context-group> 3580 </context-group>
3688 </trans-unit> 3581 </trans-unit>
3689 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
3690 <source>Info</source>
3691 <target>Informoj</target>
3692 <context-group name="null">
3693 <context context-type="linenumber">1</context>
3694 </context-group>
3695 </trans-unit>
3696 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 3582 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
3697 <source>Upload cancelled</source> 3583 <source>Upload cancelled</source>
3698 <target>AlÅuto nuligita.</target> 3584 <target>AlÅuto nuligita.</target>
@@ -3700,13 +3586,6 @@ Kiam vi alÅutos filmon al tiu ĉi kanalo, la kampo pri subteno memfare enhavos
3700 <context context-type="linenumber">1</context> 3586 <context context-type="linenumber">1</context>
3701 </context-group> 3587 </context-group>
3702 </trans-unit> 3588 </trans-unit>
3703 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa">
3704 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
3705 <target>Pardonu nin, sed PeerTube ne kapablas trakti filmojn super 8GB</target>
3706 <context-group name="null">
3707 <context context-type="linenumber">1</context>
3708 </context-group>
3709 </trans-unit>
3710 <trans-unit id="972fc644f847cf84e4732ec012915c4cdaf865ce"> 3589 <trans-unit id="972fc644f847cf84e4732ec012915c4cdaf865ce">
3711 <source>Video published.</source> 3590 <source>Video published.</source>
3712 <target>Filmo publikigita.</target> 3591 <target>Filmo publikigita.</target>
diff --git a/client/src/locale/target/angular_es_ES.xml b/client/src/locale/target/angular_es_ES.xml
index 947c9a91d..828de2a57 100644
--- a/client/src/locale/target/angular_es_ES.xml
+++ b/client/src/locale/target/angular_es_ES.xml
@@ -5,7 +5,7 @@
5 <body> 5 <body>
6 <trans-unit id="ngb.alert.close"> 6 <trans-unit id="ngb.alert.close">
7 <source>Close</source> 7 <source>Close</source>
8 <target>Cerrar</target> 8 <target>tppCerrar</target>
9 <context-group name="null"> 9 <context-group name="null">
10 <context context-type="linenumber">2</context> 10 <context context-type="linenumber">2</context>
11 </context-group> 11 </context-group>
@@ -227,6 +227,155 @@
227 <context context-type="linenumber">11</context> 227 <context context-type="linenumber">11</context>
228 </context-group> 228 </context-group>
229 </trans-unit> 229 </trans-unit>
230 <trans-unit id="f3e63578c50546530daf6050d2ba6f8226040f2c">
231 <source>You don't have notifications.</source>
232 <target>No tiene notificaciones</target>
233 <context-group name="null">
234 <context context-type="linenumber">1</context>
235 </context-group>
236 </trans-unit>
237 <trans-unit id="f79d1d9ecaab3deb3d44e23017f8283a04d2a0f3">
238 <source>
239 <x id="INTERPOLATION" equiv-text="{{ notification.video.channel.displayName }}"/> published a <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>new video<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
240 </source>
241 <target>
242 <x id="INTERPOLATION" equiv-text="{{ notification.video.channel.displayName }}"/> ha publicado un <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>nuevo vídeo<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
243 </target>
244 <context-group name="null">
245 <context context-type="linenumber">7</context>
246 </context-group>
247 </trans-unit>
248 <trans-unit id="04f2cb4c88c17d5f3e5ce969479b4eba9db114cb">
249 <source>
250 Your video <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> has been unblacklisted
251 </source>
252 <target>
253 Su vídeo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> ha sido desbloqueado
254 </target>
255 <context-group name="null">
256 <context context-type="linenumber">11</context>
257 </context-group>
258 </trans-unit>
259 <trans-unit id="65514a0efdae3b173130166416700ddeb369f37f">
260 <source>
261 Your video <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.videoBlacklist.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> has been blacklisted
262 </source>
263 <target>
264 Su vídeo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.videoBlacklist.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> ha sido bloqueado
265 </target>
266 <context-group name="null">
267 <context context-type="linenumber">15</context>
268 </context-group>
269 </trans-unit>
270 <trans-unit id="4ea67498da562ab450950a69f4331b8c4ddfd431">
271 <source>
272 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>A new video abuse<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> has been created on video <x id="START_LINK_1" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.videoAbuse.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
273 </source>
274 <target>
275 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>Una nueva denuncia de abuso<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> ha sido creada sobre el vídeo <x id="START_LINK_1" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.videoAbuse.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
276 </target>
277 <context-group name="null">
278 <context context-type="linenumber">19</context>
279 </context-group>
280 </trans-unit>
281 <trans-unit id="23b7d6f08c5c3b8722ecd627c3d54f4950923156">
282 <source>
283 <x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/> commented your video <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
284 </source>
285 <target>
286 <x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/> ha comentado su vídeo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
287 </target>
288 <context-group name="null">
289 <context context-type="linenumber">23</context>
290 </context-group>
291 </trans-unit>
292 <trans-unit id="2d0ee93317d4daa301eee7fec775c21c2f7b5a4b">
293 <source>
294 Your video <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> has been published
295 </source>
296 <target>
297 Su vídeo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> ha sido publicado
298 </target>
299 <context-group name="null">
300 <context context-type="linenumber">27</context>
301 </context-group>
302 </trans-unit>
303 <trans-unit id="371391b88724e5ee455582f07eb97728e371f24a">
304 <source>
305 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>Your video import<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> <x id="INTERPOLATION" equiv-text="{{ notification.videoImportIdentifier }}"/> succeeded
306 </source>
307 <target>
308 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>Importación de vídeo<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> <x id="INTERPOLATION" equiv-text="{{ notification.videoImportIdentifier }}"/> exitosa
309 </target>
310 <context-group name="null">
311 <context context-type="linenumber">31</context>
312 </context-group>
313 </trans-unit>
314 <trans-unit id="56e72a0a79d53e9ff8d5f92528664bcb2cf1363a">
315 <source>
316 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>Your video import<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> <x id="INTERPOLATION" equiv-text="{{ notification.videoImportIdentifier }}"/> failed
317 </source>
318 <target>
319 Error durante la <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>importación de vídeo<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> <x id="INTERPOLATION" equiv-text="{{ notification.videoImportIdentifier }}"/>
320 </target>
321 <context-group name="null">
322 <context context-type="linenumber">35</context>
323 </context-group>
324 </trans-unit>
325 <trans-unit id="d7f123ae20ca6bfb5ac0f897b90423fdc52d8e78">
326 <source>
327 User <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.account.name }}"/> registered<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on your instance
328 </source>
329 <target>
330 Nuevo usuario <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.account.name }}"/>registrado<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> en su instancia
331 </target>
332 <context-group name="null">
333 <context context-type="linenumber">39</context>
334 </context-group>
335 </trans-unit>
336 <trans-unit id="9a05dc5206104085b2b6654fb9137291194a72ef">
337 <source>
338 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.actorFollow.follower.displayName }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> is following
339
340 <x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/>
341 your channel <x id="INTERPOLATION_1" equiv-text="{{ notification.actorFollow.following.displayName }}"/>
342 <x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
343 <x id="START_TAG_NG-CONTAINER_1" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/>your account<x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
344 </source>
345 <target>
346 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.actorFollow.follower.displayName }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> ahora sigue
347
348 <x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/>
349 su canal <x id="INTERPOLATION_1" equiv-text="{{ notification.actorFollow.following.displayName }}"/>
350 <x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
351 <x id="START_TAG_NG-CONTAINER_1" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/>su cuenta<x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
352 </target>
353 <context-group name="null">
354 <context context-type="linenumber">43</context>
355 </context-group>
356 </trans-unit>
357 <trans-unit id="98b174525a2c9b4de0a510fb6eae7bdf285c0c7f">
358 <source>
359 <x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/> mentioned you on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>video <x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
360 </source>
361 <target>
362 <x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/> le ha mencionado en el <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>vídeo <x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
363 </target>
364 <context-group name="null">
365 <context context-type="linenumber">52</context>
366 </context-group>
367 </trans-unit>
368 <trans-unit id="473117e02024f603dc2dbd24a0bf81f8722cf8dc">
369 <source>
370 <x id="START_TAG_DIV" ctype="x-div" equiv-text="&lt;div&gt;"/><x id="CLOSE_TAG_DIV" ctype="x-div" equiv-text="&lt;/div&gt;"/>
371 </source>
372 <target>
373 <x id="START_TAG_DIV" ctype="x-div" equiv-text="&lt;div&gt;"/><x id="CLOSE_TAG_DIV" ctype="x-div" equiv-text="&lt;/div&gt;"/>
374 </target>
375 <context-group name="null">
376 <context context-type="linenumber">57</context>
377 </context-group>
378 </trans-unit>
230 <trans-unit id="4b3963c6d0863118fe9e9e33447d12be3c2db081"> 379 <trans-unit id="4b3963c6d0863118fe9e9e33447d12be3c2db081">
231 <source>Unlisted</source> 380 <source>Unlisted</source>
232 <target>No listado</target> 381 <target>No listado</target>
@@ -433,6 +582,13 @@ Cancelar la subscripción</target>
433 <context context-type="linenumber">25</context> 582 <context context-type="linenumber">25</context>
434 </context-group> 583 </context-group>
435 </trans-unit> 584 </trans-unit>
585 <trans-unit id="c078d4901a5fac169665947cc7a6108b94dd80c7">
586 <source><x id="INTERPOLATION" equiv-text="{{ menuEntry.label }}"/></source>
587 <target><x id="INTERPOLATION" equiv-text="{{ menuEntry.label }}"/></target>
588 <context-group name="null">
589 <context context-type="linenumber">11</context>
590 </context-group>
591 </trans-unit>
436 <trans-unit id="12910217fdcdbca64bee06f511639b653d5428ea"> 592 <trans-unit id="12910217fdcdbca64bee06f511639b653d5428ea">
437 <source> 593 <source>
438 Login 594 Login
@@ -497,7 +653,7 @@ Iniciar sesión</target>
497 <source>Password</source> 653 <source>Password</source>
498 <target>Contraseña</target> 654 <target>Contraseña</target>
499 <context-group name="null"> 655 <context-group name="null">
500 <context context-type="linenumber">12</context> 656 <context context-type="linenumber">13</context>
501 </context-group> 657 </context-group>
502 </trans-unit> 658 </trans-unit>
503 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 659 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -511,7 +667,7 @@ Iniciar sesión</target>
511 <source>Login</source> 667 <source>Login</source>
512 <target>Identificarse</target> 668 <target>Identificarse</target>
513 <context-group name="null"> 669 <context-group name="null">
514 <context context-type="linenumber">38</context> 670 <context context-type="linenumber">36</context>
515 </context-group> 671 </context-group>
516 </trans-unit> 672 </trans-unit>
517 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 673 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -521,6 +677,17 @@ Iniciar sesión</target>
521 <context context-type="linenumber">57</context> 677 <context context-type="linenumber">57</context>
522 </context-group> 678 </context-group>
523 </trans-unit> 679 </trans-unit>
680 <trans-unit id="f876804a6725f7b950c8e4c56ca596206856e6a2">
681 <source>
682 We are sorry, you cannot recover you password because your instance administrator did not configure the PeerTube email system.
683 </source>
684 <target>
685 Lo sentimos, no puede recuperar su contraseña porque el administrador de su instancia no configuró el sistema de correos electrónicos de PeerTube.
686 </target>
687 <context-group name="null">
688 <context context-type="linenumber">63</context>
689 </context-group>
690 </trans-unit>
524 <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc"> 691 <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc">
525 <source>Email</source> 692 <source>Email</source>
526 <target>Correo electrónico </target> 693 <target>Correo electrónico </target>
@@ -539,7 +706,7 @@ Iniciar sesión</target>
539 <source>Send me an email to reset my password</source> 706 <source>Send me an email to reset my password</source>
540 <target>Enviar un correo electrónico para restablecer mi contraseña</target> 707 <target>Enviar un correo electrónico para restablecer mi contraseña</target>
541 <context-group name="null"> 708 <context-group name="null">
542 <context context-type="linenumber">75</context> 709 <context context-type="linenumber">80</context>
543 </context-group> 710 </context-group>
544 </trans-unit> 711 </trans-unit>
545 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 712 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -608,7 +775,7 @@ Iniciar sesión</target>
608 <source>Signup</source> 775 <source>Signup</source>
609 <target>Registro</target> 776 <target>Registro</target>
610 <context-group name="null"> 777 <context-group name="null">
611 <context context-type="linenumber">88</context> 778 <context context-type="linenumber">78</context>
612 </context-group> 779 </context-group>
613 </trans-unit> 780 </trans-unit>
614 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 781 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -678,7 +845,18 @@ Iniciar sesión</target>
678 <source>Change the language</source> 845 <source>Change the language</source>
679 <target>Cambiar el idioma</target> 846 <target>Cambiar el idioma</target>
680 <context-group name="null"> 847 <context-group name="null">
681 <context context-type="linenumber">88</context> 848 <context context-type="linenumber">86</context>
849 </context-group>
850 </trans-unit>
851 <trans-unit id="1c98d728375e7bd5b166d1aeb29485ef8b5d6e28">
852 <source>
853 Help to translate PeerTube!
854 </source>
855 <target>
856 ¡Ayude a traducir PeerTube!
857 </target>
858 <context-group name="null">
859 <context context-type="linenumber">8</context>
682 </context-group> 860 </context-group>
683 </trans-unit> 861 </trans-unit>
684 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 862 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -689,7 +867,7 @@ Iniciar sesión</target>
689 Mi perfil público 867 Mi perfil público
690 </target> 868 </target>
691 <context-group name="null"> 869 <context-group name="null">
692 <context context-type="linenumber">18</context> 870 <context context-type="linenumber">16</context>
693 </context-group> 871 </context-group>
694 </trans-unit> 872 </trans-unit>
695 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 873 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -700,7 +878,7 @@ Iniciar sesión</target>
700 Mi cuenta 878 Mi cuenta
701 </target> 879 </target>
702 <context-group name="null"> 880 <context-group name="null">
703 <context context-type="linenumber">22</context> 881 <context context-type="linenumber">20</context>
704 </context-group> 882 </context-group>
705 </trans-unit> 883 </trans-unit>
706 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 884 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -711,7 +889,7 @@ Iniciar sesión</target>
711 Mis vídeos 889 Mis vídeos
712 </target> 890 </target>
713 <context-group name="null"> 891 <context-group name="null">
714 <context context-type="linenumber">26</context> 892 <context context-type="linenumber">24</context>
715 </context-group> 893 </context-group>
716 </trans-unit> 894 </trans-unit>
717 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 895 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -722,14 +900,14 @@ Iniciar sesión</target>
722 Desconectarse 900 Desconectarse
723 </target> 901 </target>
724 <context-group name="null"> 902 <context-group name="null">
725 <context context-type="linenumber">30</context> 903 <context context-type="linenumber">28</context>
726 </context-group> 904 </context-group>
727 </trans-unit> 905 </trans-unit>
728 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 906 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
729 <source>Create an account</source> 907 <source>Create an account</source>
730 <target>Crear una cuenta</target> 908 <target>Crear una cuenta</target>
731 <context-group name="null"> 909 <context-group name="null">
732 <context context-type="linenumber">39</context> 910 <context context-type="linenumber">37</context>
733 </context-group> 911 </context-group>
734 </trans-unit> 912 </trans-unit>
735 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 913 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -743,49 +921,49 @@ Iniciar sesión</target>
743 <source>Subscriptions</source> 921 <source>Subscriptions</source>
744 <target>Suscripciones</target> 922 <target>Suscripciones</target>
745 <context-group name="null"> 923 <context-group name="null">
746 <context context-type="linenumber">47</context> 924 <context context-type="linenumber">45</context>
747 </context-group> 925 </context-group>
748 </trans-unit> 926 </trans-unit>
749 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 927 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
750 <source>Overview</source> 928 <source>Overview</source>
751 <target>Vista general</target> 929 <target>Vista general</target>
752 <context-group name="null"> 930 <context-group name="null">
753 <context context-type="linenumber">52</context> 931 <context context-type="linenumber">50</context>
754 </context-group> 932 </context-group>
755 </trans-unit> 933 </trans-unit>
756 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 934 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
757 <source>Trending</source> 935 <source>Trending</source>
758 <target>Tendencias</target> 936 <target>Tendencias</target>
759 <context-group name="null"> 937 <context-group name="null">
760 <context context-type="linenumber">57</context> 938 <context context-type="linenumber">55</context>
761 </context-group> 939 </context-group>
762 </trans-unit> 940 </trans-unit>
763 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 941 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
764 <source>Recently added</source> 942 <source>Recently added</source>
765 <target>Añadidos recientemente</target> 943 <target>Añadidos recientemente</target>
766 <context-group name="null"> 944 <context-group name="null">
767 <context context-type="linenumber">62</context> 945 <context context-type="linenumber">60</context>
768 </context-group> 946 </context-group>
769 </trans-unit> 947 </trans-unit>
770 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 948 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
771 <source>Local</source> 949 <source>Local</source>
772 <target>Local</target> 950 <target>Local</target>
773 <context-group name="null"> 951 <context-group name="null">
774 <context context-type="linenumber">67</context> 952 <context context-type="linenumber">65</context>
775 </context-group> 953 </context-group>
776 </trans-unit> 954 </trans-unit>
777 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 955 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
778 <source>More</source> 956 <source>More</source>
779 <target>Más</target> 957 <target>Más</target>
780 <context-group name="null"> 958 <context-group name="null">
781 <context context-type="linenumber">72</context> 959 <context context-type="linenumber">70</context>
782 </context-group> 960 </context-group>
783 </trans-unit> 961 </trans-unit>
784 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 962 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
785 <source>Administration</source> 963 <source>Administration</source>
786 <target>Administración</target> 964 <target>Administración</target>
787 <context-group name="null"> 965 <context-group name="null">
788 <context context-type="linenumber">76</context> 966 <context context-type="linenumber">74</context>
789 </context-group> 967 </context-group>
790 </trans-unit> 968 </trans-unit>
791 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 969 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -799,14 +977,42 @@ Iniciar sesión</target>
799 <source>Show keyboard shortcuts</source> 977 <source>Show keyboard shortcuts</source>
800 <target>Mostrar los atajos de teclado</target> 978 <target>Mostrar los atajos de teclado</target>
801 <context-group name="null"> 979 <context-group name="null">
802 <context context-type="linenumber">91</context> 980 <context context-type="linenumber">89</context>
803 </context-group> 981 </context-group>
804 </trans-unit> 982 </trans-unit>
805 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 983 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
806 <source>Toggle dark interface</source> 984 <source>Toggle dark interface</source>
807 <target>Alternar con la interfaz oscura</target> 985 <target>Alternar con la interfaz oscura</target>
808 <context-group name="null"> 986 <context-group name="null">
809 <context context-type="linenumber">94</context> 987 <context context-type="linenumber">92</context>
988 </context-group>
989 </trans-unit>
990 <trans-unit id="2dc8a0a3763cd5c456c84630fc335398c9b86771">
991 <source>View your notifications</source>
992 <target>Ver sus notificaciones</target>
993 <context-group name="null">
994 <context context-type="linenumber">3</context>
995 </context-group>
996 </trans-unit>
997 <trans-unit id="8bcabdf6b16cad0313a86c7e940c5e3ad7f9f8ab">
998 <source>Notifications</source>
999 <target>Notificaciones</target>
1000 <context-group name="null">
1001 <context context-type="linenumber">10</context>
1002 </context-group>
1003 </trans-unit>
1004 <trans-unit id="341e026e3f317aa3164916cc63a059c961a78b81">
1005 <source>Update your notification preferences</source>
1006 <target>Actualizar sus preferencias de notificación</target>
1007 <context-group name="null">
1008 <context context-type="linenumber">15</context>
1009 </context-group>
1010 </trans-unit>
1011 <trans-unit id="3d1b5c9cd76948c04fdb7bb3fe51b6c1242c1bd5">
1012 <source>See all your notifications</source>
1013 <target>Ver todas sus notificaciones</target>
1014 <context-group name="null">
1015 <context context-type="linenumber">22</context>
810 </context-group> 1016 </context-group>
811 </trans-unit> 1017 </trans-unit>
812 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 1018 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -911,14 +1117,14 @@ Iniciar sesión</target>
911 <source>Display unlisted and private videos</source> 1117 <source>Display unlisted and private videos</source>
912 <target>Mostrar los vídeos no listados y privados</target> 1118 <target>Mostrar los vídeos no listados y privados</target>
913 <context-group name="null"> 1119 <context-group name="null">
914 <context context-type="linenumber">11</context> 1120 <context context-type="linenumber">14</context>
915 </context-group> 1121 </context-group>
916 </trans-unit> 1122 </trans-unit>
917 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 1123 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
918 <source>No results.</source> 1124 <source>No results.</source>
919 <target> Ningún resultados</target> 1125 <target> Ningún resultados</target>
920 <context-group name="null"> 1126 <context-group name="null">
921 <context context-type="linenumber">17</context> 1127 <context context-type="linenumber">20</context>
922 </context-group> 1128 </context-group>
923 </trans-unit> 1129 </trans-unit>
924 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 1130 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -976,15 +1182,64 @@ Iniciar sesión</target>
976 <context context-type="linenumber">7</context> 1182 <context context-type="linenumber">7</context>
977 </context-group> 1183 </context-group>
978 </trans-unit> 1184 </trans-unit>
979 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 1185 <trans-unit id="5fea66be16da46ed7a0775e9a62b7b5e94b77473">
1186 <source>Contact <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> administrator</source>
1187 <target>Contactar al administrador de <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/></target>
1188 <context-group name="null">
1189 <context context-type="linenumber">3</context>
1190 </context-group>
1191 </trans-unit>
1192 <trans-unit id="533b2b9a76ee1335cb44c01f0bfd50d43e9400b0">
1193 <source>Your name</source>
1194 <target>Su nombre</target>
1195 <context-group name="null">
1196 <context context-type="linenumber">11</context>
1197 </context-group>
1198 </trans-unit>
1199 <trans-unit id="0b892c7805a1c5afc0b7c21c3449760860fe7f3d">
1200 <source>Your email</source>
1201 <target>Su dirección de correo electrónico</target>
1202 <context-group name="null">
1203 <context context-type="linenumber">20</context>
1204 </context-group>
1205 </trans-unit>
1206 <trans-unit id="d2815c9b510b8172d8cac4008b9709df69d636df">
1207 <source>Your message</source>
1208 <target>Su mensaje</target>
1209 <context-group name="null">
1210 <context context-type="linenumber">29</context>
1211 </context-group>
1212 </trans-unit>
1213 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
980 <source> 1214 <source>
981 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 1215 Cancel
982</source> 1216 </source>
983 <target> 1217 <target>
984 Acerca del nodo <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> 1218 Cancelar
985</target> 1219 </target>
986 <context-group name="null"> 1220 <context-group name="null">
987 <context context-type="linenumber">1</context> 1221 <context context-type="linenumber">26</context>
1222 </context-group>
1223 </trans-unit>
1224 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
1225 <source>Submit</source>
1226 <target>Enviar</target>
1227 <context-group name="null">
1228 <context context-type="linenumber">31</context>
1229 </context-group>
1230 </trans-unit>
1231 <trans-unit id="89e55a86cb300f06139ff398c9c8bb7376f78b07">
1232 <source>About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance</source>
1233 <target>Acerca de la instancia <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/></target>
1234 <context-group name="null">
1235 <context context-type="linenumber">4</context>
1236 </context-group>
1237 </trans-unit>
1238 <trans-unit id="3c1aff50472b313c70a72ee02c081b8eeb1c616c">
1239 <source>Contact administrator</source>
1240 <target>Contactar al administrador</target>
1241 <context-group name="null">
1242 <context context-type="linenumber">6</context>
988 </context-group> 1243 </context-group>
989 </trans-unit> 1244 </trans-unit>
990 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 1245 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -998,47 +1253,47 @@ Iniciar sesión</target>
998 <source>Terms</source> 1253 <source>Terms</source>
999 <target>Términos de uso</target> 1254 <target>Términos de uso</target>
1000 <context-group name="null"> 1255 <context-group name="null">
1001 <context context-type="linenumber">44</context> 1256 <context context-type="linenumber">39</context>
1002 </context-group> 1257 </context-group>
1003 </trans-unit> 1258 </trans-unit>
1004 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 1259 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
1005 <source>User registration is allowed and</source> 1260 <source>User registration is allowed and</source>
1006 <target>El registro de usuarios está permitido y</target> 1261 <target>El registro de usuarios está permitido y</target>
1007 <context-group name="null"> 1262 <context-group name="null">
1008 <context context-type="linenumber">25</context> 1263 <context context-type="linenumber">29</context>
1009 </context-group> 1264 </context-group>
1010 </trans-unit> 1265 </trans-unit>
1011 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e"> 1266 <trans-unit id="7a0a7b5a5bc9ee7b7e415f87ecc404145fb51dff">
1012 <source> 1267 <source>
1013 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users. 1268 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
1014 </source> 1269 </source>
1015 <target> 1270 <target>
1016 este nodo ofrece una cuota estándar de <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> de espacio para los vídeos de sus usuarios. 1271 esta instancia provee un espacio máximo de <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> para los vídeos de sus usuarios.
1017 </target> 1272 </target>
1018 <context-group name="null"> 1273 <context-group name="null">
1019 <context context-type="linenumber">27</context> 1274 <context context-type="linenumber">31</context>
1020 </context-group> 1275 </context-group>
1021 </trans-unit> 1276 </trans-unit>
1022 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae"> 1277 <trans-unit id="7bee5dd41c0007820f150ee33b8257dc1aac281b">
1023 <source> 1278 <source>
1024 this instance provides unlimited space for the videos of its users. 1279 this instance provides unlimited space for the videos of its users.
1025 </source> 1280 </source>
1026 <target> 1281 <target>
1027 este nodo ofrece espacio ilimitado para los vídeos de sus usuarios. 1282 esta instancia provee un espacio ilimitado para los vídeos de sus usuarios.
1028 </target> 1283 </target>
1029 <context-group name="null"> 1284 <context-group name="null">
1030 <context context-type="linenumber">31</context> 1285 <context context-type="linenumber">35</context>
1031 </context-group> 1286 </context-group>
1032 </trans-unit> 1287 </trans-unit>
1033 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1"> 1288 <trans-unit id="b6e2ede24a2ee0f6ba2f1924ede2ae408ffc2574">
1034 <source> 1289 <source>
1035 User registration is currently not allowed. 1290 User registration is currently not allowed.
1036 </source> 1291 </source>
1037 <target> 1292 <target>
1038 El registro de usuarios no está permitido actualmente. 1293 El registro de usuarios no está abierto actualmente.
1039 </target> 1294 </target>
1040 <context-group name="null"> 1295 <context-group name="null">
1041 <context context-type="linenumber">36</context> 1296 <context context-type="linenumber">40</context>
1042 </context-group> 1297 </context-group>
1043 </trans-unit> 1298 </trans-unit>
1044 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 1299 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1395,49 +1650,49 @@ Iniciar sesión</target>
1395 <source>Short description</source> 1650 <source>Short description</source>
1396 <target>Descripción corta</target> 1651 <target>Descripción corta</target>
1397 <context-group name="null"> 1652 <context-group name="null">
1398 <context context-type="linenumber">22</context> 1653 <context context-type="linenumber">21</context>
1399 </context-group> 1654 </context-group>
1400 </trans-unit> 1655 </trans-unit>
1401 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1656 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1402 <source>Default client route</source> 1657 <source>Default client route</source>
1403 <target>Routa de cliente por defecto</target> 1658 <target>Routa de cliente por defecto</target>
1404 <context-group name="null"> 1659 <context-group name="null">
1405 <context context-type="linenumber">55</context> 1660 <context context-type="linenumber">48</context>
1406 </context-group> 1661 </context-group>
1407 </trans-unit> 1662 </trans-unit>
1408 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1663 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1409 <source>Videos Overview</source> 1664 <source>Videos Overview</source>
1410 <target>Vista general de los vídeos</target> 1665 <target>Vista general de los vídeos</target>
1411 <context-group name="null"> 1666 <context-group name="null">
1412 <context context-type="linenumber">58</context> 1667 <context context-type="linenumber">51</context>
1413 </context-group> 1668 </context-group>
1414 </trans-unit> 1669 </trans-unit>
1415 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1670 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1416 <source>Videos Trending</source> 1671 <source>Videos Trending</source>
1417 <target>Vídeos en Tendencia</target> 1672 <target>Vídeos en Tendencia</target>
1418 <context-group name="null"> 1673 <context-group name="null">
1419 <context context-type="linenumber">59</context> 1674 <context context-type="linenumber">52</context>
1420 </context-group> 1675 </context-group>
1421 </trans-unit> 1676 </trans-unit>
1422 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1677 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1423 <source>Videos Recently Added</source> 1678 <source>Videos Recently Added</source>
1424 <target>Vídeos Recientemente Añadidos</target> 1679 <target>Vídeos Recientemente Añadidos</target>
1425 <context-group name="null"> 1680 <context-group name="null">
1426 <context context-type="linenumber">60</context> 1681 <context context-type="linenumber">53</context>
1427 </context-group> 1682 </context-group>
1428 </trans-unit> 1683 </trans-unit>
1429 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1684 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1430 <source>Local videos</source> 1685 <source>Local videos</source>
1431 <target>Vídeos locales</target> 1686 <target>Vídeos locales</target>
1432 <context-group name="null"> 1687 <context-group name="null">
1433 <context context-type="linenumber">61</context> 1688 <context context-type="linenumber">54</context>
1434 </context-group> 1689 </context-group>
1435 </trans-unit> 1690 </trans-unit>
1436 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1691 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1437 <source>Policy on videos containing sensitive content</source> 1692 <source>Policy on videos containing sensitive content</source>
1438 <target>Política para los vídeos que contengan material sensible</target> 1693 <target>Política para los vídeos que contengan material sensible</target>
1439 <context-group name="null"> 1694 <context-group name="null">
1440 <context context-type="linenumber">70</context> 1695 <context context-type="linenumber">61</context>
1441 </context-group> 1696 </context-group>
1442 </trans-unit> 1697 </trans-unit>
1443 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1698 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1472,23 +1727,44 @@ Iniciar sesión</target>
1472 <source>Signup enabled</source> 1727 <source>Signup enabled</source>
1473 <target>Registro habilitado</target> 1728 <target>Registro habilitado</target>
1474 <context-group name="null"> 1729 <context-group name="null">
1475 <context context-type="linenumber">93</context> 1730 <context context-type="linenumber">84</context>
1476 </context-group> 1731 </context-group>
1477 </trans-unit> 1732 </trans-unit>
1478 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1733 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1479 <source>Signup requires email verification</source> 1734 <source>Signup requires email verification</source>
1480 <target>La suscripción requiere una verificación mediante correo electrónico</target> 1735 <target>La suscripción requiere una verificación mediante correo electrónico</target>
1481 <context-group name="null"> 1736 <context-group name="null">
1482 <context context-type="linenumber">100</context> 1737 <context context-type="linenumber">91</context>
1483 </context-group> 1738 </context-group>
1484 </trans-unit> 1739 </trans-unit>
1485 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1740 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1486 <source>Signup limit</source> 1741 <source>Signup limit</source>
1487 <target>Límite de registro</target> 1742 <target>Límite de registro</target>
1488 <context-group name="null"> 1743 <context-group name="null">
1744 <context context-type="linenumber">96</context>
1745 </context-group>
1746 </trans-unit>
1747 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1748 <source>Users</source>
1749 <target>Usuarios</target>
1750 <context-group name="null">
1489 <context context-type="linenumber">105</context> 1751 <context context-type="linenumber">105</context>
1490 </context-group> 1752 </context-group>
1491 </trans-unit> 1753 </trans-unit>
1754 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1755 <source>User default video quota</source>
1756 <target>Cuota de vídeo por defecto del usuario</target>
1757 <context-group name="null">
1758 <context context-type="linenumber">109</context>
1759 </context-group>
1760 </trans-unit>
1761 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1762 <source>User default daily upload limit</source>
1763 <target>Límite diario de subida por día por usuario</target>
1764 <context-group name="null">
1765 <context context-type="linenumber">121</context>
1766 </context-group>
1767 </trans-unit>
1492 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1768 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1493 <source>Import</source> 1769 <source>Import</source>
1494 <target>Importar</target> 1770 <target>Importar</target>
@@ -1500,49 +1776,35 @@ Iniciar sesión</target>
1500 <source>Video import with HTTP URL (i.e. YouTube) enabled</source> 1776 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1501 <target>La importación de vídeos mediante URL HTTP (por ejemplo YouTube) está activada</target> 1777 <target>La importación de vídeos mediante URL HTTP (por ejemplo YouTube) está activada</target>
1502 <context-group name="null"> 1778 <context-group name="null">
1503 <context context-type="linenumber">120</context> 1779 <context context-type="linenumber">141</context>
1504 </context-group> 1780 </context-group>
1505 </trans-unit> 1781 </trans-unit>
1506 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e"> 1782 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e">
1507 <source>Video import with a torrent file or a magnet URI enabled</source> 1783 <source>Video import with a torrent file or a magnet URI enabled</source>
1508 <target>Importar video con un archivo torrent o un enlace magnet activado</target> 1784 <target>Importar video con un archivo torrent o un enlace magnet activado</target>
1509 <context-group name="null"> 1785 <context-group name="null">
1510 <context context-type="linenumber">127</context> 1786 <context context-type="linenumber">148</context>
1511 </context-group> 1787 </context-group>
1512 </trans-unit> 1788 </trans-unit>
1513 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1789 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1514 <source>Administrator</source> 1790 <source>Administrator</source>
1515 <target>Administrador</target> 1791 <target>Administrador</target>
1516 <context-group name="null"> 1792 <context-group name="null">
1517 <context context-type="linenumber">131</context> 1793 <context context-type="linenumber">155</context>
1518 </context-group> 1794 </context-group>
1519 </trans-unit> 1795 </trans-unit>
1520 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1796 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1521 <source>Admin email</source> 1797 <source>Admin email</source>
1522 <target>Correo del administrador</target> 1798 <target>Correo del administrador</target>
1523 <context-group name="null"> 1799 <context-group name="null">
1524 <context context-type="linenumber">134</context> 1800 <context context-type="linenumber">158</context>
1525 </context-group>
1526 </trans-unit>
1527 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1528 <source>Users</source>
1529 <target>Usuarios</target>
1530 <context-group name="null">
1531 <context context-type="linenumber">144</context>
1532 </context-group> 1801 </context-group>
1533 </trans-unit> 1802 </trans-unit>
1534 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09"> 1803 <trans-unit id="f9bda6652199995a4bd4424f2e35b748eb0bda8a">
1535 <source>User default video quota</source> 1804 <source>Enable contact form</source>
1536 <target>Cuota de vídeo por defecto del usuario</target> 1805 <target>Habilitar el formulario de contacto</target>
1537 <context-group name="null"> 1806 <context-group name="null">
1538 <context context-type="linenumber">147</context> 1807 <context context-type="linenumber">169</context>
1539 </context-group>
1540 </trans-unit>
1541 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1542 <source>User default daily upload limit</source>
1543 <target>Límite diario de subida por día por usuario</target>
1544 <context-group name="null">
1545 <context context-type="linenumber">161</context>
1546 </context-group> 1808 </context-group>
1547 </trans-unit> 1809 </trans-unit>
1548 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1810 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1563,21 +1825,32 @@ Iniciar sesión</target>
1563 <source>Your Twitter username</source> 1825 <source>Your Twitter username</source>
1564 <target>Tu usuario de Twitter</target> 1826 <target>Tu usuario de Twitter</target>
1565 <context-group name="null"> 1827 <context-group name="null">
1566 <context context-type="linenumber">181</context> 1828 <context context-type="linenumber">184</context>
1567 </context-group> 1829 </context-group>
1568 </trans-unit> 1830 </trans-unit>
1569 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1831 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1570 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1832 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1571 <target>Indica la cuenta de Twitter del sitio web o de la plataforma en la que el contenido fue publicado</target> 1833 <target>Indica la cuenta de Twitter del sitio web o de la plataforma en la que el contenido fue publicado</target>
1572 <context-group name="null"> 1834 <context-group name="null">
1573 <context context-type="linenumber">184</context> 1835 <context context-type="linenumber">187</context>
1574 </context-group> 1836 </context-group>
1575 </trans-unit> 1837 </trans-unit>
1576 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1838 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1577 <source>Instance whitelisted by Twitter</source> 1839 <source>Instance whitelisted by Twitter</source>
1578 <target>Nodo en lista blanca de Twitter</target> 1840 <target>Nodo en lista blanca de Twitter</target>
1579 <context-group name="null"> 1841 <context-group name="null">
1580 <context context-type="linenumber">198</context> 1842 <context context-type="linenumber">199</context>
1843 </context-group>
1844 </trans-unit>
1845 <trans-unit id="f1276a50033dfc7a71290086d0f57d89e3438e6b">
1846 <source>If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.&lt;br /&gt;
1847 If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.&lt;br /&gt;&lt;br /&gt;
1848 Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on &lt;a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'&gt;https://cards-dev.twitter.com/validator&lt;/a&gt; to see if you instance is whitelisted.</source>
1849 <target>Si su instancia está autorizada por Twitter, un reproductor de vídeo estará incorporado al hilo Twitter cuando se comparta un vídeo desde PeerTube.&lt;br /&gt;
1850 Si la instancia no está autorizada, usamos una tarjeta con una imagen con vínculo que redireccionará hacia su instancia PeerTube.&lt;br /&gt;&lt;br /&gt;
1851 Seleccione esta casilla, guarde la configuración y pruebe colocando el URL de un vídeo de su instancia (https://example.com/videos/watch/blabla) en &lt;a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'&gt;https://cards-dev.twitter.com/validator&lt;/a&gt; para verificar si su instancia está autorizada por Twitter.</target>
1852 <context-group name="null">
1853 <context context-type="linenumber">200</context>
1581 </context-group> 1854 </context-group>
1582 </trans-unit> 1855 </trans-unit>
1583 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1856 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1591,98 +1864,162 @@ Iniciar sesión</target>
1591 <source>Transcoding</source> 1864 <source>Transcoding</source>
1592 <target>Transcodificar</target> 1865 <target>Transcodificar</target>
1593 <context-group name="null"> 1866 <context-group name="null">
1594 <context context-type="linenumber">210</context> 1867 <context context-type="linenumber">215</context>
1595 </context-group> 1868 </context-group>
1596 </trans-unit> 1869 </trans-unit>
1597 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1870 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1598 <source>Transcoding enabled</source> 1871 <source>Transcoding enabled</source>
1599 <target>Transcodificación activada</target> 1872 <target>Transcodificación activada</target>
1600 <context-group name="null"> 1873 <context-group name="null">
1601 <context context-type="linenumber">215</context> 1874 <context context-type="linenumber">221</context>
1602 </context-group> 1875 </context-group>
1603 </trans-unit> 1876 </trans-unit>
1604 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1877 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1605 <source>If you disable transcoding, many videos from your users will not work!</source> 1878 <source>If you disable transcoding, many videos from your users will not work!</source>
1606 <target>¡Si desactivas la transcodificación, muchos vídeos de tus usuarios no funcionarán!</target> 1879 <target>¡Si desactivas la transcodificación, muchos vídeos de tus usuarios no funcionarán!</target>
1607 <context-group name="null"> 1880 <context-group name="null">
1608 <context context-type="linenumber">216</context> 1881 <context context-type="linenumber">222</context>
1882 </context-group>
1883 </trans-unit>
1884 <trans-unit id="0050a55afb9c565df1f9b3f750c2d4adb697698f">
1885 <source>Allow additional extensions</source>
1886 <target>Autorizar extensiones adicionales</target>
1887 <context-group name="null">
1888 <context context-type="linenumber">231</context>
1889 </context-group>
1890 </trans-unit>
1891 <trans-unit id="9b82c3a407ee5a98c92483fbd987be8db8384c33">
1892 <source>Allow your users to upload .mkv, .mov, .avi, .flv videos</source>
1893 <target>Autorizar sus usuarios a subir vídeos .mkv, .mov, .avi y .flv</target>
1894 <context-group name="null">
1895 <context context-type="linenumber">232</context>
1609 </context-group> 1896 </context-group>
1610 </trans-unit> 1897 </trans-unit>
1611 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1898 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1612 <source>Transcoding threads</source> 1899 <source>Transcoding threads</source>
1613 <target>Hilos de transcodificaciones</target> 1900 <target>Hilos de transcodificaciones</target>
1614 <context-group name="null"> 1901 <context-group name="null">
1615 <context context-type="linenumber">223</context> 1902 <context context-type="linenumber">237</context>
1616 </context-group> 1903 </context-group>
1617 </trans-unit> 1904 </trans-unit>
1618 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1905 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1619 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1906 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1620 <target>Resolución <x id="INTERPOLATION" equiv-text="{{resolution}}"/> activada</target> 1907 <target>Resolución <x id="INTERPOLATION" equiv-text="{{resolution}}"/> activada</target>
1621 <context-group name="null"> 1908 <context-group name="null">
1622 <context context-type="linenumber">239</context> 1909 <context context-type="linenumber">252</context>
1910 </context-group>
1911 </trans-unit>
1912 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
1913 <source>
1914 Cache
1915
1916 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1917 </source>
1918 <target>
1919 Caché
1920
1921 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1922 </target>
1923 <context-group name="null">
1924 <context context-type="linenumber">260</context>
1623 </context-group> 1925 </context-group>
1624 </trans-unit> 1926 </trans-unit>
1625 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1927 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1626 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1928 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1627 <target>Algunos archivos (previsualizaciones, subtítulos) no están federados. Los obtenemos directamente del nodo de origen y las ponemos en caché.</target> 1929 <target>Algunos archivos (previsualizaciones, subtítulos) no están federados. Los obtenemos directamente del nodo de origen y las ponemos en caché.</target>
1628 <context-group name="null"> 1930 <context-group name="null">
1629 <context context-type="linenumber">249</context> 1931 <context context-type="linenumber">265</context>
1630 </context-group> 1932 </context-group>
1631 </trans-unit> 1933 </trans-unit>
1632 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1934 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1633 <source>Previews cache size</source> 1935 <source>Previews cache size</source>
1634 <target>Tamaño de caché de las previsualizaciones</target> 1936 <target>Tamaño de caché de las previsualizaciones</target>
1635 <context-group name="null"> 1937 <context-group name="null">
1636 <context context-type="linenumber">254</context> 1938 <context context-type="linenumber">271</context>
1637 </context-group> 1939 </context-group>
1638 </trans-unit> 1940 </trans-unit>
1639 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1941 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1640 <source>Video captions cache size</source> 1942 <source>Video captions cache size</source>
1641 <target>Tamaño de caché de los subtítulos</target> 1943 <target>Tamaño de caché de los subtítulos</target>
1642 <context-group name="null"> 1944 <context-group name="null">
1643 <context context-type="linenumber">265</context> 1945 <context context-type="linenumber">280</context>
1644 </context-group> 1946 </context-group>
1645 </trans-unit> 1947 </trans-unit>
1646 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1948 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1647 <source>Customizations</source> 1949 <source>Customizations</source>
1648 <target>Personalizaciones</target> 1950 <target>Personalizaciones</target>
1649 <context-group name="null"> 1951 <context-group name="null">
1650 <context context-type="linenumber">275</context> 1952 <context context-type="linenumber">289</context>
1651 </context-group> 1953 </context-group>
1652 </trans-unit> 1954 </trans-unit>
1653 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1955 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1654 <source>JavaScript</source> 1956 <source>JavaScript</source>
1655 <target>JavaScript</target> 1957 <target>JavaScript</target>
1656 <context-group name="null"> 1958 <context-group name="null">
1657 <context context-type="linenumber">278</context> 1959 <context context-type="linenumber">294</context>
1658 </context-group> 1960 </context-group>
1659 </trans-unit> 1961 </trans-unit>
1660 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1962 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1661 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1963 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1662 <target>Escribir código Javascript directamente.&lt;br /&gt;Ejemplo: &lt;pre&gt;console.log('mi nodo es maravilloso');&lt;/pre&gt;</target> 1964 <target>Escribir código Javascript directamente.&lt;br /&gt;Ejemplo: &lt;pre&gt;console.log('mi nodo es maravilloso');&lt;/pre&gt;</target>
1663 <context-group name="null"> 1965 <context-group name="null">
1664 <context context-type="linenumber">281</context> 1966 <context context-type="linenumber">297</context>
1967 </context-group>
1968 </trans-unit>
1969 <trans-unit id="d7caa08cd9b3119881bbaec3f5a3c5707f573dde">
1970 <source>
1971 Write directly CSS code. Example:&lt;br /&gt;
1972 &lt;pre&gt;
1973 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1974 background-color: red;
1975 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1976 &lt;/pre&gt;
1977
1978 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1979 &lt;pre&gt;
1980 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1981 color: red;
1982 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1983 &lt;/pre&gt;
1984 </source>
1985 <target>
1986 Escriba directamente código CSS. Por ejemplo:&lt;br /&gt;
1987 &lt;pre&gt;
1988 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1989 background-color: red;
1990 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1991 &lt;/pre&gt;
1992
1993 Prefijar con &lt;em&gt;#custom-css&lt;/em&gt; para sobrecargar estilos. Por ejemplo:
1994 &lt;pre&gt;
1995 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1996 color: red;
1997 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1998 &lt;/pre&gt;
1999 </target>
2000 <context-group name="null">
2001 <context context-type="linenumber">311</context>
1665 </context-group> 2002 </context-group>
1666 </trans-unit> 2003 </trans-unit>
1667 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab"> 2004 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab">
1668 <source>Advanced configuration</source> 2005 <source>Advanced configuration</source>
1669 <target>Configuración avanzada</target> 2006 <target>Configuración avanzada</target>
1670 <context-group name="null"> 2007 <context-group name="null">
1671 <context context-type="linenumber">207</context> 2008 <context context-type="linenumber">212</context>
1672 </context-group> 2009 </context-group>
1673 </trans-unit> 2010 </trans-unit>
1674 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 2011 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1675 <source>Update configuration</source> 2012 <source>Update configuration</source>
1676 <target>Actualizar configuración</target> 2013 <target>Actualizar configuración</target>
1677 <context-group name="null"> 2014 <context-group name="null">
1678 <context context-type="linenumber">325</context> 2015 <context context-type="linenumber">340</context>
1679 </context-group> 2016 </context-group>
1680 </trans-unit> 2017 </trans-unit>
1681 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 2018 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1682 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 2019 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1683 <target>Parece que la configuración no es válida. Por favor, busque errores potenciales en las diferentes pestañas.</target> 2020 <target>Parece que la configuración no es válida. Por favor, busque errores potenciales en las diferentes pestañas.</target>
1684 <context-group name="null"> 2021 <context-group name="null">
1685 <context context-type="linenumber">326</context> 2022 <context context-type="linenumber">341</context>
1686 </context-group> 2023 </context-group>
1687 </trans-unit> 2024 </trans-unit>
1688 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 2025 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1707,6 +2044,17 @@ Iniciar sesión</target>
1707 <context context-type="linenumber">7</context> 2044 <context context-type="linenumber">7</context>
1708 </context-group> 2045 </context-group>
1709 </trans-unit> 2046 </trans-unit>
2047 <trans-unit id="1a5c7f9b1bec1463728f44933f0e256de9c45154">
2048 <source>
2049 Moderation
2050 </source>
2051 <target>
2052 Moderación
2053 </target>
2054 <context-group name="null">
2055 <context context-type="linenumber">11</context>
2056 </context-group>
2057 </trans-unit>
1710 <trans-unit id="7bea88c54fdccfdc9f687b0ffe9bf6a653d19368"> 2058 <trans-unit id="7bea88c54fdccfdc9f687b0ffe9bf6a653d19368">
1711 <source> 2059 <source>
1712 Jobs 2060 Jobs
@@ -1754,6 +2102,13 @@ Iniciar sesión</target>
1754 <context context-type="linenumber">21</context> 2102 <context context-type="linenumber">21</context>
1755 </context-group> 2103 </context-group>
1756 </trans-unit> 2104 </trans-unit>
2105 <trans-unit id="25925fc5826bc5b3eeae7c45b08b0ed74b9e2954">
2106 <source>Filter...</source>
2107 <target>Filtrar...</target>
2108 <context-group name="null">
2109 <context context-type="linenumber">27</context>
2110 </context-group>
2111 </trans-unit>
1757 <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c"> 2112 <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c">
1758 <source>ID</source> 2113 <source>ID</source>
1759 <target>ID</target> 2114 <target>ID</target>
@@ -1789,6 +2144,27 @@ Iniciar sesión</target>
1789 <context context-type="linenumber">11</context> 2144 <context context-type="linenumber">11</context>
1790 </context-group> 2145 </context-group>
1791 </trans-unit> 2146 </trans-unit>
2147 <trans-unit id="7823909fb1d8d313382f6f4bd842f1a7ef6f08d1">
2148 <source>Accepted</source>
2149 <target>Aceptado</target>
2150 <context-group name="null">
2151 <context context-type="linenumber">32</context>
2152 </context-group>
2153 </trans-unit>
2154 <trans-unit id="e6a27066251ca1e04c5be86ad758380856df2506">
2155 <source>Pending</source>
2156 <target>Pendiente</target>
2157 <context-group name="null">
2158 <context context-type="linenumber">33</context>
2159 </context-group>
2160 </trans-unit>
2161 <trans-unit id="1d729bcbe3529d2fe2295b7a3a41282ee09de2c8">
2162 <source>Redundancy allowed</source>
2163 <target>Redundancia autorizada</target>
2164 <context-group name="null">
2165 <context context-type="linenumber">22</context>
2166 </context-group>
2167 </trans-unit>
1792 <trans-unit id="5fccee488a9ea908c16d2ab9dbdaf264f1aac479"> 2168 <trans-unit id="5fccee488a9ea908c16d2ab9dbdaf264f1aac479">
1793 <source>Manage follows</source> 2169 <source>Manage follows</source>
1794 <target>Gestionar seguimientos</target> 2170 <target>Gestionar seguimientos</target>
@@ -1893,6 +2269,13 @@ Iniciar sesión</target>
1893 <context context-type="linenumber">65</context> 2269 <context context-type="linenumber">65</context>
1894 </context-group> 2270 </context-group>
1895 </trans-unit> 2271 </trans-unit>
2272 <trans-unit id="6ded52553dd8720fd3698b8fbc3a6d037c07b496">
2273 <source>Daily video quota</source>
2274 <target>Cuota diaria de vídeo</target>
2275 <context-group name="null">
2276 <context context-type="linenumber">72</context>
2277 </context-group>
2278 </trans-unit>
1896 <trans-unit id="5e8b4663c17c337a1f11160c0a683350936faa1f"> 2279 <trans-unit id="5e8b4663c17c337a1f11160c0a683350936faa1f">
1897 <source>Users list</source> 2280 <source>Users list</source>
1898 <target>Lista de usuarios</target> 2281 <target>Lista de usuarios</target>
@@ -1900,6 +2283,13 @@ Iniciar sesión</target>
1900 <context context-type="linenumber">2</context> 2283 <context context-type="linenumber">2</context>
1901 </context-group> 2284 </context-group>
1902 </trans-unit> 2285 </trans-unit>
2286 <trans-unit id="ea762ca1d74c96d8568ac68482778f52ca531cc4">
2287 <source>Batch actions</source>
2288 <target>Acciones másivas</target>
2289 <context-group name="null">
2290 <context context-type="linenumber">19</context>
2291 </context-group>
2292 </trans-unit>
1903 <trans-unit id="08ea8692dc2a7050026df26fc39b22960bde9de5"> 2293 <trans-unit id="08ea8692dc2a7050026df26fc39b22960bde9de5">
1904 <source>Username <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 2294 <source>Username <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
1905 <target>Nombre de usuario <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 2295 <target>Nombre de usuario <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
@@ -1907,6 +2297,13 @@ Iniciar sesión</target>
1907 <context context-type="linenumber">40</context> 2297 <context context-type="linenumber">40</context>
1908 </context-group> 2298 </context-group>
1909 </trans-unit> 2299 </trans-unit>
2300 <trans-unit id="adba7c8b43e42581460fbe5d08b5cb5ab60eba4b">
2301 <source>(banned)</source>
2302 <target>(expulsado)</target>
2303 <context-group name="null">
2304 <context context-type="linenumber">65</context>
2305 </context-group>
2306 </trans-unit>
1910 <trans-unit id="be73b652c2707f42b5d780d0c7b8fc5ea0b1706c"> 2307 <trans-unit id="be73b652c2707f42b5d780d0c7b8fc5ea0b1706c">
1911 <source>Go to the account page</source> 2308 <source>Go to the account page</source>
1912 <target>Ir a la página de la cuenta</target> 2309 <target>Ir a la página de la cuenta</target>
@@ -1914,6 +2311,52 @@ Iniciar sesión</target>
1914 <context context-type="linenumber">133</context> 2311 <context context-type="linenumber">133</context>
1915 </context-group> 2312 </context-group>
1916 </trans-unit> 2313 </trans-unit>
2314 <trans-unit id="02ba1a65db92d1d0ab4ba380086e9be61891aaa5">
2315 <source>User's email must be verified to login</source>
2316 <target>Se requiere validar la dirección de correo electrónico del usuario antes de conectarse</target>
2317 <context-group name="null">
2318 <context context-type="linenumber">72</context>
2319 </context-group>
2320 </trans-unit>
2321 <trans-unit id="79cee9973620b2592ff2824c525aa8ed0b5e2b8b">
2322 <source>User's email is verified / User can login without email verification</source>
2323 <target>La dirección de correo electrónico del usuario ha sido verificada / El usuario puede conectarse sin verificación de dirección de correo electrónico</target>
2324 <context-group name="null">
2325 <context context-type="linenumber">76</context>
2326 </context-group>
2327 </trans-unit>
2328 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee">
2329 <source>Ban reason:</source>
2330 <target>Razón de la expulsión:</target>
2331 <context-group name="null">
2332 <context context-type="linenumber">95</context>
2333 </context-group>
2334 </trans-unit>
2335 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
2336 <source>Moderation comment</source>
2337 <target>Comentarios de moderación</target>
2338 <context-group name="null">
2339 <context context-type="linenumber">3</context>
2340 </context-group>
2341 </trans-unit>
2342 <trans-unit id="5731e5d5ac989bf08848b5a57a5586cf84d80964">
2343 <source>
2344 This comment can only be seen by you or the other moderators.
2345 </source>
2346 <target>
2347 Este comentario puede ser visto solo por usted y los otros moderadores.
2348 </target>
2349 <context-group name="null">
2350 <context context-type="linenumber">17</context>
2351 </context-group>
2352 </trans-unit>
2353 <trans-unit id="0562e455c88234829f3c27a38f3039f027bfd5d2">
2354 <source>Update this comment</source>
2355 <target>Actualizar este comentario</target>
2356 <context-group name="null">
2357 <context context-type="linenumber">25</context>
2358 </context-group>
2359 </trans-unit>
1917 <trans-unit id="2bf5a31043ff476ca081a4080f3f3f17518dc6f2"> 2360 <trans-unit id="2bf5a31043ff476ca081a4080f3f3f17518dc6f2">
1918 <source>Reporter</source> 2361 <source>Reporter</source>
1919 <target>Reportador</target> 2362 <target>Reportador</target>
@@ -1928,6 +2371,13 @@ Iniciar sesión</target>
1928 <context context-type="linenumber">14</context> 2371 <context context-type="linenumber">14</context>
1929 </context-group> 2372 </context-group>
1930 </trans-unit> 2373 </trans-unit>
2374 <trans-unit id="7e7ad19f1bcc2c33cdba4c1ad25e2b398ad453d9">
2375 <source>State <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2376 <target>Estado <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2377 <context-group name="null">
2378 <context context-type="linenumber">11</context>
2379 </context-group>
2380 </trans-unit>
1931 <trans-unit id="c6ab75e099e131d7a4f94e1732e7436d8fc386c7"> 2381 <trans-unit id="c6ab75e099e131d7a4f94e1732e7436d8fc386c7">
1932 <source>Go to the account</source> 2382 <source>Go to the account</source>
1933 <target>Ir a la cuenta</target> 2383 <target>Ir a la cuenta</target>
@@ -1942,6 +2392,69 @@ Iniciar sesión</target>
1942 <context context-type="linenumber">33</context> 2392 <context context-type="linenumber">33</context>
1943 </context-group> 2393 </context-group>
1944 </trans-unit> 2394 </trans-unit>
2395 <trans-unit id="030b4423b92167200e39519599f9b863b4f7c62c">
2396 <source>Actions</source>
2397 <target>Acciones</target>
2398 <context-group name="null">
2399 <context context-type="linenumber">35</context>
2400 </context-group>
2401 </trans-unit>
2402 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
2403 <source>Reason:</source>
2404 <target>Razón:</target>
2405 <context-group name="null">
2406 <context context-type="linenumber">53</context>
2407 </context-group>
2408 </trans-unit>
2409 <trans-unit id="018cbb63c7eda4b82d17dd9058cfaa0fd055c638">
2410 <source>Moderation comment:</source>
2411 <target>Comentario de moderación:</target>
2412 <context-group name="null">
2413 <context context-type="linenumber">57</context>
2414 </context-group>
2415 </trans-unit>
2416 <trans-unit id="b14fd2fc28c5eecd05554d2bcbc3a938c599e2bf">
2417 <source>Video name <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2418 <target>Nombre del vídeo <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2419 <context-group name="null">
2420 <context context-type="linenumber">8</context>
2421 </context-group>
2422 </trans-unit>
2423 <trans-unit id="96dfa3efa02bfafc0bc6d4ab186ebef2813a9e8a">
2424 <source>Sensitive</source>
2425 <target>Sensible</target>
2426 <context-group name="null">
2427 <context context-type="linenumber">9</context>
2428 </context-group>
2429 </trans-unit>
2430 <trans-unit id="a7f42da3bb4eea0b71b0a20a2aff6612a82cab99">
2431 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2432 <target>Fecha <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2433 <context-group name="null">
2434 <context context-type="linenumber">11</context>
2435 </context-group>
2436 </trans-unit>
2437 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
2438 <source>Blacklist reason:</source>
2439 <target>Razón del bloqueo:</target>
2440 <context-group name="null">
2441 <context context-type="linenumber">43</context>
2442 </context-group>
2443 </trans-unit>
2444 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
2445 <source>Moderation</source>
2446 <target>Moderación</target>
2447 <context-group name="null">
2448 <context context-type="linenumber">2</context>
2449 </context-group>
2450 </trans-unit>
2451 <trans-unit id="23a793ed0df2e10823dd469c5cea9b5c36be8f7e">
2452 <source>Video abuses</source>
2453 <target>Vídeos denunciados como abusivos</target>
2454 <context-group name="null">
2455 <context context-type="linenumber">5</context>
2456 </context-group>
2457 </trans-unit>
1945 <trans-unit id="00ecde6001106fe7406a34cc3459cc5b88e4aec1"> 2458 <trans-unit id="00ecde6001106fe7406a34cc3459cc5b88e4aec1">
1946 <source>Blacklisted videos</source> 2459 <source>Blacklisted videos</source>
1947 <target>Vídeos en lista negra</target> 2460 <target>Vídeos en lista negra</target>
@@ -1949,18 +2462,39 @@ Iniciar sesión</target>
1949 <context context-type="linenumber">7</context> 2462 <context context-type="linenumber">7</context>
1950 </context-group> 2463 </context-group>
1951 </trans-unit> 2464 </trans-unit>
1952 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6"> 2465 <trans-unit id="b1ff109b26ae8f08650415454b9098c43eba2e2c">
1953 <source>My settings</source> 2466 <source>Muted accounts</source>
1954 <target>Mis ajustes</target> 2467 <target>Cuentas silenciadas</target>
1955 <context-group name="null"> 2468 <context-group name="null">
1956 <context context-type="linenumber">3</context> 2469 <context context-type="linenumber">2</context>
1957 </context-group> 2470 </context-group>
1958 </trans-unit> 2471 </trans-unit>
1959 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894"> 2472 <trans-unit id="bd0611346af048015e0a1275091ef68ce98832d2">
1960 <source>My videos</source> 2473 <source>Muted servers</source>
1961 <target>Mis vídeos</target> 2474 <target>Servidores silenciados</target>
1962 <context-group name="null"> 2475 <context-group name="null">
1963 <context context-type="linenumber">14</context> 2476 <context context-type="linenumber">11</context>
2477 </context-group>
2478 </trans-unit>
2479 <trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92">
2480 <source>Account</source>
2481 <target>Cuenta</target>
2482 <context-group name="null">
2483 <context context-type="linenumber">12</context>
2484 </context-group>
2485 </trans-unit>
2486 <trans-unit id="079e99cce11c87b142e80fdd14dae98a61012fc4">
2487 <source>Muted at <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2488 <target>Silenciado en <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2489 <context-group name="null">
2490 <context context-type="linenumber">13</context>
2491 </context-group>
2492 </trans-unit>
2493 <trans-unit id="1f689fada9748a830117f5b429a88ef8629082a8">
2494 <source>Unmute</source>
2495 <target>Dejar de silenciar</target>
2496 <context-group name="null">
2497 <context context-type="linenumber">23</context>
1964 </context-group> 2498 </context-group>
1965 </trans-unit> 2499 </trans-unit>
1966 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 2500 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
@@ -1974,28 +2508,46 @@ Iniciar sesión</target>
1974 <source>Profile</source> 2508 <source>Profile</source>
1975 <target>Perfil</target> 2509 <target>Perfil</target>
1976 <context-group name="null"> 2510 <context-group name="null">
1977 <context context-type="linenumber">8</context> 2511 <context context-type="linenumber">7</context>
1978 </context-group> 2512 </context-group>
1979 </trans-unit> 2513 </trans-unit>
1980 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 2514 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
1981 <source>Video settings</source> 2515 <source>Video settings</source>
1982 <target>Ajustes de vídeo</target> 2516 <target>Ajustes de vídeo</target>
1983 <context-group name="null"> 2517 <context-group name="null">
1984 <context context-type="linenumber">15</context> 2518 <context context-type="linenumber">16</context>
1985 </context-group> 2519 </context-group>
1986 </trans-unit> 2520 </trans-unit>
1987 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 2521 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
1988 <source>Danger zone</source> 2522 <source>Danger zone</source>
1989 <target>Zona peligrosa</target> 2523 <target>Zona peligrosa</target>
1990 <context-group name="null"> 2524 <context-group name="null">
1991 <context context-type="linenumber">18</context> 2525 <context context-type="linenumber">19</context>
1992 </context-group> 2526 </context-group>
1993 </trans-unit> 2527 </trans-unit>
1994 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd"> 2528 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
1995 <source>Submit</source> 2529 <source>Change ownership</source>
1996 <target>Enviar</target> 2530 <target>Cambiar el titular</target>
1997 <context-group name="null"> 2531 <context-group name="null">
1998 <context context-type="linenumber">24</context> 2532 <context context-type="linenumber">46</context>
2533 </context-group>
2534 </trans-unit>
2535 <trans-unit id="046c4fa30411e6b1aa46dc51bf82d07b1adf14d4">
2536 <source>Select the next owner</source>
2537 <target>Seleccionar el próxima titular</target>
2538 <context-group name="null">
2539 <context context-type="linenumber">9</context>
2540 </context-group>
2541 </trans-unit>
2542 <trans-unit id="a5433ae2324496bea9537caa5e8a2719d8e958d8">
2543 <source>
2544 Cancel
2545 </source>
2546 <target>
2547 Cancelar
2548 </target>
2549 <context-group name="null">
2550 <context context-type="linenumber">35</context>
1999 </context-group> 2551 </context-group>
2000 </trans-unit> 2552 </trans-unit>
2001 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 2553 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
@@ -2005,6 +2557,13 @@ Iniciar sesión</target>
2005 <context context-type="linenumber">19</context> 2557 <context context-type="linenumber">19</context>
2006 </context-group> 2558 </context-group>
2007 </trans-unit> 2559 </trans-unit>
2560 <trans-unit id="4a806761798181e907e28ed1af053d466526800d">
2561 <source>Blacklisted</source>
2562 <target>Bloqueado</target>
2563 <context-group name="null">
2564 <context context-type="linenumber">22</context>
2565 </context-group>
2566 </trans-unit>
2008 <trans-unit id="17a9d3860d9ad593dd09a9f934e03999d9e76a7a"> 2567 <trans-unit id="17a9d3860d9ad593dd09a9f934e03999d9e76a7a">
2009 <source> 2568 <source>
2010 Cancel 2569 Cancel
@@ -2036,6 +2595,13 @@ Cancelar</target>
2036 <context context-type="linenumber">6</context> 2595 <context context-type="linenumber">6</context>
2037 </context-group> 2596 </context-group>
2038 </trans-unit> 2597 </trans-unit>
2598 <trans-unit id="915d4704e1649016512cbf5eeac55b4dbf933558">
2599 <source>Example: my_channel</source>
2600 <target>Por ejemplo: mi_canal</target>
2601 <context-group name="null">
2602 <context context-type="linenumber">15</context>
2603 </context-group>
2604 </trans-unit>
2039 <trans-unit id="bc155f9fc3be3f32083f19b2c77d4ad3b696d9b9"> 2605 <trans-unit id="bc155f9fc3be3f32083f19b2c77d4ad3b696d9b9">
2040 <source>Display name</source> 2606 <source>Display name</source>
2041 <target>Nombre a mostrar</target> 2607 <target>Nombre a mostrar</target>
@@ -2059,6 +2625,13 @@ Cuando subas un vídeo a este canal, el campo de soporte del vídeo se rellenarÃ
2059 <context context-type="linenumber">8</context> 2625 <context context-type="linenumber">8</context>
2060 </context-group> 2626 </context-group>
2061 </trans-unit> 2627 </trans-unit>
2628 <trans-unit id="3a5d57052d13d2da1cbcffdbb8effb9874b1595a">
2629 <source>You don't have any subscriptions yet.</source>
2630 <target>No tiene suscripciones todavía.</target>
2631 <context-group name="null">
2632 <context context-type="linenumber">1</context>
2633 </context-group>
2634 </trans-unit>
2062 <trans-unit id="c65641c36859c328928e6b0f14c3f913886f8add"> 2635 <trans-unit id="c65641c36859c328928e6b0f14c3f913886f8add">
2063 <source>Created by <x id="INTERPOLATION" equiv-text="{{ videoChannel.ownerBy }}"/></source> 2636 <source>Created by <x id="INTERPOLATION" equiv-text="{{ videoChannel.ownerBy }}"/></source>
2064 <target>Creado por <x id="INTERPOLATION" equiv-text="{{ videoChannel.ownerBy }}"/></target> 2637 <target>Creado por <x id="INTERPOLATION" equiv-text="{{ videoChannel.ownerBy }}"/></target>
@@ -2073,6 +2646,117 @@ Cuando subas un vídeo a este canal, el campo de soporte del vídeo se rellenarÃ
2073 <context context-type="linenumber">16</context> 2646 <context context-type="linenumber">16</context>
2074 </context-group> 2647 </context-group>
2075 </trans-unit> 2648 </trans-unit>
2649 <trans-unit id="fbc450919a486e8ed311a7e91a41987d47d83804">
2650 <source>Accept ownership</source>
2651 <target>Aceptar la titularidad</target>
2652 <context-group name="null">
2653 <context context-type="linenumber">3</context>
2654 </context-group>
2655 </trans-unit>
2656 <trans-unit id="4570c754149df06f31096510abfc925968c35562">
2657 <source>Select the target channel</source>
2658 <target>Seleccionar el canal objetivo</target>
2659 <context-group name="null">
2660 <context context-type="linenumber">9</context>
2661 </context-group>
2662 </trans-unit>
2663 <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740">
2664 <source>Initiator</source>
2665 <target>Iniciador</target>
2666 <context-group name="null">
2667 <context context-type="linenumber">13</context>
2668 </context-group>
2669 </trans-unit>
2670 <trans-unit id="b08d67fe4e192ea8352bebdc6aabbd1bb7abed02">
2671 <source>
2672 Created
2673 <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/>
2674 </source>
2675 <target>
2676 Creado
2677 <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/>
2678 </target>
2679 <context-group name="null">
2680 <context context-type="linenumber">15</context>
2681 </context-group>
2682 </trans-unit>
2683 <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1">
2684 <source>Status</source>
2685 <target>Estatus</target>
2686 <context-group name="null">
2687 <context context-type="linenumber">19</context>
2688 </context-group>
2689 </trans-unit>
2690 <trans-unit id="1bd5e17c9582661e20763a7634ef07881e33bbd7">
2691 <source>Action</source>
2692 <target>Acción</target>
2693 <context-group name="null">
2694 <context context-type="linenumber">20</context>
2695 </context-group>
2696 </trans-unit>
2697 <trans-unit id="f4212e793d36e1aaa6ee1b09881677f783b5feff">
2698 <source><x id="INTERPOLATION" equiv-text="{{ videoChangeOwnership.status }}"/></source>
2699 <target><x id="INTERPOLATION" equiv-text="{{ videoChangeOwnership.status }}"/></target>
2700 <context-group name="null">
2701 <context context-type="linenumber">39</context>
2702 </context-group>
2703 </trans-unit>
2704 <trans-unit id="4a5613f6b472c1ed863dff1be932913a251f27a2">
2705 <source>Refuse</source>
2706 <target>Rechazar</target>
2707 <context-group name="null">
2708 <context context-type="linenumber">47</context>
2709 </context-group>
2710 </trans-unit>
2711 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2712 <source>Muted instances</source>
2713 <target>Instancias silenciadas</target>
2714 <context-group name="null">
2715 <context context-type="linenumber">2</context>
2716 </context-group>
2717 </trans-unit>
2718 <trans-unit id="e8e93a7ae9a47c035bf5170b105c418b1deae530">
2719 <source>History enabled</source>
2720 <target>Historial habilitado</target>
2721 <context-group name="null">
2722 <context context-type="linenumber">4</context>
2723 </context-group>
2724 </trans-unit>
2725 <trans-unit id="0f1fd6758625c6a39d796378d362cdcc2b092123">
2726 <source>Delete history</source>
2727 <target>Borrar el historial</target>
2728 <context-group name="null">
2729 <context context-type="linenumber">8</context>
2730 </context-group>
2731 </trans-unit>
2732 <trans-unit id="6b4dc5732f1f2211833d4b5e76deb5985f3749af">
2733 <source>You don't have videos history yet.</source>
2734 <target>No tiene historial de vídeos todavía</target>
2735 <context-group name="null">
2736 <context context-type="linenumber">13</context>
2737 </context-group>
2738 </trans-unit>
2739 <trans-unit id="6aec8cb024acc333218d72f279caa8ea623bb628">
2740 <source><x id="INTERPOLATION" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2741 <target><x id="INTERPOLATION" equiv-text="{{ video.views | myNumberFormatter }}"/> vistas</target>
2742 <context-group name="null">
2743 <context context-type="linenumber">22</context>
2744 </context-group>
2745 </trans-unit>
2746 <trans-unit id="3a6903ba6b8cf2d828d0c86fd1feb09a27be4105">
2747 <source>Notification preferences</source>
2748 <target>Preferencias de notificación</target>
2749 <context-group name="null">
2750 <context context-type="linenumber">2</context>
2751 </context-group>
2752 </trans-unit>
2753 <trans-unit id="1da23f4068fd3796fbcb24d0c42bb62f92c96829">
2754 <source>Mark all as read</source>
2755 <target>Marcar todo como leído</target>
2756 <context-group name="null">
2757 <context context-type="linenumber">4</context>
2758 </context-group>
2759 </trans-unit>
2076 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 2760 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
2077 <source>Change password</source> 2761 <source>Change password</source>
2078 <target>Cambiar contraseña</target> 2762 <target>Cambiar contraseña</target>
@@ -2080,6 +2764,13 @@ Cuando subas un vídeo a este canal, el campo de soporte del vídeo se rellenarÃ
2080 <context context-type="linenumber">30</context> 2764 <context context-type="linenumber">30</context>
2081 </context-group> 2765 </context-group>
2082 </trans-unit> 2766 </trans-unit>
2767 <trans-unit id="0dd390d056411e1709ec97ec51c46d78600e3f7b">
2768 <source>Current password</source>
2769 <target>Contraseña actual</target>
2770 <context-group name="null">
2771 <context context-type="linenumber">7</context>
2772 </context-group>
2773 </trans-unit>
2083 <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229"> 2774 <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229">
2084 <source>New password</source> 2775 <source>New password</source>
2085 <target>Nueva contraseña</target> 2776 <target>Nueva contraseña</target>
@@ -2101,6 +2792,13 @@ Cuando subas un vídeo a este canal, el campo de soporte del vídeo se rellenarÃ
2101 <context context-type="linenumber">3</context> 2792 <context context-type="linenumber">3</context>
2102 </context-group> 2793 </context-group>
2103 </trans-unit> 2794 </trans-unit>
2795 <trans-unit id="d044c51156e295824813a866dba9545bdb59466b">
2796 <source>Use WebTorrent to exchange parts of the video with others</source>
2797 <target>Usar WebTorrent para intercambiar partes del vídeo con otros</target>
2798 <context-group name="null">
2799 <context context-type="linenumber">21</context>
2800 </context-group>
2801 </trans-unit>
2104 <trans-unit id="fb17c44abac2d1ed2a54cdd28bae289dc0b9a1c2"> 2802 <trans-unit id="fb17c44abac2d1ed2a54cdd28bae289dc0b9a1c2">
2105 <source>Automatically plays video</source> 2803 <source>Automatically plays video</source>
2106 <target>Reproducir vídeo automáticamente</target> 2804 <target>Reproducir vídeo automáticamente</target>
@@ -2143,6 +2841,13 @@ Cuando subas un vídeo a este canal, el campo de soporte del vídeo se rellenarÃ
2143 <context context-type="linenumber">18</context> 2841 <context context-type="linenumber">18</context>
2144 </context-group> 2842 </context-group>
2145 </trans-unit> 2843 </trans-unit>
2844 <trans-unit id="d1a04ba05116499d4cf59a48a282a8bcbf5b622d">
2845 <source>Once you delete your account, there is no going back. Please be certain.</source>
2846 <target>Eliminar su cuenta es definitivo. ¿Está seguro?</target>
2847 <context-group name="null">
2848 <context context-type="linenumber">2</context>
2849 </context-group>
2850 </trans-unit>
2146 <trans-unit id="9a2f889dde4574a6883c853d1034e75891b28c45"> 2851 <trans-unit id="9a2f889dde4574a6883c853d1034e75891b28c45">
2147 <source>Delete your account</source> 2852 <source>Delete your account</source>
2148 <target>Eliminar tu cuenta</target> 2853 <target>Eliminar tu cuenta</target>
@@ -2150,6 +2855,20 @@ Cuando subas un vídeo a este canal, el campo de soporte del vídeo se rellenarÃ
2150 <context context-type="linenumber">4</context> 2855 <context context-type="linenumber">4</context>
2151 </context-group> 2856 </context-group>
2152 </trans-unit> 2857 </trans-unit>
2858 <trans-unit id="dd3b6c367381ddfa8f317b8e9b31c55368c65136">
2859 <source>Activities</source>
2860 <target>Actividades</target>
2861 <context-group name="null">
2862 <context context-type="linenumber">2</context>
2863 </context-group>
2864 </trans-unit>
2865 <trans-unit id="847dffd493abbb2a5c71f3313f0eb730dd88a355">
2866 <source>Web</source>
2867 <target>Web</target>
2868 <context-group name="null">
2869 <context context-type="linenumber">3</context>
2870 </context-group>
2871 </trans-unit>
2153 <trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd"> 2872 <trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd">
2154 <source> 2873 <source>
2155 Sorry, but we couldn't find the page you were looking for. 2874 Sorry, but we couldn't find the page you were looking for.
@@ -2161,6 +2880,60 @@ Cuando subas un vídeo a este canal, el campo de soporte del vídeo se rellenarÃ
2161 <context context-type="linenumber">1</context> 2880 <context context-type="linenumber">1</context>
2162 </context-group> 2881 </context-group>
2163 </trans-unit> 2882 </trans-unit>
2883 <trans-unit id="09a69cde5889927629e2ac9dc63a71b88252b530">
2884 <source>
2885 Verify account email confirmation
2886 </source>
2887 <target>
2888 Verificar la confirmación de la dirección de correo electrónico de la cuenta
2889 </target>
2890 <context-group name="null">
2891 <context context-type="linenumber">2</context>
2892 </context-group>
2893 </trans-unit>
2894 <trans-unit id="066569dd934e07e4a5f70c415692be17d5715b57">
2895 <source>
2896 Your email has been verified and you may now login. Redirecting...
2897 </source>
2898 <target>
2899 Su dirección de correo electrónico ha sido verificada y puede conectarse ahora. En curso de redirección...
2900 </target>
2901 <context-group name="null">
2902 <context context-type="linenumber">6</context>
2903 </context-group>
2904 </trans-unit>
2905 <trans-unit id="7ee8fad77b2664dabfb90ea03470f75a6f6d1d48">
2906 <source>An error occurred. </source>
2907 <target>Un error ocurrió.</target>
2908 <context-group name="null">
2909 <context context-type="linenumber">11</context>
2910 </context-group>
2911 </trans-unit>
2912 <trans-unit id="2d02841904de7f5f60e2618670ac1059f3abec97">
2913 <source>
2914 Request email for account verification
2915 </source>
2916 <target>
2917 Solicitar un correo electrónico de verificación de la cuenta
2918 </target>
2919 <context-group name="null">
2920 <context context-type="linenumber">2</context>
2921 </context-group>
2922 </trans-unit>
2923 <trans-unit id="eb539ec6941044e284f237f5b40d6a0159afe7af">
2924 <source>Send verification email</source>
2925 <target>Enviar un correo electrónico de verificación</target>
2926 <context-group name="null">
2927 <context context-type="linenumber">17</context>
2928 </context-group>
2929 </trans-unit>
2930 <trans-unit id="a08080316e052053fd20647731a6de826dc8072f">
2931 <source>This instance does not require email verification.</source>
2932 <target>Esta instancia no requiere verificación por correo electrónico</target>
2933 <context-group name="null">
2934 <context context-type="linenumber">20</context>
2935 </context-group>
2936 </trans-unit>
2164 <trans-unit id="1380539d91f77f565de6e21ce210da891e6644b8"> 2937 <trans-unit id="1380539d91f77f565de6e21ce210da891e6644b8">
2165 <source>Support this channel</source> 2938 <source>Support this channel</source>
2166 <target>Apoyar este canal</target> 2939 <target>Apoyar este canal</target>
@@ -2203,6 +2976,13 @@ Cuando subas un vídeo a este canal, el campo de soporte del vídeo se rellenarÃ
2203 <context context-type="linenumber">159</context> 2976 <context context-type="linenumber">159</context>
2204 </context-group> 2977 </context-group>
2205 </trans-unit> 2978 </trans-unit>
2979 <trans-unit id="385811ab5a5c3e96e0db46c9ce1fc3147d8cd4c7">
2980 <source>Sorry, but something went wrong</source>
2981 <target>Disculpas, algo salió mal</target>
2982 <context-group name="null">
2983 <context context-type="linenumber">49</context>
2984 </context-group>
2985 </trans-unit>
2206 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2"> 2986 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2">
2207 <source> 2987 <source>
2208 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video. 2988 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video.
@@ -2228,18 +3008,25 @@ Cuando subas un vídeo a este canal, el campo de soporte del vídeo se rellenarÃ
2228 <context context-type="linenumber">6</context> 3008 <context context-type="linenumber">6</context>
2229 </context-group> 3009 </context-group>
2230 </trans-unit> 3010 </trans-unit>
3011 <trans-unit id="5e420747842373fa99a75a7a18df068cc81e46fb">
3012 <source>Scheduled</source>
3013 <target>Programado</target>
3014 <context-group name="null">
3015 <context context-type="linenumber">25</context>
3016 </context-group>
3017 </trans-unit>
2231 <trans-unit id="f7ac2376749c7985f94f0fc89ba75ea624de1215"> 3018 <trans-unit id="f7ac2376749c7985f94f0fc89ba75ea624de1215">
2232 <source>Publish will be available when upload is finished</source> 3019 <source>Publish will be available when upload is finished</source>
2233 <target>La publicación estará disponible cuando finalice la subida</target> 3020 <target>La publicación estará disponible cuando finalice la subida</target>
2234 <context-group name="null"> 3021 <context-group name="null">
2235 <context context-type="linenumber">53</context> 3022 <context context-type="linenumber">58</context>
2236 </context-group> 3023 </context-group>
2237 </trans-unit> 3024 </trans-unit>
2238 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 3025 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2239 <source>Publish</source> 3026 <source>Publish</source>
2240 <target>Publicar</target> 3027 <target>Publicar</target>
2241 <context-group name="null"> 3028 <context-group name="null">
2242 <context context-type="linenumber">60</context> 3029 <context context-type="linenumber">65</context>
2243 </context-group> 3030 </context-group>
2244 </trans-unit> 3031 </trans-unit>
2245 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 3032 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -2249,6 +3036,13 @@ Cuando subas un vídeo a este canal, el campo de soporte del vídeo se rellenarÃ
2249 <context context-type="linenumber">6</context> 3036 <context context-type="linenumber">6</context>
2250 </context-group> 3037 </context-group>
2251 </trans-unit> 3038 </trans-unit>
3039 <trans-unit id="1b518e7f8c067fa55ea797bb1b35b4a2d31dccbc">
3040 <source>Or</source>
3041 <target>O</target>
3042 <context-group name="null">
3043 <context context-type="linenumber">11</context>
3044 </context-group>
3045 </trans-unit>
2252 <trans-unit id="0d6558176587662e9bb3b79cca57d42591cf82f9"> 3046 <trans-unit id="0d6558176587662e9bb3b79cca57d42591cf82f9">
2253 <source>Paste magnet URI</source> 3047 <source>Paste magnet URI</source>
2254 <target>Pegar el enlace magnético</target> 3048 <target>Pegar el enlace magnético</target>
@@ -2323,6 +3117,17 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2323 <context context-type="linenumber">24</context> 3117 <context context-type="linenumber">24</context>
2324 </context-group> 3118 </context-group>
2325 </trans-unit> 3119 </trans-unit>
3120 <trans-unit id="c34c61401151c29fb3679638a7d0b95258145ec3">
3121 <source>
3122 This will replace an existing caption!
3123 </source>
3124 <target>
3125 Eso remplazará el texto existente!
3126 </target>
3127 <context-group name="null">
3128 <context context-type="linenumber">29</context>
3129 </context-group>
3130 </trans-unit>
2326 <trans-unit id="39702b643cfe3d5b96a4587c1b44a29fa665406c"> 3131 <trans-unit id="39702b643cfe3d5b96a4587c1b44a29fa665406c">
2327 <source>Add this caption</source> 3132 <source>Add this caption</source>
2328 <target>Añadir este subtítulo</target> 3133 <target>Añadir este subtítulo</target>
@@ -2344,6 +3149,27 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2344 <context context-type="linenumber">191</context> 3149 <context context-type="linenumber">191</context>
2345 </context-group> 3150 </context-group>
2346 </trans-unit> 3151 </trans-unit>
3152 <trans-unit id="457b1cff4d8d7fad0c8742f69c413ecf5e443851">
3153 <source>Tags could be used to suggest relevant recommendations.&lt;/br&gt;Press Enter to add a new tag.</source>
3154 <target>Se puede utilizar etiquetas para sugerir recomendaciones relevantes.&lt;/br&gt;Presione Enter para añadir una nueva etiqueta.</target>
3155 <context-group name="null">
3156 <context context-type="linenumber">18</context>
3157 </context-group>
3158 </trans-unit>
3159 <trans-unit id="9bdd535a2817bf0b843a124bf65e4992625e7ecf">
3160 <source>+ Tag</source>
3161 <target>+ Etiqueta</target>
3162 <context-group name="null">
3163 <context context-type="linenumber">21</context>
3164 </context-group>
3165 </trans-unit>
3166 <trans-unit id="8389e9cde2928cc27aaecbdee818a255bf7984b0">
3167 <source>Enter a new tag</source>
3168 <target>Ingresar una nueva etiqueta</target>
3169 <context-group name="null">
3170 <context context-type="linenumber">21</context>
3171 </context-group>
3172 </trans-unit>
2347 <trans-unit id="50f53834157770b8205ada0e7a6e235211e4765e"> 3173 <trans-unit id="50f53834157770b8205ada0e7a6e235211e4765e">
2348 <source>Video descriptions are truncated by default and require manual action to expand them.</source> 3174 <source>Video descriptions are truncated by default and require manual action to expand them.</source>
2349 <target>Las descripciones de vídeo se muestran truncadas por defecto y requieren de acción manual para expandirlas.</target> 3175 <target>Las descripciones de vídeo se muestran truncadas por defecto y requieren de acción manual para expandirlas.</target>
@@ -2383,14 +3209,14 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2383 <source>Wait transcoding before publishing the video</source> 3209 <source>Wait transcoding before publishing the video</source>
2384 <target>Esperar transcodificación antes de publicar el vídeo</target> 3210 <target>Esperar transcodificación antes de publicar el vídeo</target>
2385 <context-group name="null"> 3211 <context-group name="null">
2386 <context context-type="linenumber">130</context> 3212 <context context-type="linenumber">131</context>
2387 </context-group> 3213 </context-group>
2388 </trans-unit> 3214 </trans-unit>
2389 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 3215 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2390 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 3216 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
2391 <target>Si decides no esperar a la transcodificación antes de publicar el vídeo, quizás no se pueda reproducir hasta que finalice la transcodificación.</target> 3217 <target>Si decides no esperar a la transcodificación antes de publicar el vídeo, quizás no se pueda reproducir hasta que finalice la transcodificación.</target>
2392 <context-group name="null"> 3218 <context-group name="null">
2393 <context context-type="linenumber">131</context> 3219 <context context-type="linenumber">132</context>
2394 </context-group> 3220 </context-group>
2395 </trans-unit> 3221 </trans-unit>
2396 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 3222 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2404,49 +3230,81 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2404 <source>Add another caption</source> 3230 <source>Add another caption</source>
2405 <target>Añadir otro subtítulo</target> 3231 <target>Añadir otro subtítulo</target>
2406 <context-group name="null"> 3232 <context-group name="null">
2407 <context context-type="linenumber">146</context> 3233 <context context-type="linenumber">147</context>
2408 </context-group> 3234 </context-group>
2409 </trans-unit> 3235 </trans-unit>
2410 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 3236 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2411 <source>See the subtitle file</source> 3237 <source>See the subtitle file</source>
2412 <target>Ver el archivo de subtítulo</target> 3238 <target>Ver el archivo de subtítulo</target>
2413 <context-group name="null"> 3239 <context-group name="null">
2414 <context context-type="linenumber">155</context> 3240 <context context-type="linenumber">156</context>
3241 </context-group>
3242 </trans-unit>
3243 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee">
3244 <source>Already uploaded ✔</source>
3245 <target>Ya ha sido subido ✔</target>
3246 <context-group name="null">
3247 <context context-type="linenumber">160</context>
3248 </context-group>
3249 </trans-unit>
3250 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad">
3251 <source>Will be created on update</source>
3252 <target>Estará creado al actualizar</target>
3253 <context-group name="null">
3254 <context context-type="linenumber">168</context>
2415 </context-group> 3255 </context-group>
2416 </trans-unit> 3256 </trans-unit>
2417 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 3257 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2418 <source>Cancel create</source> 3258 <source>Cancel create</source>
2419 <target>Cancelar creación</target> 3259 <target>Cancelar creación</target>
2420 <context-group name="null"> 3260 <context-group name="null">
2421 <context context-type="linenumber">169</context> 3261 <context context-type="linenumber">170</context>
3262 </context-group>
3263 </trans-unit>
3264 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393">
3265 <source>Will be deleted on update</source>
3266 <target>Estará eliminado al actualizar</target>
3267 <context-group name="null">
3268 <context context-type="linenumber">176</context>
2422 </context-group> 3269 </context-group>
2423 </trans-unit> 3270 </trans-unit>
2424 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 3271 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2425 <source>Cancel deletion</source> 3272 <source>Cancel deletion</source>
2426 <target>Cancelar borrado</target> 3273 <target>Cancelar borrado</target>
2427 <context-group name="null"> 3274 <context-group name="null">
2428 <context context-type="linenumber">177</context> 3275 <context context-type="linenumber">178</context>
3276 </context-group>
3277 </trans-unit>
3278 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0">
3279 <source>
3280 No captions for now.
3281 </source>
3282 <target>
3283 Ningún texto por el momento.
3284 </target>
3285 <context-group name="null">
3286 <context context-type="linenumber">183</context>
2429 </context-group> 3287 </context-group>
2430 </trans-unit> 3288 </trans-unit>
2431 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 3289 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2432 <source>Captions</source> 3290 <source>Captions</source>
2433 <target>Subtítulos</target> 3291 <target>Subtítulos</target>
2434 <context-group name="null"> 3292 <context-group name="null">
2435 <context context-type="linenumber">139</context> 3293 <context context-type="linenumber">140</context>
2436 </context-group> 3294 </context-group>
2437 </trans-unit> 3295 </trans-unit>
2438 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 3296 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
2439 <source>Upload thumbnail</source> 3297 <source>Upload thumbnail</source>
2440 <target>Subir miniatura</target> 3298 <target>Subir miniatura</target>
2441 <context-group name="null"> 3299 <context-group name="null">
2442 <context context-type="linenumber">195</context> 3300 <context context-type="linenumber">196</context>
2443 </context-group> 3301 </context-group>
2444 </trans-unit> 3302 </trans-unit>
2445 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 3303 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
2446 <source>Upload preview</source> 3304 <source>Upload preview</source>
2447 <target>Subir previsualización</target> 3305 <target>Subir previsualización</target>
2448 <context-group name="null"> 3306 <context-group name="null">
2449 <context context-type="linenumber">202</context> 3307 <context context-type="linenumber">203</context>
2450 </context-group> 3308 </context-group>
2451 </trans-unit> 3309 </trans-unit>
2452 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 3310 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -2460,14 +3318,14 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2460 <source>Short text to tell people how they can support you (membership platform...).</source> 3318 <source>Short text to tell people how they can support you (membership platform...).</source>
2461 <target>Breve texto para explicar a la gente cómo pueden apoyarte (plataforma de miembros...).</target> 3319 <target>Breve texto para explicar a la gente cómo pueden apoyarte (plataforma de miembros...).</target>
2462 <context-group name="null"> 3320 <context-group name="null">
2463 <context context-type="linenumber">209</context> 3321 <context context-type="linenumber">210</context>
2464 </context-group> 3322 </context-group>
2465 </trans-unit> 3323 </trans-unit>
2466 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 3324 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
2467 <source>Advanced settings</source> 3325 <source>Advanced settings</source>
2468 <target>Ajustes avanzados</target> 3326 <target>Ajustes avanzados</target>
2469 <context-group name="null"> 3327 <context-group name="null">
2470 <context context-type="linenumber">190</context> 3328 <context context-type="linenumber">191</context>
2471 </context-group> 3329 </context-group>
2472 </trans-unit> 3330 </trans-unit>
2473 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 3331 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -2509,6 +3367,17 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2509 <context context-type="linenumber">37</context> 3367 <context context-type="linenumber">37</context>
2510 </context-group> 3368 </context-group>
2511 </trans-unit> 3369 </trans-unit>
3370 <trans-unit id="da44efc7b658c318651866454d258bbbe57ff21c">
3371 <source>
3372 Cancel
3373 </source>
3374 <target>
3375 Cancelar
3376 </target>
3377 <context-group name="null">
3378 <context context-type="linenumber">47</context>
3379 </context-group>
3380 </trans-unit>
2512 <trans-unit id="dc75033a5238fdc4f462212c847a45ba8018a3fd"> 3381 <trans-unit id="dc75033a5238fdc4f462212c847a45ba8018a3fd">
2513 <source>Download</source> 3382 <source>Download</source>
2514 <target>Descargar</target> 3383 <target>Descargar</target>
@@ -2523,6 +3392,19 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2523 <context context-type="linenumber">3</context> 3392 <context context-type="linenumber">3</context>
2524 </context-group> 3393 </context-group>
2525 </trans-unit> 3394 </trans-unit>
3395 <trans-unit id="827b1376aa35c7a7de90f7724d6a51ccfa20c908">
3396 <source>
3397 Your report will be sent to moderators of <x id="INTERPOLATION" equiv-text="{{ currentHost }}"/>.
3398 <x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/> It will be forwarded to origin instance <x id="INTERPOLATION_1" equiv-text="{{ originHost }}"/> too.<x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
3399 </source>
3400 <target>
3401 Su reporte estará enviado a los moderadores de <x id="INTERPOLATION" equiv-text="{{ currentHost }}"/>.
3402 <x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/> También estará transferido a la instancia original <x id="INTERPOLATION_1" equiv-text="{{ originHost }}"/>.<x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
3403 </target>
3404 <context-group name="null">
3405 <context context-type="linenumber">9</context>
3406 </context-group>
3407 </trans-unit>
2526 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 3408 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
2527 <source>Share</source> 3409 <source>Share</source>
2528 <target>Compartir</target> 3410 <target>Compartir</target>
@@ -2544,6 +3426,31 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2544 <context context-type="linenumber">34</context> 3426 <context context-type="linenumber">34</context>
2545 </context-group> 3427 </context-group>
2546 </trans-unit> 3428 </trans-unit>
3429 <trans-unit id="90e0a0a3da80b46e550c1395ff4e97c27259bef8">
3430 <source>
3431 The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites).
3432 </source>
3433 <target>
3434 El URL no es seguro (no utiliza HTTPS), por lo que el vídeo embebido no funcionará en los sitios web HTTPS (los navegadores web bloquean las consultas HTTP inseguras en los sitios web HTTPS).
3435 </target>
3436 <context-group name="null">
3437 <context context-type="linenumber">45</context>
3438 </context-group>
3439 </trans-unit>
3440 <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8">
3441 <source>Close</source>
3442 <target>Cerrar</target>
3443 <context-group name="null">
3444 <context context-type="linenumber">51</context>
3445 </context-group>
3446 </trans-unit>
3447 <trans-unit id="f672385c803647b063687d3c912e2ce5738b51c8">
3448 <source>Blacklist video</source>
3449 <target>Bloquear el vídeo</target>
3450 <context-group name="null">
3451 <context context-type="linenumber">3</context>
3452 </context-group>
3453 </trans-unit>
2547 <trans-unit id="7584313e33a66811eb10646627914a01fff0347d"> 3454 <trans-unit id="7584313e33a66811eb10646627914a01fff0347d">
2548 <source> 3455 <source>
2549 The video is being imported, it will be available when the import is finished. 3456 The video is being imported, it will be available when the import is finished.
@@ -2566,6 +3473,46 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2566 <context context-type="linenumber">15</context> 3473 <context context-type="linenumber">15</context>
2567 </context-group> 3474 </context-group>
2568 </trans-unit> 3475 </trans-unit>
3476 <trans-unit id="c89a08fd2a05d1013fed8478024f5ba37ac3d308">
3477 <source>
3478 This video will be published on <x id="INTERPOLATION" equiv-text="{{ video.scheduledUpdate.updateAt | date: 'full' }}"/>.
3479 </source>
3480 <target>
3481 Este vídeo será publicado el <x id="INTERPOLATION" equiv-text="{{ video.scheduledUpdate.updateAt | date: 'full' }}"/>.
3482 </target>
3483 <context-group name="null">
3484 <context context-type="linenumber">19</context>
3485 </context-group>
3486 </trans-unit>
3487 <trans-unit id="bd7055d3e38beff538463e75d508d1c75c683710">
3488 <source>This video is blacklisted.</source>
3489 <target>Este vídeo está bloqueado</target>
3490 <context-group name="null">
3491 <context context-type="linenumber">24</context>
3492 </context-group>
3493 </trans-unit>
3494 <trans-unit id="3da5360f8314aa95973aa52629c9f635363c5a36">
3495 <source>
3496 Published <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views
3497 </source>
3498 <target>
3499 Publicado <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> vistas
3500 </target>
3501 <context-group name="null">
3502 <context context-type="linenumber">37</context>
3503 </context-group>
3504 </trans-unit>
3505 <trans-unit id="07087373dbf99b5e8b2b2f962fd53baa97d9ab95">
3506 <source>
3507 Published <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views
3508 </source>
3509 <target>
3510 Publicado <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> vistas
3511 </target>
3512 <context-group name="null">
3513 <context context-type="linenumber">46</context>
3514 </context-group>
3515 </trans-unit>
2569 <trans-unit id="82b59049f3f89d900c98da9319e156dd513e3ced"> 3516 <trans-unit id="82b59049f3f89d900c98da9319e156dd513e3ced">
2570 <source>Like this video</source> 3517 <source>Like this video</source>
2571 <target>Me gusta este vídeo</target> 3518 <target>Me gusta este vídeo</target>
@@ -2629,6 +3576,13 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2629 <context context-type="linenumber">100</context> 3576 <context context-type="linenumber">100</context>
2630 </context-group> 3577 </context-group>
2631 </trans-unit> 3578 </trans-unit>
3579 <trans-unit id="61021f5011bc24f69cfc3f6dbbbd8f1948328b25">
3580 <source>Unblacklist this video</source>
3581 <target>Desbloquear este vídeo</target>
3582 <context-group name="null">
3583 <context context-type="linenumber">99</context>
3584 </context-group>
3585 </trans-unit>
2632 <trans-unit id="3dbfdc68f83d91cb360172eb65578cae94e7cbe5"> 3586 <trans-unit id="3dbfdc68f83d91cb360172eb65578cae94e7cbe5">
2633 <source>Delete this video</source> 3587 <source>Delete this video</source>
2634 <target>Eliminar este vídeo</target> 3588 <target>Eliminar este vídeo</target>
@@ -2643,6 +3597,13 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2643 <context context-type="linenumber">123</context> 3597 <context context-type="linenumber">123</context>
2644 </context-group> 3598 </context-group>
2645 </trans-unit> 3599 </trans-unit>
3600 <trans-unit id="0b7f242da10ece3f2995095c455b9a92ebcdd3b4">
3601 <source>By <x id="INTERPOLATION" equiv-text="{{ video.byAccount }}"/></source>
3602 <target>Por <x id="INTERPOLATION" equiv-text="{{ video.byAccount }}"/></target>
3603 <context-group name="null">
3604 <context context-type="linenumber">134</context>
3605 </context-group>
3606 </trans-unit>
2646 <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b"> 3607 <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b">
2647 <source>Show more</source> 3608 <source>Show more</source>
2648 <target>Mostrar más</target> 3609 <target>Mostrar más</target>
@@ -2657,6 +3618,24 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2657 <context context-type="linenumber">152</context> 3618 <context context-type="linenumber">152</context>
2658 </context-group> 3619 </context-group>
2659 </trans-unit> 3620 </trans-unit>
3621 <trans-unit id="4c0ba3cde3b3c58b855ffb4beaa5804a2fc3826b">
3622 <source>Friendly Reminder: </source>
3623 <target>Recuerdo amistoso:</target>
3624 <context-group name="null">
3625 <context context-type="linenumber">208</context>
3626 </context-group>
3627 </trans-unit>
3628 <trans-unit id="9e66f7507eb263abdbab7abafd825f1dc8bc880b">
3629 <source>
3630 the sharing system used for this video implies that some technical information about your system (such as a public IP address) can be sent to other peers.
3631 </source>
3632 <target>
3633 el sistema utilizado para compartir este vídeo implica que algunas informaciones técnicas acerca de su sistema (como la dirección IP pública) pueden estar enviadas a otros pares.
3634 </target>
3635 <context-group name="null">
3636 <context context-type="linenumber">209</context>
3637 </context-group>
3638 </trans-unit>
2660 <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e"> 3639 <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e">
2661 <source>More information</source> 3640 <source>More information</source>
2662 <target>Más información</target> 3641 <target>Más información</target>
@@ -2682,6 +3661,17 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2682 <context context-type="linenumber">215</context> 3661 <context context-type="linenumber">215</context>
2683 </context-group> 3662 </context-group>
2684 </trans-unit> 3663 </trans-unit>
3664 <trans-unit id="abf2b0f7b6405fa2841ca39c827e86089a95cc27">
3665 <source>
3666 Other videos
3667 </source>
3668 <target>
3669 Otros vídeos
3670 </target>
3671 <context-group name="null">
3672 <context context-type="linenumber">2</context>
3673 </context-group>
3674 </trans-unit>
2685 <trans-unit id="b5f5df598f2d75640849b2a7744f91e5dbd390e7"> 3675 <trans-unit id="b5f5df598f2d75640849b2a7744f91e5dbd390e7">
2686 <source> 3676 <source>
2687 Comments 3677 Comments
@@ -2736,6 +3726,57 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2736 <context context-type="linenumber">20</context> 3726 <context context-type="linenumber">20</context>
2737 </context-group> 3727 </context-group>
2738 </trans-unit> 3728 </trans-unit>
3729 <trans-unit id="8b2bb53dfb5f059f2b68cc4ac00661a865909135">
3730 <source>You are one step away from commenting</source>
3731 <target>Está a un paso de poder comentar</target>
3732 <context-group name="null">
3733 <context context-type="linenumber">28</context>
3734 </context-group>
3735 </trans-unit>
3736 <trans-unit id="7984a44ce86b961f4f18c9a58c638f5e8f07a225">
3737 <source>
3738 If you have an account on this instance, you can login:
3739 </source>
3740 <target>
3741 Si tiene una cuenta en esta instancia, puede conectarse:
3742 </target>
3743 <context-group name="null">
3744 <context context-type="linenumber">32</context>
3745 </context-group>
3746 </trans-unit>
3747 <trans-unit id="afe0ad39fee662489f1033e53aea3e16a7e89228">
3748 <source>login to comment</source>
3749 <target>conectarse para comentar</target>
3750 <context-group name="null">
3751 <context context-type="linenumber">35</context>
3752 </context-group>
3753 </trans-unit>
3754 <trans-unit id="a5a3f17c9b4876952d78363834d57280c8684e7c">
3755 <source>
3756 Otherwise you can comment using an account on any ActivityPub-compatible instance.
3757 On most platforms, you can find the video by typing its URL in the search bar and then comment it
3758 from within the software's interface.
3759 </source>
3760 <target>
3761 Sino, puede comentar usando una cuenta de cualquier instancia compatible con ActivityPub.
3762 En la mayoría de las plataformas, puede encontrar el vídeo colocando su URL en el campo de búsqueda y luego comentarlo
3763 desde la interfaz del software.
3764 </target>
3765 <context-group name="null">
3766 <context context-type="linenumber">36</context>
3767 </context-group>
3768 </trans-unit>
3769 <trans-unit id="968b02fbc645be799727de0d1ec3c6f9b11b20eb">
3770 <source>
3771 If you have an account on Mastodon or Pleroma, you can open it directly in their interface:
3772 </source>
3773 <target>
3774 Si tiene una cuenta en Mastodon o Pleroma, puede abrirlo directamente en su interfaz:
3775 </target>
3776 <context-group name="null">
3777 <context context-type="linenumber">41</context>
3778 </context-group>
3779 </trans-unit>
2739 <trans-unit id="a607fab03e11b0e07c1640e11a1b02d7af06b285"> 3780 <trans-unit id="a607fab03e11b0e07c1640e11a1b02d7af06b285">
2740 <source>Highlighted comment</source> 3781 <source>Highlighted comment</source>
2741 <target>Comentario resaltado</target> 3782 <target>Comentario resaltado</target>
@@ -2750,9 +3791,23 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2750 <context context-type="linenumber">14</context> 3791 <context context-type="linenumber">14</context>
2751 </context-group> 3792 </context-group>
2752 </trans-unit> 3793 </trans-unit>
2753 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08"> 3794 <trans-unit id="e0e3a472479c8ce1b78f682ffadbe59daf04d331">
2754 <source>Error getting about from server</source> 3795 <source>Cannot get about information from server</source>
2755 <target>Error al obtener información del servidor</target> 3796 <target>No se puede obtener información del servidor</target>
3797 <context-group name="null">
3798 <context context-type="linenumber">1</context>
3799 </context-group>
3800 </trans-unit>
3801 <trans-unit id="9e601a3b227bb70afbb9b59cd43547b710af1e10">
3802 <source>Your message has been sent.</source>
3803 <target>Su mensaje ha sido remitido</target>
3804 <context-group name="null">
3805 <context context-type="linenumber">1</context>
3806 </context-group>
3807 </trans-unit>
3808 <trans-unit id="8d6d4f48dae547bb32e0669cda5a665dc8db536c">
3809 <source>You already sent this form recently</source>
3810 <target>Ya envió este formulario recientemente</target>
2756 <context-group name="null"> 3811 <context-group name="null">
2757 <context context-type="linenumber">1</context> 3812 <context context-type="linenumber">1</context>
2758 </context-group> 3813 </context-group>
@@ -2778,16 +3833,44 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2778 <context context-type="linenumber">1</context> 3833 <context context-type="linenumber">1</context>
2779 </context-group> 3834 </context-group>
2780 </trans-unit> 3835 </trans-unit>
2781 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d"> 3836 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
2782 <source>Error</source> 3837 <source>240p</source>
2783 <target>Error</target> 3838 <target>240p</target>
2784 <context-group name="null"> 3839 <context-group name="null">
2785 <context context-type="linenumber">1</context> 3840 <context context-type="linenumber">1</context>
2786 </context-group> 3841 </context-group>
2787 </trans-unit> 3842 </trans-unit>
2788 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba"> 3843 <trans-unit id="c8cfad7e7a16c57c42535331b65cb7de40d8402e">
2789 <source>Success</source> 3844 <source>360p</source>
2790 <target>Correcto</target> 3845 <target>360p</target>
3846 <context-group name="null">
3847 <context context-type="linenumber">1</context>
3848 </context-group>
3849 </trans-unit>
3850 <trans-unit id="48f0af5a0d0bea4e84b27eaf41b19c85a531c2a5">
3851 <source>480p</source>
3852 <target>480p</target>
3853 <context-group name="null">
3854 <context context-type="linenumber">1</context>
3855 </context-group>
3856 </trans-unit>
3857 <trans-unit id="6f06138daf6363746ff26bfc0cb2491c09cdfdf2">
3858 <source>720p</source>
3859 <target>720p</target>
3860 <context-group name="null">
3861 <context context-type="linenumber">1</context>
3862 </context-group>
3863 </trans-unit>
3864 <trans-unit id="65c94f9beb6fe957808c40060da280cc7ace7ab9">
3865 <source>1080p</source>
3866 <target>1080p</target>
3867 <context-group name="null">
3868 <context context-type="linenumber">1</context>
3869 </context-group>
3870 </trans-unit>
3871 <trans-unit id="421a937491f19774d17eefa1d24816dae1a9f111">
3872 <source>Auto (via ffmpeg)</source>
3873 <target>Auto (vía ffmpeg)</target>
2791 <context-group name="null"> 3874 <context-group name="null">
2792 <context context-type="linenumber">1</context> 3875 <context context-type="linenumber">1</context>
2793 </context-group> 3876 </context-group>
@@ -2806,6 +3889,69 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2806 <context context-type="linenumber">1</context> 3889 <context context-type="linenumber">1</context>
2807 </context-group> 3890 </context-group>
2808 </trans-unit> 3891 </trans-unit>
3892 <trans-unit id="54adc67482fdaa0d361a2992bc91e064dc61cc9a">
3893 <source>100MB</source>
3894 <target>100MB</target>
3895 <context-group name="null">
3896 <context context-type="linenumber">1</context>
3897 </context-group>
3898 </trans-unit>
3899 <trans-unit id="cd34ef1f476d5422f49f6ed429f61fc1cfcb1174">
3900 <source>500MB</source>
3901 <target>500MB</target>
3902 <context-group name="null">
3903 <context context-type="linenumber">1</context>
3904 </context-group>
3905 </trans-unit>
3906 <trans-unit id="4a47b4beea31cac6e5970b6bc522902f545acc8b">
3907 <source>1GB</source>
3908 <target>1GB</target>
3909 <context-group name="null">
3910 <context context-type="linenumber">1</context>
3911 </context-group>
3912 </trans-unit>
3913 <trans-unit id="b26d0cac75638623098ab7e06e16b096d1f55cc8">
3914 <source>5GB</source>
3915 <target>5GB</target>
3916 <context-group name="null">
3917 <context context-type="linenumber">1</context>
3918 </context-group>
3919 </trans-unit>
3920 <trans-unit id="f9fc4e7ec6743cb6f69bea2d0859a655ed44ffae">
3921 <source>20GB</source>
3922 <target>20GB</target>
3923 <context-group name="null">
3924 <context context-type="linenumber">1</context>
3925 </context-group>
3926 </trans-unit>
3927 <trans-unit id="a56e3f92fe16d97ee4f05051ea61c466ecb51d5e">
3928 <source>50GB</source>
3929 <target>50GB</target>
3930 <context-group name="null">
3931 <context context-type="linenumber">1</context>
3932 </context-group>
3933 </trans-unit>
3934 <trans-unit id="31dcc0c63f6234ace8caa84ae1abc33d4022122d">
3935 <source>10MB</source>
3936 <target>10MB</target>
3937 <context-group name="null">
3938 <context context-type="linenumber">1</context>
3939 </context-group>
3940 </trans-unit>
3941 <trans-unit id="f2f968b6f2199b919f567702c6f23b43e5ea71af">
3942 <source>50MB</source>
3943 <target>50MB</target>
3944 <context-group name="null">
3945 <context context-type="linenumber">1</context>
3946 </context-group>
3947 </trans-unit>
3948 <trans-unit id="c31575424fe1b2a57064413f3eda7ce657c46c8a">
3949 <source>2GB</source>
3950 <target>2GB</target>
3951 <context-group name="null">
3952 <context context-type="linenumber">1</context>
3953 </context-group>
3954 </trans-unit>
2809 <trans-unit id="fc5731a28a99b25c62d43333ceebb250d60aff84"> 3955 <trans-unit id="fc5731a28a99b25c62d43333ceebb250d60aff84">
2810 <source><x id="INTERPOLATION" equiv-text="{{host}}"/> is not valid</source> 3956 <source><x id="INTERPOLATION" equiv-text="{{host}}"/> is not valid</source>
2811 <target><x id="INTERPOLATION" equiv-text="{{host}}"/> no es válido</target> 3957 <target><x id="INTERPOLATION" equiv-text="{{host}}"/> no es válido</target>
@@ -2869,6 +4015,97 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2869 <context context-type="linenumber">1</context> 4015 <context context-type="linenumber">1</context>
2870 </context-group> 4016 </context-group>
2871 </trans-unit> 4017 </trans-unit>
4018 <trans-unit id="4d8f527638f3e0b518a96e07d41d886bcce01246">
4019 <source>enabled</source>
4020 <target>habilitada</target>
4021 <context-group name="null">
4022 <context context-type="linenumber">1</context>
4023 </context-group>
4024 </trans-unit>
4025 <trans-unit id="795733aac948794cadeb3be6386882efac2c38ad">
4026 <source>disabled</source>
4027 <target>deshabilitada</target>
4028 <context-group name="null">
4029 <context context-type="linenumber">1</context>
4030 </context-group>
4031 </trans-unit>
4032 <trans-unit id="1123807fc813c816404598147173403d00117557">
4033 <source>Redundancy for <x id="INTERPOLATION" equiv-text="{{host}}"/> is <x id="INTERPOLATION_1" equiv-text="{{stateLabel}}"/></source>
4034 <target>La redundancia para <x id="INTERPOLATION" equiv-text="{{host}}"/> está <x id="INTERPOLATION_1" equiv-text="{{stateLabel}}"/></target>
4035 <context-group name="null">
4036 <context context-type="linenumber">1</context>
4037 </context-group>
4038 </trans-unit>
4039 <trans-unit id="53cc0f4a4566c4139c65f93b5dce2fe8302e78da">
4040 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by your instance.</source>
4041 <target>La cuenta <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> no está silenciada por su instancia.</target>
4042 <context-group name="null">
4043 <context context-type="linenumber">1</context>
4044 </context-group>
4045 </trans-unit>
4046 <trans-unit id="468b52e3c04fb9a3d8c8213555dfcad0cbcae330">
4047 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by your instance.</source>
4048 <target>La instancia <x id="INTERPOLATION" equiv-text="{{host}}"/> no está silenciada por su instancia.</target>
4049 <context-group name="null">
4050 <context context-type="linenumber">1</context>
4051 </context-group>
4052 </trans-unit>
4053 <trans-unit id="800cd3cdf47751b576587259ba3a1bc0a7f435b6">
4054 <source>Comment updated.</source>
4055 <target>Comentario actualizado</target>
4056 <context-group name="null">
4057 <context context-type="linenumber">1</context>
4058 </context-group>
4059 </trans-unit>
4060 <trans-unit id="586bee8c27a761611eb05661524cc7ca944b5978">
4061 <source>Delete this report</source>
4062 <target>Eliminar este reporte</target>
4063 <context-group name="null">
4064 <context context-type="linenumber">1</context>
4065 </context-group>
4066 </trans-unit>
4067 <trans-unit id="cf3b28ba29a907b334ab0e6dccd080a60ba23321">
4068 <source>Update moderation comment</source>
4069 <target>Actualizar el comentario de moderación</target>
4070 <context-group name="null">
4071 <context context-type="linenumber">1</context>
4072 </context-group>
4073 </trans-unit>
4074 <trans-unit id="d512430037b6580ba970c80cfc1687b6bdc221a3">
4075 <source>Mark as accepted</source>
4076 <target>Marcar como aceptado</target>
4077 <context-group name="null">
4078 <context context-type="linenumber">1</context>
4079 </context-group>
4080 </trans-unit>
4081 <trans-unit id="d895b090c054bfc0ad3aba816af0615a1997f5a3">
4082 <source>Mark as rejected</source>
4083 <target>Marcar como rechazado</target>
4084 <context-group name="null">
4085 <context context-type="linenumber">1</context>
4086 </context-group>
4087 </trans-unit>
4088 <trans-unit id="73b70e37cddaa6494d8a666b6cba90dc80595599">
4089 <source>Do you really want to delete this abuse report?</source>
4090 <target>¿Confirma la eliminación del reporte de abuso?</target>
4091 <context-group name="null">
4092 <context context-type="linenumber">1</context>
4093 </context-group>
4094 </trans-unit>
4095 <trans-unit id="6a7938b8780c27540ea70cc0f8f4d928c8916cf9">
4096 <source>Abuse deleted.</source>
4097 <target>Reporte de abuso eliminado.</target>
4098 <context-group name="null">
4099 <context context-type="linenumber">1</context>
4100 </context-group>
4101 </trans-unit>
4102 <trans-unit id="652845b2b32b2e117b9b02879b1af07859b0e223">
4103 <source>Do you really want to remove this video from the blacklist? It will be available again in the videos list.</source>
4104 <target>¿Confirmar el desbloqueo de este vídeo? Estará disponible de nuevo en la lista de vídeos.</target>
4105 <context-group name="null">
4106 <context context-type="linenumber">1</context>
4107 </context-group>
4108 </trans-unit>
2872 <trans-unit id="1585babc36806e20e225ac27dbba0e7c7cd09e0f"> 4109 <trans-unit id="1585babc36806e20e225ac27dbba0e7c7cd09e0f">
2873 <source>Video <x id="INTERPOLATION" equiv-text="{{name}}"/> removed from the blacklist.</source> 4110 <source>Video <x id="INTERPOLATION" equiv-text="{{name}}"/> removed from the blacklist.</source>
2874 <target>Vídeo <x id="INTERPOLATION" equiv-text="{{name}}"/> eliminado de la lista negra.</target> 4111 <target>Vídeo <x id="INTERPOLATION" equiv-text="{{name}}"/> eliminado de la lista negra.</target>
@@ -2897,6 +4134,41 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2897 <context context-type="linenumber">1</context> 4134 <context context-type="linenumber">1</context>
2898 </context-group> 4135 </context-group>
2899 </trans-unit> 4136 </trans-unit>
4137 <trans-unit id="50dc7afa2305131cdbdb384cfc1f2a5f0f4647d8">
4138 <source>Unban</source>
4139 <target>Dejar sin efecto la expulsión</target>
4140 <context-group name="null">
4141 <context context-type="linenumber">1</context>
4142 </context-group>
4143 </trans-unit>
4144 <trans-unit id="910ed85f550272401b134a40d019ab3359fe883f">
4145 <source>Set Email as Verified</source>
4146 <target>Establecer la dirección de correo electrónico como Verificada</target>
4147 <context-group name="null">
4148 <context context-type="linenumber">1</context>
4149 </context-group>
4150 </trans-unit>
4151 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf">
4152 <source>You cannot ban root.</source>
4153 <target>No puede expulsar al root.</target>
4154 <context-group name="null">
4155 <context context-type="linenumber">1</context>
4156 </context-group>
4157 </trans-unit>
4158 <trans-unit id="98119091712a8ca72905e3b4c1cf60649af7565e">
4159 <source>Do you really want to unban <x id="INTERPOLATION" equiv-text="{{num}}"/> users?</source>
4160 <target>¿Confirma dejar sin efecto la expulsión de <x id="INTERPOLATION" equiv-text="{{num}}"/> usuarios?</target>
4161 <context-group name="null">
4162 <context context-type="linenumber">1</context>
4163 </context-group>
4164 </trans-unit>
4165 <trans-unit id="6121be086a51c4c73bbdd8aebdddd9744c8f1ffd">
4166 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users unbanned.</source>
4167 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> usuarios expulsados.</target>
4168 <context-group name="null">
4169 <context context-type="linenumber">1</context>
4170 </context-group>
4171 </trans-unit>
2900 <trans-unit id="911fc197949e47aa5f0541627bc319f59edd9d11"> 4172 <trans-unit id="911fc197949e47aa5f0541627bc319f59edd9d11">
2901 <source>You cannot delete root.</source> 4173 <source>You cannot delete root.</source>
2902 <target>No puedes eliminar al root.</target> 4174 <target>No puedes eliminar al root.</target>
@@ -2904,6 +4176,90 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2904 <context context-type="linenumber">1</context> 4176 <context context-type="linenumber">1</context>
2905 </context-group> 4177 </context-group>
2906 </trans-unit> 4178 </trans-unit>
4179 <trans-unit id="9de914fe915cc730efc57e81c987188a24d3ac51">
4180 <source>If you remove these users, you will not be able to create others with the same username!</source>
4181 <target>¡Si elimina estos usuarios, no será posible crear otros con el mismo nombre de usuario!</target>
4182 <context-group name="null">
4183 <context context-type="linenumber">1</context>
4184 </context-group>
4185 </trans-unit>
4186 <trans-unit id="b708d332e3f89b24745e749fa530210f0bdea329">
4187 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users deleted.</source>
4188 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> usuarios eliminados.</target>
4189 <context-group name="null">
4190 <context context-type="linenumber">1</context>
4191 </context-group>
4192 </trans-unit>
4193 <trans-unit id="f4a8f2ef1fbfc19e1e049e69f63c40063c0d0650">
4194 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users email set as verified.</source>
4195 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> direcciones de correo electrónico de usuarios establecidas como verificadas.</target>
4196 <context-group name="null">
4197 <context context-type="linenumber">1</context>
4198 </context-group>
4199 </trans-unit>
4200 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de">
4201 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source>
4202 <target>La cuenta <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> ya no está silenciada.</target>
4203 <context-group name="null">
4204 <context context-type="linenumber">1</context>
4205 </context-group>
4206 </trans-unit>
4207 <trans-unit id="c6af80b42938d4a49e6f6c4f60ce26228916994c">
4208 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted.</source>
4209 <target>La instancia <x id="INTERPOLATION" equiv-text="{{host}}"/> ya no está silenciada.</target>
4210 <context-group name="null">
4211 <context context-type="linenumber">1</context>
4212 </context-group>
4213 </trans-unit>
4214 <trans-unit id="80057baa3b97a4349304bdaa0a880e6f4778561f">
4215 <source>My videos history</source>
4216 <target>Mi historial de vídeos</target>
4217 <context-group name="null">
4218 <context context-type="linenumber">1</context>
4219 </context-group>
4220 </trans-unit>
4221 <trans-unit id="05f6dda1754741495451b8658bd2248856765d95">
4222 <source>Videos history is enabled</source>
4223 <target>El historial de vídeos está habilitado</target>
4224 <context-group name="null">
4225 <context context-type="linenumber">1</context>
4226 </context-group>
4227 </trans-unit>
4228 <trans-unit id="6bb9ade8637c5e35fb5cb36cf7dbec71c65d4013">
4229 <source>Videos history is disabled</source>
4230 <target>El historial de vídeos está deshabilitado</target>
4231 <context-group name="null">
4232 <context context-type="linenumber">1</context>
4233 </context-group>
4234 </trans-unit>
4235 <trans-unit id="8453a7a55b8b23bbbc293cd0939fb59a73307de8">
4236 <source>Delete videos history</source>
4237 <target>Eliminar el historial de vídeos</target>
4238 <context-group name="null">
4239 <context context-type="linenumber">1</context>
4240 </context-group>
4241 </trans-unit>
4242 <trans-unit id="f8f86df8a1ae711944c3ab819bb19bf360dfa7a4">
4243 <source>Are you sure you want to delete all your videos history?</source>
4244 <target>¿Confirma la eliminación de todo su historial de vídeos?</target>
4245 <context-group name="null">
4246 <context context-type="linenumber">1</context>
4247 </context-group>
4248 </trans-unit>
4249 <trans-unit id="195d5ba6c8bd05762d9318d0afd0b094fd776164">
4250 <source>Videos history deleted</source>
4251 <target>Historial de vídeos eliminado</target>
4252 <context-group name="null">
4253 <context context-type="linenumber">1</context>
4254 </context-group>
4255 </trans-unit>
4256 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e">
4257 <source>Ownership accepted</source>
4258 <target>Titularidad aceptada</target>
4259 <context-group name="null">
4260 <context context-type="linenumber">1</context>
4261 </context-group>
4262 </trans-unit>
2907 <trans-unit id="19508af0dfbc685cbf10cf02061bb5a0f423b6fc"> 4263 <trans-unit id="19508af0dfbc685cbf10cf02061bb5a0f423b6fc">
2908 <source>Password updated.</source> 4264 <source>Password updated.</source>
2909 <target>Contraseña actualizada.</target> 4265 <target>Contraseña actualizada.</target>
@@ -2911,6 +4267,13 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2911 <context context-type="linenumber">1</context> 4267 <context context-type="linenumber">1</context>
2912 </context-group> 4268 </context-group>
2913 </trans-unit> 4269 </trans-unit>
4270 <trans-unit id="466fc8cf56fd4e4e90fec4b900ef083d52bec38c">
4271 <source>You current password is invalid.</source>
4272 <target>Su contraseña actual es invalida.</target>
4273 <context-group name="null">
4274 <context context-type="linenumber">1</context>
4275 </context-group>
4276 </trans-unit>
2914 <trans-unit id="ca8e8cf0f1686604db3b6a2ebadab7f7b426a047"> 4277 <trans-unit id="ca8e8cf0f1686604db3b6a2ebadab7f7b426a047">
2915 <source>Are you sure you want to delete your account? This will delete all you data, including channels, videos etc.</source> 4278 <source>Are you sure you want to delete your account? This will delete all you data, including channels, videos etc.</source>
2916 <target>Estás seguro de querer eliminar tu cuenta? Todos tus datos serán eliminados, incluyendo canales, vídeos, etc.</target> 4279 <target>Estás seguro de querer eliminar tu cuenta? Todos tus datos serán eliminados, incluyendo canales, vídeos, etc.</target>
@@ -2939,6 +4302,76 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2939 <context context-type="linenumber">1</context> 4302 <context context-type="linenumber">1</context>
2940 </context-group> 4303 </context-group>
2941 </trans-unit> 4304 </trans-unit>
4305 <trans-unit id="7c193bf704577e514b63497c4f366511afdb6585">
4306 <source>New video from your subscriptions</source>
4307 <target>Nuevo vídeo desde sus suscripciones</target>
4308 <context-group name="null">
4309 <context context-type="linenumber">1</context>
4310 </context-group>
4311 </trans-unit>
4312 <trans-unit id="ba897defa2e6c34d5ee3d10edf8d797a35e7e3e5">
4313 <source>New comment on your video</source>
4314 <target>Nuevo comentario en su vídeo</target>
4315 <context-group name="null">
4316 <context context-type="linenumber">1</context>
4317 </context-group>
4318 </trans-unit>
4319 <trans-unit id="0a9650640ddd1dfadfe456891d6d4f6093ad428e">
4320 <source>New video abuse on local video</source>
4321 <target>Nueva denuncia de abuso sobre un vídeo local</target>
4322 <context-group name="null">
4323 <context context-type="linenumber">1</context>
4324 </context-group>
4325 </trans-unit>
4326 <trans-unit id="abac8b7629cfcd85bff25770f83ea229f646f996">
4327 <source>One of your video is blacklisted/unblacklisted</source>
4328 <target>Uno de sus vídeos ha sido bloqueado/desbloqueado</target>
4329 <context-group name="null">
4330 <context context-type="linenumber">1</context>
4331 </context-group>
4332 </trans-unit>
4333 <trans-unit id="f3eff4df9e4aa9dab411e6eb83833a33016a88bc">
4334 <source>Video published (after transcoding/scheduled update)</source>
4335 <target>Vídeo publicado (después de una transcodificación / actualización programada)</target>
4336 <context-group name="null">
4337 <context context-type="linenumber">1</context>
4338 </context-group>
4339 </trans-unit>
4340 <trans-unit id="ec7ddc265da1df78011ae7677d62a2ae10aef7a4">
4341 <source>Video import finished</source>
4342 <target>Importación de vídeo terminada</target>
4343 <context-group name="null">
4344 <context context-type="linenumber">1</context>
4345 </context-group>
4346 </trans-unit>
4347 <trans-unit id="c327bbac87cca61f5c52f5825d564878e98b9034">
4348 <source>A new user registered on your instance</source>
4349 <target>Un nuevo usuario se registró en su instancia</target>
4350 <context-group name="null">
4351 <context context-type="linenumber">1</context>
4352 </context-group>
4353 </trans-unit>
4354 <trans-unit id="f407b90e99a04e2e0d1872c02f01eadbf53e08e2">
4355 <source>You or your channel(s) has a new follower</source>
4356 <target>Usted o su(s) canal(es) tiene un nuevo seguidor</target>
4357 <context-group name="null">
4358 <context context-type="linenumber">1</context>
4359 </context-group>
4360 </trans-unit>
4361 <trans-unit id="14c3050a9da4c1bc49d555c45d5660804d08e83b">
4362 <source>Someone mentioned you in video comments</source>
4363 <target>Alguien le mencionó en comentarios de vídeo</target>
4364 <context-group name="null">
4365 <context context-type="linenumber">1</context>
4366 </context-group>
4367 </trans-unit>
4368 <trans-unit id="a0f04081717f5f00c0a2c723903c3a2d4c296401">
4369 <source>Preferences saved</source>
4370 <target>Preferencias guardadas</target>
4371 <context-group name="null">
4372 <context context-type="linenumber">1</context>
4373 </context-group>
4374 </trans-unit>
2942 <trans-unit id="db4ff52375f6a25ad0472e92754c8c265ae47c6b"> 4375 <trans-unit id="db4ff52375f6a25ad0472e92754c8c265ae47c6b">
2943 <source>Profile updated.</source> 4376 <source>Profile updated.</source>
2944 <target>Perfil actualizado.</target> 4377 <target>Perfil actualizado.</target>
@@ -2967,6 +4400,13 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2967 <context context-type="linenumber">1</context> 4400 <context context-type="linenumber">1</context>
2968 </context-group> 4401 </context-group>
2969 </trans-unit> 4402 </trans-unit>
4403 <trans-unit id="f359f6adf6cccca7770019f947ed594169ee7d47">
4404 <source>This name already exists on this instance.</source>
4405 <target>El nombre ya existe en esta instancia.</target>
4406 <context-group name="null">
4407 <context context-type="linenumber">1</context>
4408 </context-group>
4409 </trans-unit>
2970 <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795"> 4410 <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795">
2971 <source>Create</source> 4411 <source>Create</source>
2972 <target>Crear</target> 4412 <target>Crear</target>
@@ -2981,23 +4421,16 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
2981 <context context-type="linenumber">1</context> 4421 <context context-type="linenumber">1</context>
2982 </context-group> 4422 </context-group>
2983 </trans-unit> 4423 </trans-unit>
2984 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 4424 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
2985 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 4425 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
2986 <target>¿De verdad quieres eliminar <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? Esto eliminará también todos los vídeos subidos a este canal.</target> 4426 <target>Canal de vídeo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> eliminado.</target>
2987 <context-group name="null">
2988 <context context-type="linenumber">1</context>
2989 </context-group>
2990 </trans-unit>
2991 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
2992 <source>Please type the name of the video channel to confirm</source>
2993 <target>Por favor escribe el nombre del canal de vídeo para confirmar</target>
2994 <context-group name="null"> 4427 <context-group name="null">
2995 <context context-type="linenumber">1</context> 4428 <context context-type="linenumber">1</context>
2996 </context-group> 4429 </context-group>
2997 </trans-unit> 4430 </trans-unit>
2998 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 4431 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2999 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 4432 <source>My videos</source>
3000 <target>Canal de vídeo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> eliminado.</target> 4433 <target>Mis vídeos</target>
3001 <context-group name="null"> 4434 <context-group name="null">
3002 <context context-type="linenumber">1</context> 4435 <context context-type="linenumber">1</context>
3003 </context-group> 4436 </context-group>
@@ -3065,6 +4498,76 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3065 <context context-type="linenumber">1</context> 4498 <context context-type="linenumber">1</context>
3066 </context-group> 4499 </context-group>
3067 </trans-unit> 4500 </trans-unit>
4501 <trans-unit id="740c53a50a618bf5c7a5bd5c3f7321f0bd1840dd">
4502 <source>Ownership change request sent.</source>
4503 <target>Solicitud de cambio de titularidad enviada.</target>
4504 <context-group name="null">
4505 <context context-type="linenumber">1</context>
4506 </context-group>
4507 </trans-unit>
4508 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
4509 <source>My library</source>
4510 <target>Mi biblioteca</target>
4511 <context-group name="null">
4512 <context context-type="linenumber">1</context>
4513 </context-group>
4514 </trans-unit>
4515 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
4516 <source>My channels</source>
4517 <target>Mis canales</target>
4518 <context-group name="null">
4519 <context context-type="linenumber">1</context>
4520 </context-group>
4521 </trans-unit>
4522 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
4523 <source>My subscriptions</source>
4524 <target>Mis suscripciones</target>
4525 <context-group name="null">
4526 <context context-type="linenumber">1</context>
4527 </context-group>
4528 </trans-unit>
4529 <trans-unit id="4f953496ca94b4f83af049ff715172df2729fb79">
4530 <source>My history</source>
4531 <target>Mi historial</target>
4532 <context-group name="null">
4533 <context context-type="linenumber">1</context>
4534 </context-group>
4535 </trans-unit>
4536 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
4537 <source>Misc</source>
4538 <target>Diversos</target>
4539 <context-group name="null">
4540 <context context-type="linenumber">1</context>
4541 </context-group>
4542 </trans-unit>
4543 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
4544 <source>Ownership changes</source>
4545 <target>Cambios de titularidad</target>
4546 <context-group name="null">
4547 <context context-type="linenumber">1</context>
4548 </context-group>
4549 </trans-unit>
4550 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
4551 <source>My settings</source>
4552 <target>Mis ajustes</target>
4553 <context-group name="null">
4554 <context context-type="linenumber">1</context>
4555 </context-group>
4556 </trans-unit>
4557 <trans-unit id="0e2434e7d84145c4e8a930ccc4c26c3cb2887e0d">
4558 <source>My notifications</source>
4559 <target>Mis notificaciones</target>
4560 <context-group name="null">
4561 <context context-type="linenumber">1</context>
4562 </context-group>
4563 </trans-unit>
4564 <trans-unit id="af55337b4032d675ab6b2081af797ca9c979b706">
4565 <source>An email with verification link will be sent to <x id="INTERPOLATION" equiv-text="{{email}}"/>.</source>
4566 <target>Un correo electrónico con un vínculo de verificación será enviado a <x id="INTERPOLATION" equiv-text="{{email}}"/>.</target>
4567 <context-group name="null">
4568 <context context-type="linenumber">1</context>
4569 </context-group>
4570 </trans-unit>
3068 <trans-unit id="ccbf0490fb6b60d21e03bb2c9003df0ce1a58752"> 4571 <trans-unit id="ccbf0490fb6b60d21e03bb2c9003df0ce1a58752">
3069 <source>Unable to find user id or verification string.</source> 4572 <source>Unable to find user id or verification string.</source>
3070 <target>No se pudo encontrar el id de usuario o la cadena de verificación.</target> 4573 <target>No se pudo encontrar el id de usuario o la cadena de verificación.</target>
@@ -3072,6 +4575,97 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3072 <context context-type="linenumber">1</context> 4575 <context context-type="linenumber">1</context>
3073 </context-group> 4576 </context-group>
3074 </trans-unit> 4577 </trans-unit>
4578 <trans-unit id="ff6becacbce7fc0943b0af0df4dd67e5e11bf598">
4579 <source>Subscribe to the account</source>
4580 <target>Suscribirse a la cuenta</target>
4581 <context-group name="null">
4582 <context context-type="linenumber">1</context>
4583 </context-group>
4584 </trans-unit>
4585 <trans-unit id="1c95cc372311830f936b39f73c5d6d20c0b16013">
4586 <source>Focus the search bar</source>
4587 <target>Enfocar la barra de búsqueda</target>
4588 <context-group name="null">
4589 <context context-type="linenumber">1</context>
4590 </context-group>
4591 </trans-unit>
4592 <trans-unit id="b19ee83cbd2b735fd081b9aa483a890578019099">
4593 <source>Toggle the left menu</source>
4594 <target>Conmutar el menú de la izquierda</target>
4595 <context-group name="null">
4596 <context context-type="linenumber">1</context>
4597 </context-group>
4598 </trans-unit>
4599 <trans-unit id="b54759e30f7c1983940cdacb8eb03f102a869084">
4600 <source>Go to the videos overview page</source>
4601 <target>Ir a la página general de vídeos</target>
4602 <context-group name="null">
4603 <context context-type="linenumber">1</context>
4604 </context-group>
4605 </trans-unit>
4606 <trans-unit id="1e919c88a3f889d6659288e69d3e178da0ea7ab0">
4607 <source>Go to the trending videos page</source>
4608 <target>Ir a la página de vídeos populares</target>
4609 <context-group name="null">
4610 <context context-type="linenumber">1</context>
4611 </context-group>
4612 </trans-unit>
4613 <trans-unit id="249618dcdd7fbdc863c0714e2eb9e8940bc9c37d">
4614 <source>Go to the recently added videos page</source>
4615 <target>Ir a la página de vídeos recientes</target>
4616 <context-group name="null">
4617 <context context-type="linenumber">1</context>
4618 </context-group>
4619 </trans-unit>
4620 <trans-unit id="7e194daef3a3509128c4300d4c7c292c49ebf3f5">
4621 <source>Go to the local videos page</source>
4622 <target>Ir a la página de vídeos locales</target>
4623 <context-group name="null">
4624 <context context-type="linenumber">1</context>
4625 </context-group>
4626 </trans-unit>
4627 <trans-unit id="f1fb6204f39a7338e5110b2f113643c9288496ba">
4628 <source>Go to the videos upload page</source>
4629 <target>Ir a la página de subida de vídeos</target>
4630 <context-group name="null">
4631 <context context-type="linenumber">1</context>
4632 </context-group>
4633 </trans-unit>
4634 <trans-unit id="0ed7b40c11da9d4565af9c041df20c15bc6be97e">
4635 <source>Toggle Dark theme</source>
4636 <target>Conmutar el tema Oscuro</target>
4637 <context-group name="null">
4638 <context context-type="linenumber">1</context>
4639 </context-group>
4640 </trans-unit>
4641 <trans-unit id="badd4b24618ccc8a34620acb9053fc654b9612b2">
4642 <source>Go to my subscriptions</source>
4643 <target>Ir a mis suscripciones</target>
4644 <context-group name="null">
4645 <context context-type="linenumber">1</context>
4646 </context-group>
4647 </trans-unit>
4648 <trans-unit id="b7184b5a236618e8edd747529869c392ab6dace1">
4649 <source>Go to my videos</source>
4650 <target>Ir a mis vídeos</target>
4651 <context-group name="null">
4652 <context context-type="linenumber">1</context>
4653 </context-group>
4654 </trans-unit>
4655 <trans-unit id="acf985bd42886b9b3030b5f68f0e8417c39b40a7">
4656 <source>Go to my imports</source>
4657 <target>Ir a mis importaciones</target>
4658 <context-group name="null">
4659 <context context-type="linenumber">1</context>
4660 </context-group>
4661 </trans-unit>
4662 <trans-unit id="cfe3c51f0ae9385dc2ce6df740d87e5514aa9390">
4663 <source>Go to my channels</source>
4664 <target>Ir a mis canales</target>
4665 <context-group name="null">
4666 <context context-type="linenumber">1</context>
4667 </context-group>
4668 </trans-unit>
3075 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7"> 4669 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7">
3076 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>. 4670 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>.
3077</source> 4671</source>
@@ -3088,6 +4682,13 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3088 <context context-type="linenumber">1</context> 4682 <context context-type="linenumber">1</context>
3089 </context-group> 4683 </context-group>
3090 </trans-unit> 4684 </trans-unit>
4685 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
4686 <source>Error</source>
4687 <target>Error</target>
4688 <context-group name="null">
4689 <context context-type="linenumber">1</context>
4690 </context-group>
4691 </trans-unit>
3091 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 4692 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
3092 <source>You need to reconnect.</source> 4693 <source>You need to reconnect.</source>
3093 <target>Tienes que reconectar.</target> 4694 <target>Tienes que reconectar.</target>
@@ -3102,6 +4703,41 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3102 <context context-type="linenumber">1</context> 4703 <context context-type="linenumber">1</context>
3103 </context-group> 4704 </context-group>
3104 </trans-unit> 4705 </trans-unit>
4706 <trans-unit id="5c0c574151dc8671d9199980ee04bf65aec3b452">
4707 <source>Keyboard Shortcuts:</source>
4708 <target>Atajos de teclado:</target>
4709 <context-group name="null">
4710 <context context-type="linenumber">1</context>
4711 </context-group>
4712 </trans-unit>
4713 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4714 <source>Info</source>
4715 <target>Info</target>
4716 <context-group name="null">
4717 <context context-type="linenumber">1</context>
4718 </context-group>
4719 </trans-unit>
4720 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
4721 <source>Success</source>
4722 <target>Correcto</target>
4723 <context-group name="null">
4724 <context context-type="linenumber">1</context>
4725 </context-group>
4726 </trans-unit>
4727 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
4728 <source>Incorrect username or password.</source>
4729 <target>Nombre de usuario o contraseña incorrecta</target>
4730 <context-group name="null">
4731 <context context-type="linenumber">1</context>
4732 </context-group>
4733 </trans-unit>
4734 <trans-unit id="39980cc1cf8df621d43f5480d001bdf5d4139338">
4735 <source>You account is blocked.</source>
4736 <target>Su cuenta ha sido bloqueada</target>
4737 <context-group name="null">
4738 <context context-type="linenumber">1</context>
4739 </context-group>
4740 </trans-unit>
3105 <trans-unit id="7701e3762dc4a2b2e302c24f17820bc8dd7cacc1"> 4741 <trans-unit id="7701e3762dc4a2b2e302c24f17820bc8dd7cacc1">
3106 <source>An email with the reset password instructions will be sent to <x id="INTERPOLATION" equiv-text="{{email}}"/>.</source> 4742 <source>An email with the reset password instructions will be sent to <x id="INTERPOLATION" equiv-text="{{email}}"/>.</source>
3107 <target>Un correo con las instrucciones para restablecer la contraseña será enviado a <x id="INTERPOLATION" equiv-text="{{email}}"/>.</target> 4743 <target>Un correo con las instrucciones para restablecer la contraseña será enviado a <x id="INTERPOLATION" equiv-text="{{email}}"/>.</target>
@@ -3298,6 +4934,69 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3298 <context context-type="linenumber">1</context> 4934 <context context-type="linenumber">1</context>
3299 </context-group> 4935 </context-group>
3300 </trans-unit> 4936 </trans-unit>
4937 <trans-unit id="4166cc066b963a23829b48a09e394f73b453fabd">
4938 <source>Transcoding threads must be greater or equal to 0.</source>
4939 <target>El número de subprocesos de transcodificación tiene que ser superior o igual a 0.</target>
4940 <context-group name="null">
4941 <context context-type="linenumber">1</context>
4942 </context-group>
4943 </trans-unit>
4944 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4945 <source>Email is required.</source>
4946 <target>Se requiere un correo electrónico.</target>
4947 <context-group name="null">
4948 <context context-type="linenumber">1</context>
4949 </context-group>
4950 </trans-unit>
4951 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4952 <source>Email must be valid.</source>
4953 <target>El correo electrónico ha de ser válido.</target>
4954 <context-group name="null">
4955 <context context-type="linenumber">1</context>
4956 </context-group>
4957 </trans-unit>
4958 <trans-unit id="ac451f128840b34804ea69c820dc3566f476fb33">
4959 <source>Your name is required.</source>
4960 <target>Su nombre es requerido.</target>
4961 <context-group name="null">
4962 <context context-type="linenumber">1</context>
4963 </context-group>
4964 </trans-unit>
4965 <trans-unit id="1fc4633008a2431fdec891d58efcc8b865d7de1a">
4966 <source>Your name must be at least 1 character long.</source>
4967 <target>Su nombre tiene que contener por lo menos 1 carácter.</target>
4968 <context-group name="null">
4969 <context context-type="linenumber">1</context>
4970 </context-group>
4971 </trans-unit>
4972 <trans-unit id="c7b44b92c0ce3ccd2f804d001e13da399524e11b">
4973 <source>Your name cannot be more than 120 characters long.</source>
4974 <target>Su nombre no puede contener más de 120 caracteres.</target>
4975 <context-group name="null">
4976 <context context-type="linenumber">1</context>
4977 </context-group>
4978 </trans-unit>
4979 <trans-unit id="40b35cf927f9f9a59404a6c914ec4632690b69b2">
4980 <source>A message is required.</source>
4981 <target>Se tiene que colocar un mensaje.</target>
4982 <context-group name="null">
4983 <context context-type="linenumber">1</context>
4984 </context-group>
4985 </trans-unit>
4986 <trans-unit id="d8d4a23f467ee3e93ca0edb1198c233ed633cf64">
4987 <source>The message must be at least 3 characters long.</source>
4988 <target>El mensaje tiene que contener por lo menos 3 caracteres.</target>
4989 <context-group name="null">
4990 <context context-type="linenumber">1</context>
4991 </context-group>
4992 </trans-unit>
4993 <trans-unit id="07422f6141cfcabaf3c2ce77e3e063222849ef60">
4994 <source>The message cannot be more than 5000 characters long.</source>
4995 <target>El mensaje no puede contener más de 5.000 caracteres.</target>
4996 <context-group name="null">
4997 <context context-type="linenumber">1</context>
4998 </context-group>
4999 </trans-unit>
3301 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 5000 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
3302 <source>Username is required.</source> 5001 <source>Username is required.</source>
3303 <target>Se requiere un nombre de usuario.</target> 5002 <target>Se requiere un nombre de usuario.</target>
@@ -3319,37 +5018,23 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3319 <context context-type="linenumber">1</context> 5018 <context context-type="linenumber">1</context>
3320 </context-group> 5019 </context-group>
3321 </trans-unit> 5020 </trans-unit>
3322 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea"> 5021 <trans-unit id="6330d25a3bc6f55dfd5177da6e681d1d3b1a2b1a">
3323 <source>Username must be at least 3 characters long.</source> 5022 <source>Username must be at least 1 character long.</source>
3324 <target>El nombre de usuario ha de ocupar más de 3 caracteres.</target> 5023 <target>El nombre de usuario tiene que contener por lo menos un carácter.</target>
3325 <context-group name="null">
3326 <context context-type="linenumber">1</context>
3327 </context-group>
3328 </trans-unit>
3329 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
3330 <source>Username cannot be more than 20 characters long.</source>
3331 <target>El nombre de usuario no puede ocupar más de 20 caracteres.</target>
3332 <context-group name="null">
3333 <context context-type="linenumber">1</context>
3334 </context-group>
3335 </trans-unit>
3336 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
3337 <source>Username should be only lowercase alphanumeric characters.</source>
3338 <target>El nombre de usuario debe utilizar únicamente caracteres alfanuméricos en minúscula.</target>
3339 <context-group name="null"> 5024 <context-group name="null">
3340 <context context-type="linenumber">1</context> 5025 <context context-type="linenumber">1</context>
3341 </context-group> 5026 </context-group>
3342 </trans-unit> 5027 </trans-unit>
3343 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0"> 5028 <trans-unit id="aaaf3d00c35f809eebc7fd68a3f7b8b0230b197a">
3344 <source>Email is required.</source> 5029 <source>Username cannot be more than 50 characters long.</source>
3345 <target>Se requiere un correo electrónico.</target> 5030 <target>El nombre de usuario no puede contener más de 50 caracteres.</target>
3346 <context-group name="null"> 5031 <context-group name="null">
3347 <context context-type="linenumber">1</context> 5032 <context context-type="linenumber">1</context>
3348 </context-group> 5033 </context-group>
3349 </trans-unit> 5034 </trans-unit>
3350 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1"> 5035 <trans-unit id="6f3e95be2538a22da07beaefc39bb2195683990c">
3351 <source>Email must be valid.</source> 5036 <source>Username should be lowercase alphanumeric; dots and underscores are allowed.</source>
3352 <target>El correo electrónico ha de ser válido.</target> 5037 <target>El nombre de usuario puede contener minúsculas, cifras, puntos y barras bajas.</target>
3353 <context-group name="null"> 5038 <context-group name="null">
3354 <context context-type="linenumber">1</context> 5039 <context context-type="linenumber">1</context>
3355 </context-group> 5040 </context-group>
@@ -3389,6 +5074,20 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3389 <context context-type="linenumber">1</context> 5074 <context context-type="linenumber">1</context>
3390 </context-group> 5075 </context-group>
3391 </trans-unit> 5076 </trans-unit>
5077 <trans-unit id="7e58d1fb4e86af94f5199660ef349d55811888bb">
5078 <source>Daily upload limit is required.</source>
5079 <target>Se requiere colocar un límite diario de subida.</target>
5080 <context-group name="null">
5081 <context context-type="linenumber">1</context>
5082 </context-group>
5083 </trans-unit>
5084 <trans-unit id="e283cbc4469959ea664f9d545f15278e089a6f1e">
5085 <source>Daily upload limit must be greater than -1.</source>
5086 <target>El límite diario de subida tiene que ser superior a -1.</target>
5087 <context-group name="null">
5088 <context context-type="linenumber">1</context>
5089 </context-group>
5090 </trans-unit>
3392 <trans-unit id="545e77fd5d9526228a2133109447c23225ed9c85"> 5091 <trans-unit id="545e77fd5d9526228a2133109447c23225ed9c85">
3393 <source>User role is required.</source> 5092 <source>User role is required.</source>
3394 <target>Se requiere un rol de usuario.</target> 5093 <target>Se requiere un rol de usuario.</target>
@@ -3403,16 +5102,16 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3403 <context context-type="linenumber">1</context> 5102 <context context-type="linenumber">1</context>
3404 </context-group> 5103 </context-group>
3405 </trans-unit> 5104 </trans-unit>
3406 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674"> 5105 <trans-unit id="085b2d6f79819a72a2b56cada4ef5085ba51d90c">
3407 <source>Display name must be at least 3 characters long.</source> 5106 <source>Display name must be at least 1 character long.</source>
3408 <target>El nombre para mostrar debe ocupar como mínimo 3 caracteres.</target> 5107 <target>El nombre mostrado tiene que contener por lo menos 1 carácter.</target>
3409 <context-group name="null"> 5108 <context-group name="null">
3410 <context context-type="linenumber">1</context> 5109 <context context-type="linenumber">1</context>
3411 </context-group> 5110 </context-group>
3412 </trans-unit> 5111 </trans-unit>
3413 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9"> 5112 <trans-unit id="5a920575b8e1067f5b11c66a4a36d3ced87756f1">
3414 <source>Display name cannot be more than 120 characters long.</source> 5113 <source>Display name cannot be more than 50 characters long.</source>
3415 <target>El nombre a mostrar no puede ocupar más de 120 caracteres.</target> 5114 <target>El nombre mostrado no puede contener más de 50 caracteres.</target>
3416 <context-group name="null"> 5115 <context-group name="null">
3417 <context context-type="linenumber">1</context> 5116 <context context-type="linenumber">1</context>
3418 </context-group> 5117 </context-group>
@@ -3424,6 +5123,13 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3424 <context context-type="linenumber">1</context> 5123 <context context-type="linenumber">1</context>
3425 </context-group> 5124 </context-group>
3426 </trans-unit> 5125 </trans-unit>
5126 <trans-unit id="a4179e366d4aa335f1ddd0a13e9109c71a9338d0">
5127 <source>Description cannot be more than 1000 characters long.</source>
5128 <target>La descripción no puede contener más de 1.000 caracteres.</target>
5129 <context-group name="null">
5130 <context context-type="linenumber">1</context>
5131 </context-group>
5132 </trans-unit>
3427 <trans-unit id="4a3ebc6ddb6b6677aed7b04eb503f9ddd0cfe561"> 5133 <trans-unit id="4a3ebc6ddb6b6677aed7b04eb503f9ddd0cfe561">
3428 <source>You must to agree with the instance terms in order to registering on it.</source> 5134 <source>You must to agree with the instance terms in order to registering on it.</source>
3429 <target>Debes aceptar los términos de uso del nodo para poder registrarte en él.</target> 5135 <target>Debes aceptar los términos de uso del nodo para poder registrarte en él.</target>
@@ -3431,6 +5137,20 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3431 <context context-type="linenumber">1</context> 5137 <context context-type="linenumber">1</context>
3432 </context-group> 5138 </context-group>
3433 </trans-unit> 5139 </trans-unit>
5140 <trans-unit id="6d2c3ebffd49b8933200a6d4e5b74712be49bf00">
5141 <source>Ban reason must be at least 3 characters long.</source>
5142 <target>La razón de la expulsión tiene que contener por lo menos 3 caracteres.</target>
5143 <context-group name="null">
5144 <context context-type="linenumber">1</context>
5145 </context-group>
5146 </trans-unit>
5147 <trans-unit id="be32ff1dd6e464c5c085dd7d128316f476d2e0fd">
5148 <source>Ban reason cannot be more than 250 characters long.</source>
5149 <target>La razón de la expulsión no puede contener más de 250 caracteres.</target>
5150 <context-group name="null">
5151 <context context-type="linenumber">1</context>
5152 </context-group>
5153 </trans-unit>
3434 <trans-unit id="b3cf1889d2fdd6b15e697c270c9b80772fe2cae6"> 5154 <trans-unit id="b3cf1889d2fdd6b15e697c270c9b80772fe2cae6">
3435 <source>Report reason is required.</source> 5155 <source>Report reason is required.</source>
3436 <target>Se requiere un motivo para reportar.</target> 5156 <target>Se requiere un motivo para reportar.</target>
@@ -3445,9 +5165,37 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3445 <context context-type="linenumber">1</context> 5165 <context context-type="linenumber">1</context>
3446 </context-group> 5166 </context-group>
3447 </trans-unit> 5167 </trans-unit>
3448 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9"> 5168 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
3449 <source>Report reason cannot be more than 300 characters long.</source> 5169 <source>Moderation comment is required.</source>
3450 <target>El motivo del reporte no puede ocupar más de 300 caracteres.</target> 5170 <target>Se requiere llenar el comentario de moderación.</target>
5171 <context-group name="null">
5172 <context context-type="linenumber">1</context>
5173 </context-group>
5174 </trans-unit>
5175 <trans-unit id="82e31d0837eaa69a4364e7434d253ce138b3c5c2">
5176 <source>Moderation comment must be at least 2 characters long.</source>
5177 <target>El comentario de moderación tiene que contener por lo menos 2 caracteres.</target>
5178 <context-group name="null">
5179 <context context-type="linenumber">1</context>
5180 </context-group>
5181 </trans-unit>
5182 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
5183 <source>The channel is required.</source>
5184 <target>Se requiere llenar el canal.</target>
5185 <context-group name="null">
5186 <context context-type="linenumber">1</context>
5187 </context-group>
5188 </trans-unit>
5189 <trans-unit id="0776b05d442a0a16f083a5eefa52a166b9d514ca">
5190 <source>Blacklist reason must be at least 2 characters long.</source>
5191 <target>La razón del bloqueo tiene que contener por lo menos 2 caracteres.</target>
5192 <context-group name="null">
5193 <context context-type="linenumber">1</context>
5194 </context-group>
5195 </trans-unit>
5196 <trans-unit id="5009443905b0b152915247799492bf5e164e7626">
5197 <source>Blacklist reason cannot be more than 300 characters long.</source>
5198 <target>La razón del bloqueo no puede contener más de 300 caracteres.</target>
3451 <context-group name="null"> 5199 <context-group name="null">
3452 <context context-type="linenumber">1</context> 5200 <context context-type="linenumber">1</context>
3453 </context-group> 5201 </context-group>
@@ -3466,6 +5214,48 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3466 <context context-type="linenumber">1</context> 5214 <context context-type="linenumber">1</context>
3467 </context-group> 5215 </context-group>
3468 </trans-unit> 5216 </trans-unit>
5217 <trans-unit id="bd7fc070c728dc6dbf3959d49fe5bb27ce15d294">
5218 <source>The username is required.</source>
5219 <target>Se requiere llenar el nombre de usuario.</target>
5220 <context-group name="null">
5221 <context context-type="linenumber">1</context>
5222 </context-group>
5223 </trans-unit>
5224 <trans-unit id="c8465c3773699dd075e0147e264d2e232f605803">
5225 <source>You can only transfer ownership to a local account</source>
5226 <target>Solo puede transferir la titularidad a una cuenta local</target>
5227 <context-group name="null">
5228 <context context-type="linenumber">1</context>
5229 </context-group>
5230 </trans-unit>
5231 <trans-unit id="541087322c34e8b26954fd67ff4fc80d1a6c1b33">
5232 <source>Name is required.</source>
5233 <target>Se requiere llenar el nombre.</target>
5234 <context-group name="null">
5235 <context context-type="linenumber">1</context>
5236 </context-group>
5237 </trans-unit>
5238 <trans-unit id="b8b59b6284a14fc71268cf722ed98c62c5af4a76">
5239 <source>Name must be at least 1 character long.</source>
5240 <target>El nombre tiene que contener por lo menos 1 carácter.</target>
5241 <context-group name="null">
5242 <context context-type="linenumber">1</context>
5243 </context-group>
5244 </trans-unit>
5245 <trans-unit id="e14cd37d29f13eac7384c339e4f1df58d96e4e3d">
5246 <source>Name cannot be more than 50 characters long.</source>
5247 <target>El nombre no puede contener más de 50 caracteres.</target>
5248 <context-group name="null">
5249 <context context-type="linenumber">1</context>
5250 </context-group>
5251 </trans-unit>
5252 <trans-unit id="135185da003b14cbb69521f570fa617a00bbbe18">
5253 <source>Name should be lowercase alphanumeric; dots and underscores are allowed.</source>
5254 <target>El nombre puede contener minúsculas, cifras, puntos y barras bajas.</target>
5255 <context-group name="null">
5256 <context context-type="linenumber">1</context>
5257 </context-group>
5258 </trans-unit>
3469 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 5259 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
3470 <source>Support text must be at least 3 characters long.</source> 5260 <source>Support text must be at least 3 characters long.</source>
3471 <target>El texto para el apoyo ha de ocupar como mínimo 3 caracteres.</target> 5261 <target>El texto para el apoyo ha de ocupar como mínimo 3 caracteres.</target>
@@ -3473,6 +5263,13 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3473 <context context-type="linenumber">1</context> 5263 <context context-type="linenumber">1</context>
3474 </context-group> 5264 </context-group>
3475 </trans-unit> 5265 </trans-unit>
5266 <trans-unit id="15ec53d9ee65cb930c5f5d10ae2e8dd3fd44fc85">
5267 <source>Support text cannot be more than 1000 characters long.</source>
5268 <target>El texto de apoyo no puede contener más de 1.000 caracteres.</target>
5269 <context-group name="null">
5270 <context context-type="linenumber">1</context>
5271 </context-group>
5272 </trans-unit>
3476 <trans-unit id="6ca60e0f6dfbc0073b0514bce7d273150b0b9e79"> 5273 <trans-unit id="6ca60e0f6dfbc0073b0514bce7d273150b0b9e79">
3477 <source>Comment is required.</source> 5274 <source>Comment is required.</source>
3478 <target>Se requiere comentario.</target> 5275 <target>Se requiere comentario.</target>
@@ -3564,6 +5361,13 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3564 <context context-type="linenumber">1</context> 5361 <context context-type="linenumber">1</context>
3565 </context-group> 5362 </context-group>
3566 </trans-unit> 5363 </trans-unit>
5364 <trans-unit id="f17de746af56840511cae11559539b6d8b6955ad">
5365 <source>Video support cannot be more than 1000 characters long.</source>
5366 <target>El soporte de vídeo no puede contener más de 1.000 caracteres.</target>
5367 <context-group name="null">
5368 <context context-type="linenumber">1</context>
5369 </context-group>
5370 </trans-unit>
3567 <trans-unit id="453413bf387dea681958871319bab489dd5e6ec0"> 5371 <trans-unit id="453413bf387dea681958871319bab489dd5e6ec0">
3568 <source>A date is required to schedule video update.</source> 5372 <source>A date is required to schedule video update.</source>
3569 <target>Se requiere una fecha para actualizar la programación del vídeo.</target> 5373 <target>Se requiere una fecha para actualizar la programación del vídeo.</target>
@@ -3914,6 +5718,27 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
3914 <context context-type="linenumber">1</context> 5718 <context context-type="linenumber">1</context>
3915 </context-group> 5719 </context-group>
3916 </trans-unit> 5720 </trans-unit>
5721 <trans-unit id="a0fdb831d4557925dbaa4f8aff7e5035f7506411">
5722 <source>Transcode your videos in multiple resolutions</source>
5723 <target>Transcodificar sus vídeos en múltiples resoluciones</target>
5724 <context-group name="null">
5725 <context context-type="linenumber">1</context>
5726 </context-group>
5727 </trans-unit>
5728 <trans-unit id="590fc27fcbd7dd680da2bb2da644a183338f6bd1">
5729 <source>HTTP import (YouTube, Vimeo, direct URL...)</source>
5730 <target>Importación HTTP (YouTube, Vimeo, URL directo...)</target>
5731 <context-group name="null">
5732 <context context-type="linenumber">1</context>
5733 </context-group>
5734 </trans-unit>
5735 <trans-unit id="4e231a74ad4739e7b0606e8e66d5a656f5855a5a">
5736 <source>Torrent import</source>
5737 <target>Importación de torrent</target>
5738 <context-group name="null">
5739 <context context-type="linenumber">1</context>
5740 </context-group>
5741 </trans-unit>
3917 <trans-unit id="7296e9f7cc4956b6d57c541728b0826e76d108ba"> 5742 <trans-unit id="7296e9f7cc4956b6d57c541728b0826e76d108ba">
3918 <source>~ <x id="INTERPOLATION" equiv-text="{{minutes}}"/> <x id="ICU" equiv-text="{minutes, plural, =1 {...} other {...}}"/></source> 5743 <source>~ <x id="INTERPOLATION" equiv-text="{{minutes}}"/> <x id="ICU" equiv-text="{minutes, plural, =1 {...} other {...}}"/></source>
3919 <target>~ <x id="INTERPOLATION" equiv-text="{{minutes}}"/> <x id="ICU" equiv-text="{minutes, plural, =1 {...} other {...}}"/></target> 5744 <target>~ <x id="INTERPOLATION" equiv-text="{{minutes}}"/> <x id="ICU" equiv-text="{minutes, plural, =1 {...} other {...}}"/></target>
@@ -4068,6 +5893,41 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
4068 <context context-type="linenumber">1</context> 5893 <context context-type="linenumber">1</context>
4069 </context-group> 5894 </context-group>
4070 </trans-unit> 5895 </trans-unit>
5896 <trans-unit id="f9b4f2d8146c789cd40314f640ec4e88efbaf681">
5897 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users banned.</source>
5898 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> usuarios bloqueados.</target>
5899 <context-group name="null">
5900 <context context-type="linenumber">1</context>
5901 </context-group>
5902 </trans-unit>
5903 <trans-unit id="3ab99e62550869aebc85661fca2faf46785263dd">
5904 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> banned.</source>
5905 <target>Usuario <x id="INTERPOLATION" equiv-text="{{username}}"/> bloqueado.</target>
5906 <context-group name="null">
5907 <context context-type="linenumber">1</context>
5908 </context-group>
5909 </trans-unit>
5910 <trans-unit id="faafee0c03ad25c8a43aa91bd5d98185b67ff734">
5911 <source>Do you really want to unban <x id="INTERPOLATION" equiv-text="{{username}}"/>?</source>
5912 <target>¿Confirma el desbloqueo de <x id="INTERPOLATION" equiv-text="{{username}}"/>?</target>
5913 <context-group name="null">
5914 <context context-type="linenumber">1</context>
5915 </context-group>
5916 </trans-unit>
5917 <trans-unit id="925ba9946b7b256a586f0fcbe3e04fa7a0dee7bd">
5918 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> unbanned.</source>
5919 <target>El usuario <x id="INTERPOLATION" equiv-text="{{username}}"/> ha sido desbloqueado.</target>
5920 <context-group name="null">
5921 <context context-type="linenumber">1</context>
5922 </context-group>
5923 </trans-unit>
5924 <trans-unit id="ad07d34d4aadfe03c964cec02ca1d3a921e6b603">
5925 <source>If you remove this user, you will not be able to create another with the same username!</source>
5926 <target>¡Si elimina este usuario, no podrá crear otro con el mismo nombre de usuario!</target>
5927 <context-group name="null">
5928 <context context-type="linenumber">1</context>
5929 </context-group>
5930 </trans-unit>
4071 <trans-unit id="28220fae6799ab98ef6b41af449aa9680082357a"> 5931 <trans-unit id="28220fae6799ab98ef6b41af449aa9680082357a">
4072 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> deleted.</source> 5932 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> deleted.</source>
4073 <target>Usuario <x id="INTERPOLATION" equiv-text="{{username}}"/> eliminado.</target> 5933 <target>Usuario <x id="INTERPOLATION" equiv-text="{{username}}"/> eliminado.</target>
@@ -4075,6 +5935,111 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
4075 <context context-type="linenumber">1</context> 5935 <context context-type="linenumber">1</context>
4076 </context-group> 5936 </context-group>
4077 </trans-unit> 5937 </trans-unit>
5938 <trans-unit id="534202c90c6dcadd2989fc72c5030d5483e26096">
5939 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> email set as verified</source>
5940 <target>El correo electrónico del usuario <x id="INTERPOLATION" equiv-text="{{username}}"/> establecido como verificado</target>
5941 <context-group name="null">
5942 <context context-type="linenumber">1</context>
5943 </context-group>
5944 </trans-unit>
5945 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249">
5946 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source>
5947 <target>Cuenta <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> silenciada.</target>
5948 <context-group name="null">
5949 <context context-type="linenumber">1</context>
5950 </context-group>
5951 </trans-unit>
5952 <trans-unit id="086eda792aeb1b0d131d633b50fdd1792f5f24c6">
5953 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted.</source>
5954 <target>Instancia <x id="INTERPOLATION" equiv-text="{{host}}"/> silenciada.</target>
5955 <context-group name="null">
5956 <context context-type="linenumber">1</context>
5957 </context-group>
5958 </trans-unit>
5959 <trans-unit id="bb72d6d1219e89d182e9fd09d853d83baf8d6499">
5960 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted by the instance.</source>
5961 <target>Cuenta <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> silenciada por la instancia.</target>
5962 <context-group name="null">
5963 <context context-type="linenumber">1</context>
5964 </context-group>
5965 </trans-unit>
5966 <trans-unit id="8686834bc4afe42c1991c6c18f0bce174a0e17a6">
5967 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by the instance.</source>
5968 <target>Cuenta <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> ya no silenciada por la instancia.</target>
5969 <context-group name="null">
5970 <context context-type="linenumber">1</context>
5971 </context-group>
5972 </trans-unit>
5973 <trans-unit id="35d3509161861a610b0895bf084c781e56ba2830">
5974 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted by the instance.</source>
5975 <target>Instancia <x id="INTERPOLATION" equiv-text="{{host}}"/> silenciada por la instancia.</target>
5976 <context-group name="null">
5977 <context context-type="linenumber">1</context>
5978 </context-group>
5979 </trans-unit>
5980 <trans-unit id="978aeec5613fa97e8a5336d3599cebb23ee5a90f">
5981 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by the instance.</source>
5982 <target>La instancia <x id="INTERPOLATION" equiv-text="{{host}}"/> ya no es silenciada por la instancia.</target>
5983 <context-group name="null">
5984 <context context-type="linenumber">1</context>
5985 </context-group>
5986 </trans-unit>
5987 <trans-unit id="4a09bf8724e7659fbb5ec33647529cdef7614bdc">
5988 <source>Mute this account</source>
5989 <target>Silenciar esta cuenta</target>
5990 <context-group name="null">
5991 <context context-type="linenumber">1</context>
5992 </context-group>
5993 </trans-unit>
5994 <trans-unit id="d666ca3261aef72b2ddcd649d7b32af488f59952">
5995 <source>Unmute this account</source>
5996 <target>Dejar de silenciar esta cuenta</target>
5997 <context-group name="null">
5998 <context context-type="linenumber">1</context>
5999 </context-group>
6000 </trans-unit>
6001 <trans-unit id="e17218983b1de76e5a920b04e1c2ecbdb6e3e06d">
6002 <source>Mute the instance</source>
6003 <target>Silenciar esta instancia</target>
6004 <context-group name="null">
6005 <context context-type="linenumber">1</context>
6006 </context-group>
6007 </trans-unit>
6008 <trans-unit id="a23514d8aca2f8633622dda0e86b399dc576a2b9">
6009 <source>Unmute the instance</source>
6010 <target>Dejar de silenciar esta instancia</target>
6011 <context-group name="null">
6012 <context context-type="linenumber">1</context>
6013 </context-group>
6014 </trans-unit>
6015 <trans-unit id="4e4107055b44eee44b6954c41120de1cb4d46432">
6016 <source>Mute this account by your instance</source>
6017 <target>Silenciar esta cuenta por su instancia</target>
6018 <context-group name="null">
6019 <context context-type="linenumber">1</context>
6020 </context-group>
6021 </trans-unit>
6022 <trans-unit id="a51c59cb5ecb7004a6a8ddd2855b5c52266ad957">
6023 <source>Unmute this account by your instance</source>
6024 <target>Dejar de silenciar esta cuenta por su instancia</target>
6025 <context-group name="null">
6026 <context context-type="linenumber">1</context>
6027 </context-group>
6028 </trans-unit>
6029 <trans-unit id="588073e831cec240d6bb0db0b133e45dab69f178">
6030 <source>Mute the instance by your instance</source>
6031 <target>Silenciar esta instancia por su instancia</target>
6032 <context-group name="null">
6033 <context context-type="linenumber">1</context>
6034 </context-group>
6035 </trans-unit>
6036 <trans-unit id="676221cdabd4805901343976988c028dbf71b20a">
6037 <source>Unmute the instance by your instance</source>
6038 <target>Dejar de silenciar esta instancia por su instancia</target>
6039 <context-group name="null">
6040 <context context-type="linenumber">1</context>
6041 </context-group>
6042 </trans-unit>
4078 <trans-unit id="0c0f5bbcd2386018ec057877f9d3c5c2c9880cac"> 6043 <trans-unit id="0c0f5bbcd2386018ec057877f9d3c5c2c9880cac">
4079 <source>Request is too large for the server. Please contact you administrator if you want to increase the limit size.</source> 6044 <source>Request is too large for the server. Please contact you administrator if you want to increase the limit size.</source>
4080 <target>La petición es demasiado grande para el servidor. Por favor contacta con tu administrador si quieres aumentar el límite de tamaño.</target> 6045 <target>La petición es demasiado grande para el servidor. Por favor contacta con tu administrador si quieres aumentar el límite de tamaño.</target>
@@ -4103,6 +6068,76 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
4103 <context context-type="linenumber">1</context> 6068 <context context-type="linenumber">1</context>
4104 </context-group> 6069 </context-group>
4105 </trans-unit> 6070 </trans-unit>
6071 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
6072 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
6073 <target>Suscrito a <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
6074 <context-group name="null">
6075 <context context-type="linenumber">1</context>
6076 </context-group>
6077 </trans-unit>
6078 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
6079 <source>Subscribed</source>
6080 <target>Suscrito</target>
6081 <context-group name="null">
6082 <context context-type="linenumber">1</context>
6083 </context-group>
6084 </trans-unit>
6085 <trans-unit id="3e7735fa326fcdc9e1188b6d9ff4b4329312fc26">
6086 <source>Unsubscribed from <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
6087 <target>Ya no está suscrito a <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
6088 <context-group name="null">
6089 <context context-type="linenumber">1</context>
6090 </context-group>
6091 </trans-unit>
6092 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
6093 <source>Unsubscribed</source>
6094 <target>Ya no está suscrito</target>
6095 <context-group name="null">
6096 <context context-type="linenumber">1</context>
6097 </context-group>
6098 </trans-unit>
6099 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf">
6100 <source>Moderator</source>
6101 <target>Moderador</target>
6102 <context-group name="null">
6103 <context context-type="linenumber">1</context>
6104 </context-group>
6105 </trans-unit>
6106 <trans-unit id="d4195053fd38eacf6dee1fc507296928978cc8fb">
6107 <source>Only I can see this video</source>
6108 <target>Soy el único que pueda ver este vídeo</target>
6109 <context-group name="null">
6110 <context context-type="linenumber">1</context>
6111 </context-group>
6112 </trans-unit>
6113 <trans-unit id="17b62592e5fcabb5235bb25c4883a827ab37cf70">
6114 <source>Only people with the private link can see this video</source>
6115 <target>Solo las personas que tengan el vínculo privado pueden ver este vídeo</target>
6116 <context-group name="null">
6117 <context context-type="linenumber">1</context>
6118 </context-group>
6119 </trans-unit>
6120 <trans-unit id="15be15cbdc6e960f57e801f457c19165ab39632b">
6121 <source>Anyone can see this video</source>
6122 <target>Todos pueden ver este vídeo</target>
6123 <context-group name="null">
6124 <context context-type="linenumber">1</context>
6125 </context-group>
6126 </trans-unit>
6127 <trans-unit id="21565881ad1dff3c98738b9535b3515cec140609">
6128 <source>Welcome! Now please check your emails to verify your account and complete signup.</source>
6129 <target>¡Le damos la bienvenida! Ahora revise sus correos electrónicos para verificar su cuenta y terminar el proceso de registro. </target>
6130 <context-group name="null">
6131 <context context-type="linenumber">1</context>
6132 </context-group>
6133 </trans-unit>
6134 <trans-unit id="14200e26888a07633c0f177020dce8f3ec7311a6">
6135 <source>You are now logged in as <x id="INTERPOLATION" equiv-text="{{username}}"/>!</source>
6136 <target>¡Está conectado como <x id="INTERPOLATION" equiv-text="{{username}}"/>!</target>
6137 <context-group name="null">
6138 <context context-type="linenumber">1</context>
6139 </context-group>
6140 </trans-unit>
4106 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb"> 6141 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb">
4107 <source>Video to import updated.</source> 6142 <source>Video to import updated.</source>
4108 <target>Video to import updated.</target> 6143 <target>Video to import updated.</target>
@@ -4131,23 +6166,23 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
4131 <context context-type="linenumber">1</context> 6166 <context context-type="linenumber">1</context>
4132 </context-group> 6167 </context-group>
4133 </trans-unit> 6168 </trans-unit>
4134 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5"> 6169 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
4135 <source>Info</source> 6170 <source>Upload cancelled</source>
4136 <target>Info</target> 6171 <target>Subida cancelada</target>
4137 <context-group name="null"> 6172 <context-group name="null">
4138 <context context-type="linenumber">1</context> 6173 <context context-type="linenumber">1</context>
4139 </context-group> 6174 </context-group>
4140 </trans-unit> 6175 </trans-unit>
4141 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 6176 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
4142 <source>Upload cancelled</source> 6177 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
4143 <target>Subida cancelada</target> 6178 <target>Con este vídeo, está pasando su cuota de espacio (tamaño del vídeo: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, espacio utilizado: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, cuota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
4144 <context-group name="null"> 6179 <context-group name="null">
4145 <context context-type="linenumber">1</context> 6180 <context context-type="linenumber">1</context>
4146 </context-group> 6181 </context-group>
4147 </trans-unit> 6182 </trans-unit>
4148 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa"> 6183 <trans-unit id="c980896ac8e08e9751545db1b7ef0e93fb8a52cd">
4149 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source> 6184 <source>Your daily video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{quotaUsedDaily}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{quotaDaily}}"/>)</source>
4150 <target>Lo sentimos pero PeerTube no puede manejar vídeos &gt; 8 GB</target> 6185 <target>Con este vídeo, su cuota de espacio diario ha sido excedido (tamaño del vídeo: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, espacio usado: <x id="INTERPOLATION_1" equiv-text="{{quotaUsedDaily}}"/>, cuota: <x id="INTERPOLATION_2" equiv-text="{{quotaDaily}}"/>)</target>
4151 <context-group name="null"> 6186 <context-group name="null">
4152 <context context-type="linenumber">1</context> 6187 <context context-type="linenumber">1</context>
4153 </context-group> 6188 </context-group>
@@ -4173,6 +6208,13 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
4173 <context context-type="linenumber">1</context> 6208 <context context-type="linenumber">1</context>
4174 </context-group> 6209 </context-group>
4175 </trans-unit> 6210 </trans-unit>
6211 <trans-unit id="73c33d602da89a33d353d686f36c2fff39f0aee3">
6212 <source>Video blacklisted.</source>
6213 <target>Vídeo bloqueado</target>
6214 <context-group name="null">
6215 <context context-type="linenumber">1</context>
6216 </context-group>
6217 </trans-unit>
4176 <trans-unit id="ef90545bc832876c0d7f9a10363c75137472bbb5"> 6218 <trans-unit id="ef90545bc832876c0d7f9a10363c75137472bbb5">
4177 <source>Copied</source> 6219 <source>Copied</source>
4178 <target>Copiado</target> 6220 <target>Copiado</target>
@@ -4187,6 +6229,27 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
4187 <context context-type="linenumber">1</context> 6229 <context context-type="linenumber">1</context>
4188 </context-group> 6230 </context-group>
4189 </trans-unit> 6231 </trans-unit>
6232 <trans-unit id="aca77c42f255d4bc6e95c12c5d656070726c6c2f">
6233 <source>Start at <x id="INTERPOLATION" equiv-text="{{timestamp}}"/></source>
6234 <target>Iniciar a <x id="INTERPOLATION" equiv-text="{{timestamp}}"/></target>
6235 <context-group name="null">
6236 <context context-type="linenumber">1</context>
6237 </context-group>
6238 </trans-unit>
6239 <trans-unit id="0e65067fdcc9d8725a41896cb1e229d1415a45f6">
6240 <source>Like the video</source>
6241 <target>Colocar Me gusta a este vídeo</target>
6242 <context-group name="null">
6243 <context context-type="linenumber">1</context>
6244 </context-group>
6245 </trans-unit>
6246 <trans-unit id="1a999e06e1aca0a70cd7d0e3e5c2c63d0e1885c8">
6247 <source>Dislike the video</source>
6248 <target>Eliminar Me gusta de este vídeo</target>
6249 <context-group name="null">
6250 <context context-type="linenumber">1</context>
6251 </context-group>
6252 </trans-unit>
4190 <trans-unit id="f1abd89c9280323209e939fa9c30f6e5cda20c95"> 6253 <trans-unit id="f1abd89c9280323209e939fa9c30f6e5cda20c95">
4191 <source>Do you really want to delete this video?</source> 6254 <source>Do you really want to delete this video?</source>
4192 <target>¿De verdad quieres eliminar este vídeo?</target> 6255 <target>¿De verdad quieres eliminar este vídeo?</target>
@@ -4215,5 +6278,12 @@ Enhorabuena, el vídeo sera importado con BitTorrent! Ya puedes añadir informac
4215 <context context-type="linenumber">1</context> 6278 <context context-type="linenumber">1</context>
4216 </context-group> 6279 </context-group>
4217 </trans-unit> 6280 </trans-unit>
6281 <trans-unit id="1b157e15c434469d91e56d027b78bf69c9983165">
6282 <source>Videos from your subscriptions</source>
6283 <target>Vídeos desde sus suscripciones</target>
6284 <context-group name="null">
6285 <context context-type="linenumber">1</context>
6286 </context-group>
6287 </trans-unit>
4218 </body> 6288 </body>
4219 </file></xliff> \ No newline at end of file 6289 </file></xliff> \ No newline at end of file
diff --git a/client/src/locale/target/angular_eu_ES.xml b/client/src/locale/target/angular_eu_ES.xml
index d30351a35..0393ab85c 100644
--- a/client/src/locale/target/angular_eu_ES.xml
+++ b/client/src/locale/target/angular_eu_ES.xml
@@ -499,7 +499,7 @@
499 <source>Password</source> 499 <source>Password</source>
500 <target>Pasahitza</target> 500 <target>Pasahitza</target>
501 <context-group name="null"> 501 <context-group name="null">
502 <context context-type="linenumber">12</context> 502 <context context-type="linenumber">13</context>
503 </context-group> 503 </context-group>
504 </trans-unit> 504 </trans-unit>
505 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 505 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -513,7 +513,7 @@
513 <source>Login</source> 513 <source>Login</source>
514 <target>Hasi saioa</target> 514 <target>Hasi saioa</target>
515 <context-group name="null"> 515 <context-group name="null">
516 <context context-type="linenumber">38</context> 516 <context context-type="linenumber">36</context>
517 </context-group> 517 </context-group>
518 </trans-unit> 518 </trans-unit>
519 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 519 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -541,7 +541,7 @@
541 <source>Send me an email to reset my password</source> 541 <source>Send me an email to reset my password</source>
542 <target>Bidali e-mail bat nire pasahitza berrezartzeko</target> 542 <target>Bidali e-mail bat nire pasahitza berrezartzeko</target>
543 <context-group name="null"> 543 <context-group name="null">
544 <context context-type="linenumber">75</context> 544 <context context-type="linenumber">80</context>
545 </context-group> 545 </context-group>
546 </trans-unit> 546 </trans-unit>
547 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 547 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -601,11 +601,18 @@
601 <context context-type="linenumber">17</context> 601 <context context-type="linenumber">17</context>
602 </context-group> 602 </context-group>
603 </trans-unit> 603 </trans-unit>
604 <trans-unit id="7fe213724c4c0a4112c40c673884acb98a0a3b92">
605 <source>I am at least 16 years old and agree to the &lt;a href='/about/instance#terms-section' target='_blank'rel='noopener noreferrer'&gt;Terms&lt;/a&gt; of this instance</source>
606 <target>16 urte edo gehiago ditut eta onartzen ditut instantzia honen &lt;a href='/about/instance#terms-section' target='_blank'rel='noopener noreferrer'&gt;erabilera badintzak&lt;/a&gt;</target>
607 <context-group name="null">
608 <context context-type="linenumber">55</context>
609 </context-group>
610 </trans-unit>
604 <trans-unit id="717a5e3574fec754fbeb348c2d5561c4d81facc4"> 611 <trans-unit id="717a5e3574fec754fbeb348c2d5561c4d81facc4">
605 <source>Signup</source> 612 <source>Signup</source>
606 <target>Eman izena</target> 613 <target>Eman izena</target>
607 <context-group name="null"> 614 <context-group name="null">
608 <context context-type="linenumber">88</context> 615 <context context-type="linenumber">78</context>
609 </context-group> 616 </context-group>
610 </trans-unit> 617 </trans-unit>
611 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 618 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -633,6 +640,19 @@
633 <context context-type="linenumber">6</context> 640 <context context-type="linenumber">6</context>
634 </context-group> 641 </context-group>
635 </trans-unit> 642 </trans-unit>
643 <trans-unit id="7c603b9ed878097782e2b8908f662e2344b46061">
644 <source>
645 Filters
646 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/><x id="INTERPOLATION" equiv-text="{{ numberOfFilters() }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
647 </source>
648 <target>
649 Iragazkiak
650 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/><x id="INTERPOLATION" equiv-text="{{ numberOfFilters() }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
651 </target>
652 <context-group name="null">
653 <context context-type="linenumber">16</context>
654 </context-group>
655 </trans-unit>
636 <trans-unit id="e2dbf0426cbb0b573faf49dffeb7d5bdf16eda5d"> 656 <trans-unit id="e2dbf0426cbb0b573faf49dffeb7d5bdf16eda5d">
637 <source> 657 <source>
638 No results found 658 No results found
@@ -662,7 +682,7 @@
662 <source>Change the language</source> 682 <source>Change the language</source>
663 <target>Aldatu hizkuntza</target> 683 <target>Aldatu hizkuntza</target>
664 <context-group name="null"> 684 <context-group name="null">
665 <context context-type="linenumber">88</context> 685 <context context-type="linenumber">86</context>
666 </context-group> 686 </context-group>
667 </trans-unit> 687 </trans-unit>
668 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 688 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -673,7 +693,7 @@
673 Nire profil publikoa 693 Nire profil publikoa
674 </target> 694 </target>
675 <context-group name="null"> 695 <context-group name="null">
676 <context context-type="linenumber">18</context> 696 <context context-type="linenumber">16</context>
677 </context-group> 697 </context-group>
678 </trans-unit> 698 </trans-unit>
679 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 699 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -684,7 +704,7 @@
684 Nire kontua 704 Nire kontua
685 </target> 705 </target>
686 <context-group name="null"> 706 <context-group name="null">
687 <context context-type="linenumber">22</context> 707 <context context-type="linenumber">20</context>
688 </context-group> 708 </context-group>
689 </trans-unit> 709 </trans-unit>
690 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 710 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -695,7 +715,7 @@
695 Nire bideoak 715 Nire bideoak
696 </target> 716 </target>
697 <context-group name="null"> 717 <context-group name="null">
698 <context context-type="linenumber">26</context> 718 <context context-type="linenumber">24</context>
699 </context-group> 719 </context-group>
700 </trans-unit> 720 </trans-unit>
701 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 721 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -706,14 +726,14 @@
706 Amaitu saioa 726 Amaitu saioa
707 </target> 727 </target>
708 <context-group name="null"> 728 <context-group name="null">
709 <context context-type="linenumber">30</context> 729 <context context-type="linenumber">28</context>
710 </context-group> 730 </context-group>
711 </trans-unit> 731 </trans-unit>
712 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 732 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
713 <source>Create an account</source> 733 <source>Create an account</source>
714 <target>Sortu kontu bat</target> 734 <target>Sortu kontu bat</target>
715 <context-group name="null"> 735 <context-group name="null">
716 <context context-type="linenumber">39</context> 736 <context context-type="linenumber">37</context>
717 </context-group> 737 </context-group>
718 </trans-unit> 738 </trans-unit>
719 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 739 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -727,49 +747,49 @@
727 <source>Subscriptions</source> 747 <source>Subscriptions</source>
728 <target>Harpidetzak</target> 748 <target>Harpidetzak</target>
729 <context-group name="null"> 749 <context-group name="null">
730 <context context-type="linenumber">47</context> 750 <context context-type="linenumber">45</context>
731 </context-group> 751 </context-group>
732 </trans-unit> 752 </trans-unit>
733 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 753 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
734 <source>Overview</source> 754 <source>Overview</source>
735 <target>Gainbegirada</target> 755 <target>Gainbegirada</target>
736 <context-group name="null"> 756 <context-group name="null">
737 <context context-type="linenumber">52</context> 757 <context context-type="linenumber">50</context>
738 </context-group> 758 </context-group>
739 </trans-unit> 759 </trans-unit>
740 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 760 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
741 <source>Trending</source> 761 <source>Trending</source>
742 <target>Joerak</target> 762 <target>Joerak</target>
743 <context-group name="null"> 763 <context-group name="null">
744 <context context-type="linenumber">57</context> 764 <context context-type="linenumber">55</context>
745 </context-group> 765 </context-group>
746 </trans-unit> 766 </trans-unit>
747 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 767 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
748 <source>Recently added</source> 768 <source>Recently added</source>
749 <target>Gehitutako azkenak</target> 769 <target>Gehitutako azkenak</target>
750 <context-group name="null"> 770 <context-group name="null">
751 <context context-type="linenumber">62</context> 771 <context context-type="linenumber">60</context>
752 </context-group> 772 </context-group>
753 </trans-unit> 773 </trans-unit>
754 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 774 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
755 <source>Local</source> 775 <source>Local</source>
756 <target>Tokikoa</target> 776 <target>Tokikoa</target>
757 <context-group name="null"> 777 <context-group name="null">
758 <context context-type="linenumber">67</context> 778 <context context-type="linenumber">65</context>
759 </context-group> 779 </context-group>
760 </trans-unit> 780 </trans-unit>
761 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 781 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
762 <source>More</source> 782 <source>More</source>
763 <target>Gehiago</target> 783 <target>Gehiago</target>
764 <context-group name="null"> 784 <context-group name="null">
765 <context context-type="linenumber">72</context> 785 <context context-type="linenumber">70</context>
766 </context-group> 786 </context-group>
767 </trans-unit> 787 </trans-unit>
768 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 788 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
769 <source>Administration</source> 789 <source>Administration</source>
770 <target>Administrazioa</target> 790 <target>Administrazioa</target>
771 <context-group name="null"> 791 <context-group name="null">
772 <context context-type="linenumber">76</context> 792 <context context-type="linenumber">74</context>
773 </context-group> 793 </context-group>
774 </trans-unit> 794 </trans-unit>
775 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 795 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -783,14 +803,14 @@
783 <source>Show keyboard shortcuts</source> 803 <source>Show keyboard shortcuts</source>
784 <target>Erakutsi teklatu-lasterbideak</target> 804 <target>Erakutsi teklatu-lasterbideak</target>
785 <context-group name="null"> 805 <context-group name="null">
786 <context context-type="linenumber">91</context> 806 <context context-type="linenumber">89</context>
787 </context-group> 807 </context-group>
788 </trans-unit> 808 </trans-unit>
789 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 809 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
790 <source>Toggle dark interface</source> 810 <source>Toggle dark interface</source>
791 <target>Txandakatu interfaze iluna</target> 811 <target>Txandakatu interfaze iluna</target>
792 <context-group name="null"> 812 <context-group name="null">
793 <context context-type="linenumber">94</context> 813 <context context-type="linenumber">92</context>
794 </context-group> 814 </context-group>
795 </trans-unit> 815 </trans-unit>
796 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 816 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -895,14 +915,14 @@
895 <source>Display unlisted and private videos</source> 915 <source>Display unlisted and private videos</source>
896 <target>Bistaratu zerrendatu gabeko bideoak eta bideo pribatuak</target> 916 <target>Bistaratu zerrendatu gabeko bideoak eta bideo pribatuak</target>
897 <context-group name="null"> 917 <context-group name="null">
898 <context context-type="linenumber">11</context> 918 <context context-type="linenumber">14</context>
899 </context-group> 919 </context-group>
900 </trans-unit> 920 </trans-unit>
901 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 921 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
902 <source>No results.</source> 922 <source>No results.</source>
903 <target>Emaitzarik ez.</target> 923 <target>Emaitzarik ez.</target>
904 <context-group name="null"> 924 <context-group name="null">
905 <context context-type="linenumber">17</context> 925 <context context-type="linenumber">20</context>
906 </context-group> 926 </context-group>
907 </trans-unit> 927 </trans-unit>
908 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 928 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -960,15 +980,22 @@
960 <context context-type="linenumber">7</context> 980 <context context-type="linenumber">7</context>
961 </context-group> 981 </context-group>
962 </trans-unit> 982 </trans-unit>
963 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 983 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
964 <source> 984 <source>
965 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 985 Cancel
966</source> 986 </source>
967 <target> 987 <target>
968 <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instantziari buruz 988 Utzi
969</target> 989 </target>
970 <context-group name="null"> 990 <context-group name="null">
971 <context context-type="linenumber">1</context> 991 <context context-type="linenumber">26</context>
992 </context-group>
993 </trans-unit>
994 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
995 <source>Submit</source>
996 <target>Bidali</target>
997 <context-group name="null">
998 <context context-type="linenumber">31</context>
972 </context-group> 999 </context-group>
973 </trans-unit> 1000 </trans-unit>
974 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 1001 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -982,45 +1009,14 @@
982 <source>Terms</source> 1009 <source>Terms</source>
983 <target>Baldintzak</target> 1010 <target>Baldintzak</target>
984 <context-group name="null"> 1011 <context-group name="null">
985 <context context-type="linenumber">44</context> 1012 <context context-type="linenumber">39</context>
986 </context-group> 1013 </context-group>
987 </trans-unit> 1014 </trans-unit>
988 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 1015 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
989 <source>User registration is allowed and</source> 1016 <source>User registration is allowed and</source>
990 <target>Erabiltzaile berriek izena ematea onartzen da eta</target> 1017 <target>Erabiltzaile berriek izena ematea onartzen da eta</target>
991 <context-group name="null"> 1018 <context-group name="null">
992 <context context-type="linenumber">25</context> 1019 <context context-type="linenumber">29</context>
993 </context-group>
994 </trans-unit>
995 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
996 <source>
997 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
998 </source>
999 <target>
1000 instantzia honek <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> eskaintzen ditu erabiltzaileen bideoetarako oinarrizko kuota gisa.
1001 </target>
1002 <context-group name="null">
1003 <context context-type="linenumber">27</context>
1004 </context-group>
1005 </trans-unit>
1006 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
1007 <source>
1008 this instance provides unlimited space for the videos of its users.
1009 </source>
1010 <target>
1011 instantzia honek mugagabeko espazioa eskaintzen du bere erabiltzaileen bideoetarako. </target>
1012 <context-group name="null">
1013 <context context-type="linenumber">31</context>
1014 </context-group>
1015 </trans-unit>
1016 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
1017 <source>
1018 User registration is currently not allowed.
1019 </source>
1020 <target>
1021Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
1022 <context-group name="null">
1023 <context context-type="linenumber">36</context>
1024 </context-group> 1020 </context-group>
1025 </trans-unit> 1021 </trans-unit>
1026 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 1022 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1239,6 +1235,19 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
1239 <context context-type="linenumber">83</context> 1235 <context context-type="linenumber">83</context>
1240 </context-group> 1236 </context-group>
1241 </trans-unit> 1237 </trans-unit>
1238 <trans-unit id="b1372cb61ca791a0f7f95bf31c86c97df142adc4">
1239 <source>
1240 PeerTube is in its early stages, and want to deliver the best countermeasures possible by the time the stable is released.
1241 In the meantime, we want to test different ideas related to this issue:
1242 </source>
1243 <target>
1244 PeerTube oso berria da oraindik, eta egonkortzen denerako babes-neurri egokienak ezarri nahi ditugu.
1245 Bitartean, hainbat ideia saiatu nahi ditugu gai honen inguruan:
1246 </target>
1247 <context-group name="null">
1248 <context context-type="linenumber">85</context>
1249 </context-group>
1250 </trans-unit>
1242 <trans-unit id="d32608aba08c6bb3cc4e4e8ec6223e5f4e78ca19"> 1251 <trans-unit id="d32608aba08c6bb3cc4e4e8ec6223e5f4e78ca19">
1243 <source>Set a limit to the number of peers sent by the tracker</source> 1252 <source>Set a limit to the number of peers sent by the tracker</source>
1244 <target>Tracker-ak bidaltzen dituen berdin kopurua mugatzea</target> 1253 <target>Tracker-ak bidaltzen dituen berdin kopurua mugatzea</target>
@@ -1362,49 +1371,49 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
1362 <source>Short description</source> 1371 <source>Short description</source>
1363 <target>Deskripzio laburra</target> 1372 <target>Deskripzio laburra</target>
1364 <context-group name="null"> 1373 <context-group name="null">
1365 <context context-type="linenumber">22</context> 1374 <context context-type="linenumber">21</context>
1366 </context-group> 1375 </context-group>
1367 </trans-unit> 1376 </trans-unit>
1368 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1377 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1369 <source>Default client route</source> 1378 <source>Default client route</source>
1370 <target>Lehenetsitako bezeroaren ibilbidea</target> 1379 <target>Lehenetsitako bezeroaren ibilbidea</target>
1371 <context-group name="null"> 1380 <context-group name="null">
1372 <context context-type="linenumber">55</context> 1381 <context context-type="linenumber">48</context>
1373 </context-group> 1382 </context-group>
1374 </trans-unit> 1383 </trans-unit>
1375 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1384 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1376 <source>Videos Overview</source> 1385 <source>Videos Overview</source>
1377 <target>Bideoen gainbegirada</target> 1386 <target>Bideoen gainbegirada</target>
1378 <context-group name="null"> 1387 <context-group name="null">
1379 <context context-type="linenumber">58</context> 1388 <context context-type="linenumber">51</context>
1380 </context-group> 1389 </context-group>
1381 </trans-unit> 1390 </trans-unit>
1382 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1391 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1383 <source>Videos Trending</source> 1392 <source>Videos Trending</source>
1384 <target>Joera diren bideoak</target> 1393 <target>Joera diren bideoak</target>
1385 <context-group name="null"> 1394 <context-group name="null">
1386 <context context-type="linenumber">59</context> 1395 <context context-type="linenumber">52</context>
1387 </context-group> 1396 </context-group>
1388 </trans-unit> 1397 </trans-unit>
1389 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1398 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1390 <source>Videos Recently Added</source> 1399 <source>Videos Recently Added</source>
1391 <target>Azkenaldian gehitutako bidoeak</target> 1400 <target>Azkenaldian gehitutako bidoeak</target>
1392 <context-group name="null"> 1401 <context-group name="null">
1393 <context context-type="linenumber">60</context> 1402 <context context-type="linenumber">53</context>
1394 </context-group> 1403 </context-group>
1395 </trans-unit> 1404 </trans-unit>
1396 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1405 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1397 <source>Local videos</source> 1406 <source>Local videos</source>
1398 <target>Tokiko bideoak</target> 1407 <target>Tokiko bideoak</target>
1399 <context-group name="null"> 1408 <context-group name="null">
1400 <context context-type="linenumber">61</context> 1409 <context context-type="linenumber">54</context>
1401 </context-group> 1410 </context-group>
1402 </trans-unit> 1411 </trans-unit>
1403 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1412 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1404 <source>Policy on videos containing sensitive content</source> 1413 <source>Policy on videos containing sensitive content</source>
1405 <target>Eduki hunkigarria duten bideoen politika</target> 1414 <target>Eduki hunkigarria duten bideoen politika</target>
1406 <context-group name="null"> 1415 <context-group name="null">
1407 <context context-type="linenumber">70</context> 1416 <context context-type="linenumber">61</context>
1408 </context-group> 1417 </context-group>
1409 </trans-unit> 1418 </trans-unit>
1410 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1419 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1439,23 +1448,44 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
1439 <source>Signup enabled</source> 1448 <source>Signup enabled</source>
1440 <target>Izena ematea gaituta</target> 1449 <target>Izena ematea gaituta</target>
1441 <context-group name="null"> 1450 <context-group name="null">
1442 <context context-type="linenumber">93</context> 1451 <context context-type="linenumber">84</context>
1443 </context-group> 1452 </context-group>
1444 </trans-unit> 1453 </trans-unit>
1445 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1454 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1446 <source>Signup requires email verification</source> 1455 <source>Signup requires email verification</source>
1447 <target>Izena emateko e-mail helbidea baieztatu behar da</target> 1456 <target>Izena emateko e-mail helbidea baieztatu behar da</target>
1448 <context-group name="null"> 1457 <context-group name="null">
1449 <context context-type="linenumber">100</context> 1458 <context context-type="linenumber">91</context>
1450 </context-group> 1459 </context-group>
1451 </trans-unit> 1460 </trans-unit>
1452 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1461 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1453 <source>Signup limit</source> 1462 <source>Signup limit</source>
1454 <target>Izena emateko muga</target> 1463 <target>Izena emateko muga</target>
1455 <context-group name="null"> 1464 <context-group name="null">
1465 <context context-type="linenumber">96</context>
1466 </context-group>
1467 </trans-unit>
1468 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1469 <source>Users</source>
1470 <target>Erabiltzaileak</target>
1471 <context-group name="null">
1456 <context context-type="linenumber">105</context> 1472 <context context-type="linenumber">105</context>
1457 </context-group> 1473 </context-group>
1458 </trans-unit> 1474 </trans-unit>
1475 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1476 <source>User default video quota</source>
1477 <target>Erabiltzailearen lehenetsitako bideo-kuota</target>
1478 <context-group name="null">
1479 <context context-type="linenumber">109</context>
1480 </context-group>
1481 </trans-unit>
1482 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1483 <source>User default daily upload limit</source>
1484 <target>Erabiltzailearentzat lehenetsitako eguneko igoera muga</target>
1485 <context-group name="null">
1486 <context context-type="linenumber">121</context>
1487 </context-group>
1488 </trans-unit>
1459 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1489 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1460 <source>Import</source> 1490 <source>Import</source>
1461 <target>Inportatu</target> 1491 <target>Inportatu</target>
@@ -1467,49 +1497,28 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
1467 <source>Video import with HTTP URL (i.e. YouTube) enabled</source> 1497 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1468 <target>HTTP URL bidezko bideoen inportazioa gaituta (adibidez YouTube)</target> 1498 <target>HTTP URL bidezko bideoen inportazioa gaituta (adibidez YouTube)</target>
1469 <context-group name="null"> 1499 <context-group name="null">
1470 <context context-type="linenumber">120</context> 1500 <context context-type="linenumber">141</context>
1471 </context-group> 1501 </context-group>
1472 </trans-unit> 1502 </trans-unit>
1473 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e"> 1503 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e">
1474 <source>Video import with a torrent file or a magnet URI enabled</source> 1504 <source>Video import with a torrent file or a magnet URI enabled</source>
1475 <target>Bideoa torrent fitxategia edo magnet URL bidez inportatzea gaituta</target> 1505 <target>Bideoa torrent fitxategia edo magnet URL bidez inportatzea gaituta</target>
1476 <context-group name="null"> 1506 <context-group name="null">
1477 <context context-type="linenumber">127</context> 1507 <context context-type="linenumber">148</context>
1478 </context-group> 1508 </context-group>
1479 </trans-unit> 1509 </trans-unit>
1480 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1510 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1481 <source>Administrator</source> 1511 <source>Administrator</source>
1482 <target>Administratzailea</target> 1512 <target>Administratzailea</target>
1483 <context-group name="null"> 1513 <context-group name="null">
1484 <context context-type="linenumber">131</context> 1514 <context context-type="linenumber">155</context>
1485 </context-group> 1515 </context-group>
1486 </trans-unit> 1516 </trans-unit>
1487 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1517 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1488 <source>Admin email</source> 1518 <source>Admin email</source>
1489 <target>Administratzailearen e-maila</target> 1519 <target>Administratzailearen e-maila</target>
1490 <context-group name="null"> 1520 <context-group name="null">
1491 <context context-type="linenumber">134</context> 1521 <context context-type="linenumber">158</context>
1492 </context-group>
1493 </trans-unit>
1494 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1495 <source>Users</source>
1496 <target>Erabiltzaileak</target>
1497 <context-group name="null">
1498 <context context-type="linenumber">144</context>
1499 </context-group>
1500 </trans-unit>
1501 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1502 <source>User default video quota</source>
1503 <target>Erabiltzailearen lehenetsitako bideo-kuota</target>
1504 <context-group name="null">
1505 <context context-type="linenumber">147</context>
1506 </context-group>
1507 </trans-unit>
1508 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1509 <source>User default daily upload limit</source>
1510 <target>Erabiltzailearentzat lehenetsitako eguneko igoera muga</target>
1511 <context-group name="null">
1512 <context context-type="linenumber">161</context>
1513 </context-group> 1522 </context-group>
1514 </trans-unit> 1523 </trans-unit>
1515 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1524 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1530,21 +1539,21 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
1530 <source>Your Twitter username</source> 1539 <source>Your Twitter username</source>
1531 <target>Zure Twitter erabiltzaile-izena</target> 1540 <target>Zure Twitter erabiltzaile-izena</target>
1532 <context-group name="null"> 1541 <context-group name="null">
1533 <context context-type="linenumber">181</context> 1542 <context context-type="linenumber">184</context>
1534 </context-group> 1543 </context-group>
1535 </trans-unit> 1544 </trans-unit>
1536 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1545 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1537 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1546 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1538 <target>Edukia argitaratuko den webgune edo plataformarentzat Twitter kontua adierazten du.</target> 1547 <target>Edukia argitaratuko den webgune edo plataformarentzat Twitter kontua adierazten du.</target>
1539 <context-group name="null"> 1548 <context-group name="null">
1540 <context context-type="linenumber">184</context> 1549 <context context-type="linenumber">187</context>
1541 </context-group> 1550 </context-group>
1542 </trans-unit> 1551 </trans-unit>
1543 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1552 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1544 <source>Instance whitelisted by Twitter</source> 1553 <source>Instance whitelisted by Twitter</source>
1545 <target>Twitter-ek onartutako instantzia</target> 1554 <target>Twitter-ek onartutako instantzia</target>
1546 <context-group name="null"> 1555 <context-group name="null">
1547 <context context-type="linenumber">198</context> 1556 <context context-type="linenumber">199</context>
1548 </context-group> 1557 </context-group>
1549 </trans-unit> 1558 </trans-unit>
1550 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1559 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1558,35 +1567,35 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
1558 <source>Transcoding</source> 1567 <source>Transcoding</source>
1559 <target>Transkodeketa</target> 1568 <target>Transkodeketa</target>
1560 <context-group name="null"> 1569 <context-group name="null">
1561 <context context-type="linenumber">210</context> 1570 <context context-type="linenumber">215</context>
1562 </context-group> 1571 </context-group>
1563 </trans-unit> 1572 </trans-unit>
1564 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1573 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1565 <source>Transcoding enabled</source> 1574 <source>Transcoding enabled</source>
1566 <target>Transkodeketa gaituta</target> 1575 <target>Transkodeketa gaituta</target>
1567 <context-group name="null"> 1576 <context-group name="null">
1568 <context context-type="linenumber">215</context> 1577 <context context-type="linenumber">221</context>
1569 </context-group> 1578 </context-group>
1570 </trans-unit> 1579 </trans-unit>
1571 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1580 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1572 <source>If you disable transcoding, many videos from your users will not work!</source> 1581 <source>If you disable transcoding, many videos from your users will not work!</source>
1573 <target>Transkodeketa desgaitzen baduzu, erabiltzaileen bideo askok ez dute funtzionatuko!</target> 1582 <target>Transkodeketa desgaitzen baduzu, erabiltzaileen bideo askok ez dute funtzionatuko!</target>
1574 <context-group name="null"> 1583 <context-group name="null">
1575 <context context-type="linenumber">216</context> 1584 <context context-type="linenumber">222</context>
1576 </context-group> 1585 </context-group>
1577 </trans-unit> 1586 </trans-unit>
1578 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1587 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1579 <source>Transcoding threads</source> 1588 <source>Transcoding threads</source>
1580 <target>Transkodetze hariak</target> 1589 <target>Transkodetze hariak</target>
1581 <context-group name="null"> 1590 <context-group name="null">
1582 <context context-type="linenumber">223</context> 1591 <context context-type="linenumber">237</context>
1583 </context-group> 1592 </context-group>
1584 </trans-unit> 1593 </trans-unit>
1585 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1594 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1586 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1595 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1587 <target><x id="INTERPOLATION" equiv-text="{{resolution}}"/> bereizmena gaituta</target> 1596 <target><x id="INTERPOLATION" equiv-text="{{resolution}}"/> bereizmena gaituta</target>
1588 <context-group name="null"> 1597 <context-group name="null">
1589 <context context-type="linenumber">239</context> 1598 <context context-type="linenumber">252</context>
1590 </context-group> 1599 </context-group>
1591 </trans-unit> 1600 </trans-unit>
1592 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1601 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1601,83 +1610,48 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
1601 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1610 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1602 </target> 1611 </target>
1603 <context-group name="null"> 1612 <context-group name="null">
1604 <context context-type="linenumber">244</context> 1613 <context context-type="linenumber">260</context>
1605 </context-group> 1614 </context-group>
1606 </trans-unit> 1615 </trans-unit>
1607 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1616 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1608 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1617 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1609 <target>Fitxategi batzuk ez dira federatzen (aurrebistak, azpitituluak). Zuzenean jatorrizko instantziatik jasotzen ditugu eta cachean gorde.</target> 1618 <target>Fitxategi batzuk ez dira federatzen (aurrebistak, azpitituluak). Zuzenean jatorrizko instantziatik jasotzen ditugu eta cachean gorde.</target>
1610 <context-group name="null"> 1619 <context-group name="null">
1611 <context context-type="linenumber">249</context> 1620 <context context-type="linenumber">265</context>
1612 </context-group> 1621 </context-group>
1613 </trans-unit> 1622 </trans-unit>
1614 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1623 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1615 <source>Previews cache size</source> 1624 <source>Previews cache size</source>
1616 <target>Aurrebisten cachearen tamaina</target> 1625 <target>Aurrebisten cachearen tamaina</target>
1617 <context-group name="null"> 1626 <context-group name="null">
1618 <context context-type="linenumber">254</context> 1627 <context context-type="linenumber">271</context>
1619 </context-group> 1628 </context-group>
1620 </trans-unit> 1629 </trans-unit>
1621 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1630 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1622 <source>Video captions cache size</source> 1631 <source>Video captions cache size</source>
1623 <target>Bideoaren azpitituluen cachearen tamaina</target> 1632 <target>Bideoaren azpitituluen cachearen tamaina</target>
1624 <context-group name="null"> 1633 <context-group name="null">
1625 <context context-type="linenumber">265</context> 1634 <context context-type="linenumber">280</context>
1626 </context-group> 1635 </context-group>
1627 </trans-unit> 1636 </trans-unit>
1628 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1637 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1629 <source>Customizations</source> 1638 <source>Customizations</source>
1630 <target>Pertsonalizazioak</target> 1639 <target>Pertsonalizazioak</target>
1631 <context-group name="null"> 1640 <context-group name="null">
1632 <context context-type="linenumber">275</context> 1641 <context context-type="linenumber">289</context>
1633 </context-group> 1642 </context-group>
1634 </trans-unit> 1643 </trans-unit>
1635 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1644 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1636 <source>JavaScript</source> 1645 <source>JavaScript</source>
1637 <target>JavaScript</target> 1646 <target>JavaScript</target>
1638 <context-group name="null"> 1647 <context-group name="null">
1639 <context context-type="linenumber">278</context> 1648 <context context-type="linenumber">294</context>
1640 </context-group> 1649 </context-group>
1641 </trans-unit> 1650 </trans-unit>
1642 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1651 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1643 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1652 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1644 <target>IdatziJavaScript kodea zuzenean.&lt;br /&gt;Adibidez: &lt;pre&gt;console.log('nire instantzia zoragarria da');&lt;/pre&gt;</target> 1653 <target>IdatziJavaScript kodea zuzenean.&lt;br /&gt;Adibidez: &lt;pre&gt;console.log('nire instantzia zoragarria da');&lt;/pre&gt;</target>
1645 <context-group name="null"> 1654 <context-group name="null">
1646 <context context-type="linenumber">281</context>
1647 </context-group>
1648 </trans-unit>
1649 <trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5">
1650 <source>
1651 Write directly CSS code. Example:&lt;br /&gt;
1652 &lt;pre&gt;
1653 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1654 background-color: red;
1655 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1656 &lt;/pre&gt;
1657
1658 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1659 &lt;pre&gt;
1660 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1661 color: red;
1662 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1663 &lt;/pre&gt;
1664 </source>
1665 <target>
1666 Idatzi CSS kodea zuzenean. Adibidez:&lt;br /&gt;
1667 &lt;pre&gt;
1668 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1669 background-color: red;
1670 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1671 &lt;/pre&gt;
1672
1673 Idatzi aurretik &lt;em&gt;#custom-css&lt;/em&gt; estiloak gainidazteko. Adibidez:
1674 &lt;pre&gt;
1675 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1676 color: red;
1677 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1678 &lt;/pre&gt;
1679 </target>
1680 <context-group name="null">
1681 <context context-type="linenumber">297</context> 1655 <context context-type="linenumber">297</context>
1682 </context-group> 1656 </context-group>
1683 </trans-unit> 1657 </trans-unit>
@@ -1685,21 +1659,21 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
1685 <source>Advanced configuration</source> 1659 <source>Advanced configuration</source>
1686 <target>Konfigurazio aurreratua</target> 1660 <target>Konfigurazio aurreratua</target>
1687 <context-group name="null"> 1661 <context-group name="null">
1688 <context context-type="linenumber">207</context> 1662 <context context-type="linenumber">212</context>
1689 </context-group> 1663 </context-group>
1690 </trans-unit> 1664 </trans-unit>
1691 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1665 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1692 <source>Update configuration</source> 1666 <source>Update configuration</source>
1693 <target>Eguneratu konfigurazioa</target> 1667 <target>Eguneratu konfigurazioa</target>
1694 <context-group name="null"> 1668 <context-group name="null">
1695 <context context-type="linenumber">325</context> 1669 <context context-type="linenumber">340</context>
1696 </context-group> 1670 </context-group>
1697 </trans-unit> 1671 </trans-unit>
1698 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1672 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1699 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1673 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1700 <target>Konfigurazioa baliogabea dela dirudi. Bilatu zer egon daitekeen gaizki fitxa desberdinetan begiratuz.</target> 1674 <target>Konfigurazioa baliogabea dela dirudi. Bilatu zer egon daitekeen gaizki fitxa desberdinetan begiratuz.</target>
1701 <context-group name="null"> 1675 <context-group name="null">
1702 <context context-type="linenumber">326</context> 1676 <context context-type="linenumber">341</context>
1703 </context-group> 1677 </context-group>
1704 </trans-unit> 1678 </trans-unit>
1705 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1679 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1984,11 +1958,25 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
1984 <context context-type="linenumber">133</context> 1958 <context context-type="linenumber">133</context>
1985 </context-group> 1959 </context-group>
1986 </trans-unit> 1960 </trans-unit>
1961 <trans-unit id="02ba1a65db92d1d0ab4ba380086e9be61891aaa5">
1962 <source>User's email must be verified to login</source>
1963 <target>Erabiltzailearen e-mail helbidea baieztatu behar da saioa hasi aurretik</target>
1964 <context-group name="null">
1965 <context context-type="linenumber">72</context>
1966 </context-group>
1967 </trans-unit>
1968 <trans-unit id="79cee9973620b2592ff2824c525aa8ed0b5e2b8b">
1969 <source>User's email is verified / User can login without email verification</source>
1970 <target>Erabiltzailearen e-mail helbidea baieztatuta dago / Erabiltzaileak e-mail helbidea baieztatu gabe saioa hasi dezake</target>
1971 <context-group name="null">
1972 <context context-type="linenumber">76</context>
1973 </context-group>
1974 </trans-unit>
1987 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee"> 1975 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee">
1988 <source>Ban reason:</source> 1976 <source>Ban reason:</source>
1989 <target>Debekatzeko arrazoia:</target> 1977 <target>Debekatzeko arrazoia:</target>
1990 <context-group name="null"> 1978 <context-group name="null">
1991 <context context-type="linenumber">92</context> 1979 <context context-type="linenumber">95</context>
1992 </context-group> 1980 </context-group>
1993 </trans-unit> 1981 </trans-unit>
1994 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 1982 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -2055,7 +2043,7 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
2055 <source>Actions</source> 2043 <source>Actions</source>
2056 <target>Ekintzak</target> 2044 <target>Ekintzak</target>
2057 <context-group name="null"> 2045 <context-group name="null">
2058 <context context-type="linenumber">33</context> 2046 <context context-type="linenumber">35</context>
2059 </context-group> 2047 </context-group>
2060 </trans-unit> 2048 </trans-unit>
2061 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 2049 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -2090,14 +2078,14 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
2090 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 2078 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2091 <target>Data <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 2079 <target>Data <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2092 <context-group name="null"> 2080 <context-group name="null">
2093 <context context-type="linenumber">10</context> 2081 <context context-type="linenumber">11</context>
2094 </context-group> 2082 </context-group>
2095 </trans-unit> 2083 </trans-unit>
2096 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f"> 2084 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
2097 <source>Blacklist reason:</source> 2085 <source>Blacklist reason:</source>
2098 <target>Zerrenda beltzean sartzeko arrazoia:</target> 2086 <target>Zerrenda beltzean sartzeko arrazoia:</target>
2099 <context-group name="null"> 2087 <context-group name="null">
2100 <context context-type="linenumber">41</context> 2088 <context context-type="linenumber">43</context>
2101 </context-group> 2089 </context-group>
2102 </trans-unit> 2090 </trans-unit>
2103 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 2091 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -2149,69 +2137,6 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
2149 <context context-type="linenumber">23</context> 2137 <context context-type="linenumber">23</context>
2150 </context-group> 2138 </context-group>
2151 </trans-unit> 2139 </trans-unit>
2152 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2153 <source>My settings</source>
2154 <target>Nire ezarpenak</target>
2155 <context-group name="null">
2156 <context context-type="linenumber">3</context>
2157 </context-group>
2158 </trans-unit>
2159 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2160 <source>My library</source>
2161 <target>Nire liburutegia</target>
2162 <context-group name="null">
2163 <context context-type="linenumber">7</context>
2164 </context-group>
2165 </trans-unit>
2166 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2167 <source>My channels</source>
2168 <target>Nire kanalak</target>
2169 <context-group name="null">
2170 <context context-type="linenumber">12</context>
2171 </context-group>
2172 </trans-unit>
2173 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2174 <source>My videos</source>
2175 <target>Nire bideoak</target>
2176 <context-group name="null">
2177 <context context-type="linenumber">14</context>
2178 </context-group>
2179 </trans-unit>
2180 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2181 <source>My subscriptions</source>
2182 <target>Nire harpidetzak</target>
2183 <context-group name="null">
2184 <context context-type="linenumber">16</context>
2185 </context-group>
2186 </trans-unit>
2187 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
2188 <source>My imports</source>
2189 <target>Nire inportazioak</target>
2190 <context-group name="null">
2191 <context context-type="linenumber">18</context>
2192 </context-group>
2193 </trans-unit>
2194 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
2195 <source>Misc</source>
2196 <target>Denetarik</target>
2197 <context-group name="null">
2198 <context context-type="linenumber">24</context>
2199 </context-group>
2200 </trans-unit>
2201 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2202 <source>Muted instances</source>
2203 <target>Mutututako instantziak</target>
2204 <context-group name="null">
2205 <context context-type="linenumber">2</context>
2206 </context-group>
2207 </trans-unit>
2208 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
2209 <source>Ownership changes</source>
2210 <target>Jabetza aldaketak</target>
2211 <context-group name="null">
2212 <context context-type="linenumber">33</context>
2213 </context-group>
2214 </trans-unit>
2215 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 2140 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
2216 <source>Video quota:</source> 2141 <source>Video quota:</source>
2217 <target>Bideo-kuota:</target> 2142 <target>Bideo-kuota:</target>
@@ -2223,21 +2148,21 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
2223 <source>Profile</source> 2148 <source>Profile</source>
2224 <target>Profila</target> 2149 <target>Profila</target>
2225 <context-group name="null"> 2150 <context-group name="null">
2226 <context context-type="linenumber">8</context> 2151 <context context-type="linenumber">7</context>
2227 </context-group> 2152 </context-group>
2228 </trans-unit> 2153 </trans-unit>
2229 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 2154 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
2230 <source>Video settings</source> 2155 <source>Video settings</source>
2231 <target>Bideo ezarpenak</target> 2156 <target>Bideo ezarpenak</target>
2232 <context-group name="null"> 2157 <context-group name="null">
2233 <context context-type="linenumber">15</context> 2158 <context context-type="linenumber">16</context>
2234 </context-group> 2159 </context-group>
2235 </trans-unit> 2160 </trans-unit>
2236 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 2161 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
2237 <source>Danger zone</source> 2162 <source>Danger zone</source>
2238 <target>Eremu arriskutsua</target> 2163 <target>Eremu arriskutsua</target>
2239 <context-group name="null"> 2164 <context-group name="null">
2240 <context context-type="linenumber">18</context> 2165 <context context-type="linenumber">19</context>
2241 </context-group> 2166 </context-group>
2242 </trans-unit> 2167 </trans-unit>
2243 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 2168 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -2265,13 +2190,6 @@ Erabiltzaile berriek izena ematea ez da onartzen orain.</target>
2265 <context context-type="linenumber">35</context> 2190 <context context-type="linenumber">35</context>
2266 </context-group> 2191 </context-group>
2267 </trans-unit> 2192 </trans-unit>
2268 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
2269 <source>Submit</source>
2270 <target>Bidali</target>
2271 <context-group name="null">
2272 <context context-type="linenumber">24</context>
2273 </context-group>
2274 </trans-unit>
2275 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 2193 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
2276 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 2194 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2277 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> ikustaldi</target> 2195 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> ikustaldi</target>
@@ -2430,6 +2348,13 @@ Kanal honetara bideo bat igotzen duzunean, bideoa babesteko eremua testu honekin
2430 <context context-type="linenumber">47</context> 2348 <context context-type="linenumber">47</context>
2431 </context-group> 2349 </context-group>
2432 </trans-unit> 2350 </trans-unit>
2351 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2352 <source>Muted instances</source>
2353 <target>Mutututako instantziak</target>
2354 <context-group name="null">
2355 <context context-type="linenumber">2</context>
2356 </context-group>
2357 </trans-unit>
2433 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 2358 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
2434 <source>Change password</source> 2359 <source>Change password</source>
2435 <target>Aldatu pasahitza</target> 2360 <target>Aldatu pasahitza</target>
@@ -2465,6 +2390,13 @@ Kanal honetara bideo bat igotzen duzunean, bideoa babesteko eremua testu honekin
2465 <context context-type="linenumber">3</context> 2390 <context context-type="linenumber">3</context>
2466 </context-group> 2391 </context-group>
2467 </trans-unit> 2392 </trans-unit>
2393 <trans-unit id="d044c51156e295824813a866dba9545bdb59466b">
2394 <source>Use WebTorrent to exchange parts of the video with others</source>
2395 <target>Erabili WebTorrent bideoaren zatiak besteekin partekatzeko</target>
2396 <context-group name="null">
2397 <context context-type="linenumber">21</context>
2398 </context-group>
2399 </trans-unit>
2468 <trans-unit id="fb17c44abac2d1ed2a54cdd28bae289dc0b9a1c2"> 2400 <trans-unit id="fb17c44abac2d1ed2a54cdd28bae289dc0b9a1c2">
2469 <source>Automatically plays video</source> 2401 <source>Automatically plays video</source>
2470 <target>Automatikoki abiatzen du bideoa</target> 2402 <target>Automatikoki abiatzen du bideoa</target>
@@ -2507,6 +2439,13 @@ Kanal honetara bideo bat igotzen duzunean, bideoa babesteko eremua testu honekin
2507 <context context-type="linenumber">18</context> 2439 <context context-type="linenumber">18</context>
2508 </context-group> 2440 </context-group>
2509 </trans-unit> 2441 </trans-unit>
2442 <trans-unit id="d1a04ba05116499d4cf59a48a282a8bcbf5b622d">
2443 <source>Once you delete your account, there is no going back. Please be certain.</source>
2444 <target>Behin kontua ezabatuta ez dago atzera egiterik. Ziurtatu hau dela nahi duzuna.</target>
2445 <context-group name="null">
2446 <context context-type="linenumber">2</context>
2447 </context-group>
2448 </trans-unit>
2510 <trans-unit id="9a2f889dde4574a6883c853d1034e75891b28c45"> 2449 <trans-unit id="9a2f889dde4574a6883c853d1034e75891b28c45">
2511 <source>Delete your account</source> 2450 <source>Delete your account</source>
2512 <target>Ezabatu zure kontua</target> 2451 <target>Ezabatu zure kontua</target>
@@ -2621,6 +2560,13 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
2621 <context context-type="linenumber">159</context> 2560 <context context-type="linenumber">159</context>
2622 </context-group> 2561 </context-group>
2623 </trans-unit> 2562 </trans-unit>
2563 <trans-unit id="385811ab5a5c3e96e0db46c9ce1fc3147d8cd4c7">
2564 <source>Sorry, but something went wrong</source>
2565 <target>Akatsen bat egon da</target>
2566 <context-group name="null">
2567 <context context-type="linenumber">49</context>
2568 </context-group>
2569 </trans-unit>
2624 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2"> 2570 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2">
2625 <source> 2571 <source>
2626 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video. 2572 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video.
@@ -2657,14 +2603,14 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
2657 <source>Publish will be available when upload is finished</source> 2603 <source>Publish will be available when upload is finished</source>
2658 <target>Argitaratzea behin igoera bukatzean egongo da erabilgarri</target> 2604 <target>Argitaratzea behin igoera bukatzean egongo da erabilgarri</target>
2659 <context-group name="null"> 2605 <context-group name="null">
2660 <context context-type="linenumber">53</context> 2606 <context context-type="linenumber">58</context>
2661 </context-group> 2607 </context-group>
2662 </trans-unit> 2608 </trans-unit>
2663 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 2609 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2664 <source>Publish</source> 2610 <source>Publish</source>
2665 <target>Argitaratu</target> 2611 <target>Argitaratu</target>
2666 <context-group name="null"> 2612 <context-group name="null">
2667 <context context-type="linenumber">60</context> 2613 <context context-type="linenumber">65</context>
2668 </context-group> 2614 </context-group>
2669 </trans-unit> 2615 </trans-unit>
2670 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 2616 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -2847,14 +2793,14 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
2847 <source>Wait transcoding before publishing the video</source> 2793 <source>Wait transcoding before publishing the video</source>
2848 <target>Itxaron transkodetzeari bideoa argitaratu aurretik</target> 2794 <target>Itxaron transkodetzeari bideoa argitaratu aurretik</target>
2849 <context-group name="null"> 2795 <context-group name="null">
2850 <context context-type="linenumber">130</context> 2796 <context context-type="linenumber">131</context>
2851 </context-group> 2797 </context-group>
2852 </trans-unit> 2798 </trans-unit>
2853 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 2799 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2854 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 2800 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
2855 <target>Bideoa argitaratu aurretik ez baduzu transkodetzea bukatu arte itxaroten, bideoa transkodetzea bukatu arte ezin ikustea gerta daiteke.</target> 2801 <target>Bideoa argitaratu aurretik ez baduzu transkodetzea bukatu arte itxaroten, bideoa transkodetzea bukatu arte ezin ikustea gerta daiteke.</target>
2856 <context-group name="null"> 2802 <context-group name="null">
2857 <context context-type="linenumber">131</context> 2803 <context context-type="linenumber">132</context>
2858 </context-group> 2804 </context-group>
2859 </trans-unit> 2805 </trans-unit>
2860 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2806 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2868,56 +2814,81 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
2868 <source>Add another caption</source> 2814 <source>Add another caption</source>
2869 <target>Gehitu beste azpititulu bat</target> 2815 <target>Gehitu beste azpititulu bat</target>
2870 <context-group name="null"> 2816 <context-group name="null">
2871 <context context-type="linenumber">146</context> 2817 <context context-type="linenumber">147</context>
2872 </context-group> 2818 </context-group>
2873 </trans-unit> 2819 </trans-unit>
2874 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 2820 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2875 <source>See the subtitle file</source> 2821 <source>See the subtitle file</source>
2876 <target>Ikusi azpitituluen fitxategia</target> 2822 <target>Ikusi azpitituluen fitxategia</target>
2877 <context-group name="null"> 2823 <context-group name="null">
2878 <context context-type="linenumber">155</context> 2824 <context context-type="linenumber">156</context>
2879 </context-group> 2825 </context-group>
2880 </trans-unit> 2826 </trans-unit>
2881 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee"> 2827 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee">
2882 <source>Already uploaded ✔</source> 2828 <source>Already uploaded ✔</source>
2883 <target>Jadanik igota ✔</target> 2829 <target>Jadanik igota ✔</target>
2884 <context-group name="null"> 2830 <context-group name="null">
2885 <context context-type="linenumber">159</context> 2831 <context context-type="linenumber">160</context>
2832 </context-group>
2833 </trans-unit>
2834 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad">
2835 <source>Will be created on update</source>
2836 <target>Eguneratzean sortuko da</target>
2837 <context-group name="null">
2838 <context context-type="linenumber">168</context>
2886 </context-group> 2839 </context-group>
2887 </trans-unit> 2840 </trans-unit>
2888 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 2841 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2889 <source>Cancel create</source> 2842 <source>Cancel create</source>
2890 <target>Ezeztatu sorkuntza</target> 2843 <target>Ezeztatu sorkuntza</target>
2891 <context-group name="null"> 2844 <context-group name="null">
2892 <context context-type="linenumber">169</context> 2845 <context context-type="linenumber">170</context>
2846 </context-group>
2847 </trans-unit>
2848 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393">
2849 <source>Will be deleted on update</source>
2850 <target>Eguneratzean ezabatuko da</target>
2851 <context-group name="null">
2852 <context context-type="linenumber">176</context>
2893 </context-group> 2853 </context-group>
2894 </trans-unit> 2854 </trans-unit>
2895 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 2855 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2896 <source>Cancel deletion</source> 2856 <source>Cancel deletion</source>
2897 <target>Ezeztatu ezabaketa</target> 2857 <target>Ezeztatu ezabaketa</target>
2898 <context-group name="null"> 2858 <context-group name="null">
2899 <context context-type="linenumber">177</context> 2859 <context context-type="linenumber">178</context>
2860 </context-group>
2861 </trans-unit>
2862 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0">
2863 <source>
2864 No captions for now.
2865 </source>
2866 <target>
2867 Azpititulurik ez oraingoz.
2868 </target>
2869 <context-group name="null">
2870 <context context-type="linenumber">183</context>
2900 </context-group> 2871 </context-group>
2901 </trans-unit> 2872 </trans-unit>
2902 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 2873 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2903 <source>Captions</source> 2874 <source>Captions</source>
2904 <target>Azpitituluak</target> 2875 <target>Azpitituluak</target>
2905 <context-group name="null"> 2876 <context-group name="null">
2906 <context context-type="linenumber">139</context> 2877 <context context-type="linenumber">140</context>
2907 </context-group> 2878 </context-group>
2908 </trans-unit> 2879 </trans-unit>
2909 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 2880 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
2910 <source>Upload thumbnail</source> 2881 <source>Upload thumbnail</source>
2911 <target>Igo irudia</target> 2882 <target>Igo irudia</target>
2912 <context-group name="null"> 2883 <context-group name="null">
2913 <context context-type="linenumber">195</context> 2884 <context context-type="linenumber">196</context>
2914 </context-group> 2885 </context-group>
2915 </trans-unit> 2886 </trans-unit>
2916 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 2887 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
2917 <source>Upload preview</source> 2888 <source>Upload preview</source>
2918 <target>Igo aurrebista</target> 2889 <target>Igo aurrebista</target>
2919 <context-group name="null"> 2890 <context-group name="null">
2920 <context context-type="linenumber">202</context> 2891 <context context-type="linenumber">203</context>
2921 </context-group> 2892 </context-group>
2922 </trans-unit> 2893 </trans-unit>
2923 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 2894 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -2931,14 +2902,14 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
2931 <source>Short text to tell people how they can support you (membership platform...).</source> 2902 <source>Short text to tell people how they can support you (membership platform...).</source>
2932 <target>Jendeari zu nola babestu azaltzeko testu labur bat (kidetza plataforma...).</target> 2903 <target>Jendeari zu nola babestu azaltzeko testu labur bat (kidetza plataforma...).</target>
2933 <context-group name="null"> 2904 <context-group name="null">
2934 <context context-type="linenumber">209</context> 2905 <context context-type="linenumber">210</context>
2935 </context-group> 2906 </context-group>
2936 </trans-unit> 2907 </trans-unit>
2937 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 2908 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
2938 <source>Advanced settings</source> 2909 <source>Advanced settings</source>
2939 <target>Ezarpen aurreratuak</target> 2910 <target>Ezarpen aurreratuak</target>
2940 <context-group name="null"> 2911 <context-group name="null">
2941 <context context-type="linenumber">190</context> 2912 <context context-type="linenumber">191</context>
2942 </context-group> 2913 </context-group>
2943 </trans-unit> 2914 </trans-unit>
2944 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 2915 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -3005,17 +2976,6 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3005 <context context-type="linenumber">3</context> 2976 <context context-type="linenumber">3</context>
3006 </context-group> 2977 </context-group>
3007 </trans-unit> 2978 </trans-unit>
3008 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
3009 <source>
3010 Cancel
3011 </source>
3012 <target>
3013 Utzi
3014 </target>
3015 <context-group name="null">
3016 <context context-type="linenumber">19</context>
3017 </context-group>
3018 </trans-unit>
3019 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 2979 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
3020 <source>Share</source> 2980 <source>Share</source>
3021 <target>Partekatu</target> 2981 <target>Partekatu</target>
@@ -3337,6 +3297,24 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3337 <context context-type="linenumber">20</context> 3297 <context context-type="linenumber">20</context>
3338 </context-group> 3298 </context-group>
3339 </trans-unit> 3299 </trans-unit>
3300 <trans-unit id="8b2bb53dfb5f059f2b68cc4ac00661a865909135">
3301 <source>You are one step away from commenting</source>
3302 <target>Iruzkina egitetik urrats batera zaude</target>
3303 <context-group name="null">
3304 <context context-type="linenumber">28</context>
3305 </context-group>
3306 </trans-unit>
3307 <trans-unit id="7984a44ce86b961f4f18c9a58c638f5e8f07a225">
3308 <source>
3309 If you have an account on this instance, you can login:
3310 </source>
3311 <target>
3312 Instantzia honetan kontua baduzu, saioa hasi dezakezu:
3313 </target>
3314 <context-group name="null">
3315 <context context-type="linenumber">32</context>
3316 </context-group>
3317 </trans-unit>
3340 <trans-unit id="afe0ad39fee662489f1033e53aea3e16a7e89228"> 3318 <trans-unit id="afe0ad39fee662489f1033e53aea3e16a7e89228">
3341 <source>login to comment</source> 3319 <source>login to comment</source>
3342 <target>hasi saioa iruzkinak egiteko</target> 3320 <target>hasi saioa iruzkinak egiteko</target>
@@ -3344,6 +3322,15 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3344 <context context-type="linenumber">35</context> 3322 <context context-type="linenumber">35</context>
3345 </context-group> 3323 </context-group>
3346 </trans-unit> 3324 </trans-unit>
3325 <trans-unit id="968b02fbc645be799727de0d1ec3c6f9b11b20eb">
3326 <source>
3327 If you have an account on Mastodon or Pleroma, you can open it directly in their interface:
3328 </source>
3329 <target>Mastodon edo Pleroma sareetan kontua baduzu, zuzenean ireki dezakezu hango interfazean:</target>
3330 <context-group name="null">
3331 <context context-type="linenumber">41</context>
3332 </context-group>
3333 </trans-unit>
3347 <trans-unit id="a607fab03e11b0e07c1640e11a1b02d7af06b285"> 3334 <trans-unit id="a607fab03e11b0e07c1640e11a1b02d7af06b285">
3348 <source>Highlighted comment</source> 3335 <source>Highlighted comment</source>
3349 <target>Nabarmendutako iruzkina</target> 3336 <target>Nabarmendutako iruzkina</target>
@@ -3358,13 +3345,6 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3358 <context context-type="linenumber">14</context> 3345 <context context-type="linenumber">14</context>
3359 </context-group> 3346 </context-group>
3360 </trans-unit> 3347 </trans-unit>
3361 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
3362 <source>Error getting about from server</source>
3363 <target>Errorea informazioa zerbitzaritik jasotzean</target>
3364 <context-group name="null">
3365 <context context-type="linenumber">1</context>
3366 </context-group>
3367 </trans-unit>
3368 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 3348 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
3369 <source>No description</source> 3349 <source>No description</source>
3370 <target>Deskripziorik ez</target> 3350 <target>Deskripziorik ez</target>
@@ -3386,13 +3366,6 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3386 <context context-type="linenumber">1</context> 3366 <context context-type="linenumber">1</context>
3387 </context-group> 3367 </context-group>
3388 </trans-unit> 3368 </trans-unit>
3389 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
3390 <source>Error</source>
3391 <target>Errorea</target>
3392 <context-group name="null">
3393 <context context-type="linenumber">1</context>
3394 </context-group>
3395 </trans-unit>
3396 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6"> 3369 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
3397 <source>240p</source> 3370 <source>240p</source>
3398 <target>240p</target> 3371 <target>240p</target>
@@ -3435,13 +3408,6 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3435 <context context-type="linenumber">1</context> 3408 <context context-type="linenumber">1</context>
3436 </context-group> 3409 </context-group>
3437 </trans-unit> 3410 </trans-unit>
3438 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
3439 <source>Success</source>
3440 <target>Arrakasta</target>
3441 <context-group name="null">
3442 <context context-type="linenumber">1</context>
3443 </context-group>
3444 </trans-unit>
3445 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 3411 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
3446 <source>Configuration updated.</source> 3412 <source>Configuration updated.</source>
3447 <target>Konfigurazioa eguneratuta.</target> 3413 <target>Konfigurazioa eguneratuta.</target>
@@ -3596,6 +3562,20 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3596 <context context-type="linenumber">1</context> 3562 <context context-type="linenumber">1</context>
3597 </context-group> 3563 </context-group>
3598 </trans-unit> 3564 </trans-unit>
3565 <trans-unit id="53cc0f4a4566c4139c65f93b5dce2fe8302e78da">
3566 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by your instance.</source>
3567 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> kontua zure instantziak desmutututa.</target>
3568 <context-group name="null">
3569 <context context-type="linenumber">1</context>
3570 </context-group>
3571 </trans-unit>
3572 <trans-unit id="468b52e3c04fb9a3d8c8213555dfcad0cbcae330">
3573 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by your instance.</source>
3574 <target><x id="INTERPOLATION" equiv-text="{{host}}"/> instantzia zure instantziak demutututa.</target>
3575 <context-group name="null">
3576 <context context-type="linenumber">1</context>
3577 </context-group>
3578 </trans-unit>
3599 <trans-unit id="800cd3cdf47751b576587259ba3a1bc0a7f435b6"> 3579 <trans-unit id="800cd3cdf47751b576587259ba3a1bc0a7f435b6">
3600 <source>Comment updated.</source> 3580 <source>Comment updated.</source>
3601 <target>Iruzkina eguneratua.</target> 3581 <target>Iruzkina eguneratua.</target>
@@ -3687,6 +3667,13 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3687 <context context-type="linenumber">1</context> 3667 <context context-type="linenumber">1</context>
3688 </context-group> 3668 </context-group>
3689 </trans-unit> 3669 </trans-unit>
3670 <trans-unit id="910ed85f550272401b134a40d019ab3359fe883f">
3671 <source>Set Email as Verified</source>
3672 <target>Ezarri e-maila baieztatua gisa</target>
3673 <context-group name="null">
3674 <context context-type="linenumber">1</context>
3675 </context-group>
3676 </trans-unit>
3690 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf"> 3677 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf">
3691 <source>You cannot ban root.</source> 3678 <source>You cannot ban root.</source>
3692 <target>Ezin duzu root debekatu</target> 3679 <target>Ezin duzu root debekatu</target>
@@ -3694,6 +3681,20 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3694 <context context-type="linenumber">1</context> 3681 <context context-type="linenumber">1</context>
3695 </context-group> 3682 </context-group>
3696 </trans-unit> 3683 </trans-unit>
3684 <trans-unit id="98119091712a8ca72905e3b4c1cf60649af7565e">
3685 <source>Do you really want to unban <x id="INTERPOLATION" equiv-text="{{num}}"/> users?</source>
3686 <target>Ziur <x id="INTERPOLATION" equiv-text="{{num}}"/> erabiltzaileei debekua kendu nahi diozula?</target>
3687 <context-group name="null">
3688 <context context-type="linenumber">1</context>
3689 </context-group>
3690 </trans-unit>
3691 <trans-unit id="6121be086a51c4c73bbdd8aebdddd9744c8f1ffd">
3692 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users unbanned.</source>
3693 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> erabiltzaileei debekua kendu zaie.</target>
3694 <context-group name="null">
3695 <context context-type="linenumber">1</context>
3696 </context-group>
3697 </trans-unit>
3697 <trans-unit id="911fc197949e47aa5f0541627bc319f59edd9d11"> 3698 <trans-unit id="911fc197949e47aa5f0541627bc319f59edd9d11">
3698 <source>You cannot delete root.</source> 3699 <source>You cannot delete root.</source>
3699 <target>Ezin duzu erroa ezabatu.</target> 3700 <target>Ezin duzu erroa ezabatu.</target>
@@ -3708,6 +3709,34 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3708 <context context-type="linenumber">1</context> 3709 <context context-type="linenumber">1</context>
3709 </context-group> 3710 </context-group>
3710 </trans-unit> 3711 </trans-unit>
3712 <trans-unit id="b708d332e3f89b24745e749fa530210f0bdea329">
3713 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users deleted.</source>
3714 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> erabiltzaile ezabatuta.</target>
3715 <context-group name="null">
3716 <context context-type="linenumber">1</context>
3717 </context-group>
3718 </trans-unit>
3719 <trans-unit id="f4a8f2ef1fbfc19e1e049e69f63c40063c0d0650">
3720 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users email set as verified.</source>
3721 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> erabiltzailearen e-mail helbidea baieztatua gisa ezarri da.</target>
3722 <context-group name="null">
3723 <context context-type="linenumber">1</context>
3724 </context-group>
3725 </trans-unit>
3726 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de">
3727 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source>
3728 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> kontua desmutututa.</target>
3729 <context-group name="null">
3730 <context context-type="linenumber">1</context>
3731 </context-group>
3732 </trans-unit>
3733 <trans-unit id="c6af80b42938d4a49e6f6c4f60ce26228916994c">
3734 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted.</source>
3735 <target><x id="INTERPOLATION" equiv-text="{{host}}"/> instantzia desmutututa.</target>
3736 <context-group name="null">
3737 <context context-type="linenumber">1</context>
3738 </context-group>
3739 </trans-unit>
3711 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e"> 3740 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e">
3712 <source>Ownership accepted</source> 3741 <source>Ownership accepted</source>
3713 <target>Jabetza onartuta</target> 3742 <target>Jabetza onartuta</target>
@@ -3722,6 +3751,13 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3722 <context context-type="linenumber">1</context> 3751 <context context-type="linenumber">1</context>
3723 </context-group> 3752 </context-group>
3724 </trans-unit> 3753 </trans-unit>
3754 <trans-unit id="466fc8cf56fd4e4e90fec4b900ef083d52bec38c">
3755 <source>You current password is invalid.</source>
3756 <target>Zure uneko pasahitza baliogabea da.</target>
3757 <context-group name="null">
3758 <context context-type="linenumber">1</context>
3759 </context-group>
3760 </trans-unit>
3725 <trans-unit id="ca8e8cf0f1686604db3b6a2ebadab7f7b426a047"> 3761 <trans-unit id="ca8e8cf0f1686604db3b6a2ebadab7f7b426a047">
3726 <source>Are you sure you want to delete your account? This will delete all you data, including channels, videos etc.</source> 3762 <source>Are you sure you want to delete your account? This will delete all you data, including channels, videos etc.</source>
3727 <target>Ziur kontua ezabatu nahi duzula? Honek zure datu guztiak ezabatuko ditu, kanalak, bideoak eta abar barne.</target> 3763 <target>Ziur kontua ezabatu nahi duzula? Honek zure datu guztiak ezabatuko ditu, kanalak, bideoak eta abar barne.</target>
@@ -3799,23 +3835,16 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3799 <context context-type="linenumber">1</context> 3835 <context context-type="linenumber">1</context>
3800 </context-group> 3836 </context-group>
3801 </trans-unit> 3837 </trans-unit>
3802 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 3838 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
3803 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 3839 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
3804 <target>Ziur <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> ezabatu nahi duzula? Kanalera igotako bideo guztiak ezabatuko dira ere.</target> 3840 <target><x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> bideo kanala ezabatuta.</target>
3805 <context-group name="null">
3806 <context context-type="linenumber">1</context>
3807 </context-group>
3808 </trans-unit>
3809 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
3810 <source>Please type the name of the video channel to confirm</source>
3811 <target>Idatzi bideo kanalaren izena berresteko</target>
3812 <context-group name="null"> 3841 <context-group name="null">
3813 <context context-type="linenumber">1</context> 3842 <context context-type="linenumber">1</context>
3814 </context-group> 3843 </context-group>
3815 </trans-unit> 3844 </trans-unit>
3816 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 3845 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
3817 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 3846 <source>My videos</source>
3818 <target><x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> bideo kanala ezabatuta.</target> 3847 <target>Nire bideoak</target>
3819 <context-group name="null"> 3848 <context-group name="null">
3820 <context context-type="linenumber">1</context> 3849 <context context-type="linenumber">1</context>
3821 </context-group> 3850 </context-group>
@@ -3890,16 +3919,44 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3890 <context context-type="linenumber">1</context> 3919 <context context-type="linenumber">1</context>
3891 </context-group> 3920 </context-group>
3892 </trans-unit> 3921 </trans-unit>
3893 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 3922 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
3894 <source>Channels</source> 3923 <source>My library</source>
3895 <target>Kanalak</target> 3924 <target>Nire liburutegia</target>
3896 <context-group name="null"> 3925 <context-group name="null">
3897 <context context-type="linenumber">1</context> 3926 <context context-type="linenumber">1</context>
3898 </context-group> 3927 </context-group>
3899 </trans-unit> 3928 </trans-unit>
3900 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d"> 3929 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
3901 <source>Video imports</source> 3930 <source>My channels</source>
3902 <target>Bideo inportazioak</target> 3931 <target>Nire kanalak</target>
3932 <context-group name="null">
3933 <context context-type="linenumber">1</context>
3934 </context-group>
3935 </trans-unit>
3936 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
3937 <source>My subscriptions</source>
3938 <target>Nire harpidetzak</target>
3939 <context-group name="null">
3940 <context context-type="linenumber">1</context>
3941 </context-group>
3942 </trans-unit>
3943 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
3944 <source>Misc</source>
3945 <target>Denetarik</target>
3946 <context-group name="null">
3947 <context context-type="linenumber">1</context>
3948 </context-group>
3949 </trans-unit>
3950 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
3951 <source>Ownership changes</source>
3952 <target>Jabetza aldaketak</target>
3953 <context-group name="null">
3954 <context context-type="linenumber">1</context>
3955 </context-group>
3956 </trans-unit>
3957 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
3958 <source>My settings</source>
3959 <target>Nire ezarpenak</target>
3903 <context-group name="null"> 3960 <context-group name="null">
3904 <context context-type="linenumber">1</context> 3961 <context context-type="linenumber">1</context>
3905 </context-group> 3962 </context-group>
@@ -3932,6 +3989,13 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3932 <context context-type="linenumber">1</context> 3989 <context context-type="linenumber">1</context>
3933 </context-group> 3990 </context-group>
3934 </trans-unit> 3991 </trans-unit>
3992 <trans-unit id="b19ee83cbd2b735fd081b9aa483a890578019099">
3993 <source>Toggle the left menu</source>
3994 <target>Txandakatu ezkerreko menua</target>
3995 <context-group name="null">
3996 <context context-type="linenumber">1</context>
3997 </context-group>
3998 </trans-unit>
3935 <trans-unit id="b54759e30f7c1983940cdacb8eb03f102a869084"> 3999 <trans-unit id="b54759e30f7c1983940cdacb8eb03f102a869084">
3936 <source>Go to the videos overview page</source> 4000 <source>Go to the videos overview page</source>
3937 <target>Joan bideoen ikuspegi orokorraren orrira </target> 4001 <target>Joan bideoen ikuspegi orokorraren orrira </target>
@@ -3939,6 +4003,69 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3939 <context context-type="linenumber">1</context> 4003 <context context-type="linenumber">1</context>
3940 </context-group> 4004 </context-group>
3941 </trans-unit> 4005 </trans-unit>
4006 <trans-unit id="1e919c88a3f889d6659288e69d3e178da0ea7ab0">
4007 <source>Go to the trending videos page</source>
4008 <target>Joan puri-purian dauden bideoen orrira</target>
4009 <context-group name="null">
4010 <context context-type="linenumber">1</context>
4011 </context-group>
4012 </trans-unit>
4013 <trans-unit id="249618dcdd7fbdc863c0714e2eb9e8940bc9c37d">
4014 <source>Go to the recently added videos page</source>
4015 <target>Joan gehitutako azken bideoen orrira</target>
4016 <context-group name="null">
4017 <context context-type="linenumber">1</context>
4018 </context-group>
4019 </trans-unit>
4020 <trans-unit id="7e194daef3a3509128c4300d4c7c292c49ebf3f5">
4021 <source>Go to the local videos page</source>
4022 <target>Joan bideo lokalen orrira</target>
4023 <context-group name="null">
4024 <context context-type="linenumber">1</context>
4025 </context-group>
4026 </trans-unit>
4027 <trans-unit id="f1fb6204f39a7338e5110b2f113643c9288496ba">
4028 <source>Go to the videos upload page</source>
4029 <target>Joan bideoak igotzeko orrira</target>
4030 <context-group name="null">
4031 <context context-type="linenumber">1</context>
4032 </context-group>
4033 </trans-unit>
4034 <trans-unit id="0ed7b40c11da9d4565af9c041df20c15bc6be97e">
4035 <source>Toggle Dark theme</source>
4036 <target>Txandakatu gai iluna</target>
4037 <context-group name="null">
4038 <context context-type="linenumber">1</context>
4039 </context-group>
4040 </trans-unit>
4041 <trans-unit id="badd4b24618ccc8a34620acb9053fc654b9612b2">
4042 <source>Go to my subscriptions</source>
4043 <target>Joan nire harpidetzetara</target>
4044 <context-group name="null">
4045 <context context-type="linenumber">1</context>
4046 </context-group>
4047 </trans-unit>
4048 <trans-unit id="b7184b5a236618e8edd747529869c392ab6dace1">
4049 <source>Go to my videos</source>
4050 <target>Joan nire bideoetara</target>
4051 <context-group name="null">
4052 <context context-type="linenumber">1</context>
4053 </context-group>
4054 </trans-unit>
4055 <trans-unit id="acf985bd42886b9b3030b5f68f0e8417c39b40a7">
4056 <source>Go to my imports</source>
4057 <target>Joan nire inportazioetara</target>
4058 <context-group name="null">
4059 <context context-type="linenumber">1</context>
4060 </context-group>
4061 </trans-unit>
4062 <trans-unit id="cfe3c51f0ae9385dc2ce6df740d87e5514aa9390">
4063 <source>Go to my channels</source>
4064 <target>Joan nire kanaletara</target>
4065 <context-group name="null">
4066 <context context-type="linenumber">1</context>
4067 </context-group>
4068 </trans-unit>
3942 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7"> 4069 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7">
3943 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>. 4070 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>.
3944</source> 4071</source>
@@ -3955,6 +4082,13 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3955 <context context-type="linenumber">1</context> 4082 <context context-type="linenumber">1</context>
3956 </context-group> 4083 </context-group>
3957 </trans-unit> 4084 </trans-unit>
4085 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
4086 <source>Error</source>
4087 <target>Errorea</target>
4088 <context-group name="null">
4089 <context context-type="linenumber">1</context>
4090 </context-group>
4091 </trans-unit>
3958 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 4092 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
3959 <source>You need to reconnect.</source> 4093 <source>You need to reconnect.</source>
3960 <target>Berriro konektatu behar duzu.</target> 4094 <target>Berriro konektatu behar duzu.</target>
@@ -3969,6 +4103,27 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
3969 <context context-type="linenumber">1</context> 4103 <context context-type="linenumber">1</context>
3970 </context-group> 4104 </context-group>
3971 </trans-unit> 4105 </trans-unit>
4106 <trans-unit id="5c0c574151dc8671d9199980ee04bf65aec3b452">
4107 <source>Keyboard Shortcuts:</source>
4108 <target>Teklatu laster-bideak:</target>
4109 <context-group name="null">
4110 <context context-type="linenumber">1</context>
4111 </context-group>
4112 </trans-unit>
4113 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4114 <source>Info</source>
4115 <target>Informazioa</target>
4116 <context-group name="null">
4117 <context context-type="linenumber">1</context>
4118 </context-group>
4119 </trans-unit>
4120 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
4121 <source>Success</source>
4122 <target>Arrakasta</target>
4123 <context-group name="null">
4124 <context context-type="linenumber">1</context>
4125 </context-group>
4126 </trans-unit>
3972 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 4127 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
3973 <source>Incorrect username or password.</source> 4128 <source>Incorrect username or password.</source>
3974 <target>Erabiltzaile-izen edo pasahitz okerra.</target> 4129 <target>Erabiltzaile-izen edo pasahitz okerra.</target>
@@ -4186,6 +4341,20 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
4186 <context context-type="linenumber">1</context> 4341 <context context-type="linenumber">1</context>
4187 </context-group> 4342 </context-group>
4188 </trans-unit> 4343 </trans-unit>
4344 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4345 <source>Email is required.</source>
4346 <target>E-maila behar da.</target>
4347 <context-group name="null">
4348 <context context-type="linenumber">1</context>
4349 </context-group>
4350 </trans-unit>
4351 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4352 <source>Email must be valid.</source>
4353 <target>E-maila baliozkoa izan behar da.</target>
4354 <context-group name="null">
4355 <context context-type="linenumber">1</context>
4356 </context-group>
4357 </trans-unit>
4189 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 4358 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
4190 <source>Username is required.</source> 4359 <source>Username is required.</source>
4191 <target>Erabiltzaile izena beha da.</target> 4360 <target>Erabiltzaile izena beha da.</target>
@@ -4207,41 +4376,6 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
4207 <context context-type="linenumber">1</context> 4376 <context context-type="linenumber">1</context>
4208 </context-group> 4377 </context-group>
4209 </trans-unit> 4378 </trans-unit>
4210 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
4211 <source>Username must be at least 3 characters long.</source>
4212 <target>Erabiltzaile-izenak gutxienez 3 karaktere izan behar ditu.</target>
4213 <context-group name="null">
4214 <context context-type="linenumber">1</context>
4215 </context-group>
4216 </trans-unit>
4217 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
4218 <source>Username cannot be more than 20 characters long.</source>
4219 <target>Erabiltzaile-izenak ezin ditu 20 karaktere baino gehiago izan.</target>
4220 <context-group name="null">
4221 <context context-type="linenumber">1</context>
4222 </context-group>
4223 </trans-unit>
4224 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
4225 <source>Username should be only lowercase alphanumeric characters.</source>
4226 <target>Erabiltzaile-izena minuskulaz dauden karaktere alfanumerikoak besterik ezin ditu izan.</target>
4227 <context-group name="null">
4228 <context context-type="linenumber">1</context>
4229 </context-group>
4230 </trans-unit>
4231 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4232 <source>Email is required.</source>
4233 <target>E-maila behar da.</target>
4234 <context-group name="null">
4235 <context context-type="linenumber">1</context>
4236 </context-group>
4237 </trans-unit>
4238 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4239 <source>Email must be valid.</source>
4240 <target>E-maila baliozkoa izan behar da.</target>
4241 <context-group name="null">
4242 <context context-type="linenumber">1</context>
4243 </context-group>
4244 </trans-unit>
4245 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 4379 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
4246 <source>Password must be at least 6 characters long.</source> 4380 <source>Password must be at least 6 characters long.</source>
4247 <target>Pasahitza gutxienez 6 karaktere luze izan behar da.</target> 4381 <target>Pasahitza gutxienez 6 karaktere luze izan behar da.</target>
@@ -4305,23 +4439,16 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
4305 <context context-type="linenumber">1</context> 4439 <context context-type="linenumber">1</context>
4306 </context-group> 4440 </context-group>
4307 </trans-unit> 4441 </trans-unit>
4308 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674"> 4442 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
4309 <source>Display name must be at least 3 characters long.</source> 4443 <source>Description must be at least 3 characters long.</source>
4310 <target>Pantaila-izena gutxienez 3 karaktere luze izan behar da.</target> 4444 <target>Deskripzioa gutxienez 3 karaktere luze izan behar da.</target>
4311 <context-group name="null">
4312 <context context-type="linenumber">1</context>
4313 </context-group>
4314 </trans-unit>
4315 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
4316 <source>Display name cannot be more than 120 characters long.</source>
4317 <target>Pantaila-izena ezin da 120 karaktere baino luzeagoa izan.</target>
4318 <context-group name="null"> 4445 <context-group name="null">
4319 <context context-type="linenumber">1</context> 4446 <context context-type="linenumber">1</context>
4320 </context-group> 4447 </context-group>
4321 </trans-unit> 4448 </trans-unit>
4322 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 4449 <trans-unit id="a4179e366d4aa335f1ddd0a13e9109c71a9338d0">
4323 <source>Description must be at least 3 characters long.</source> 4450 <source>Description cannot be more than 1000 characters long.</source>
4324 <target>Deskripzioa gutxienez 3 karaktere luze izan behar da.</target> 4451 <target>Deskripzioa ezin da 1000 karaktere baino luzeagoa izan.</target>
4325 <context-group name="null"> 4452 <context-group name="null">
4326 <context context-type="linenumber">1</context> 4453 <context context-type="linenumber">1</context>
4327 </context-group> 4454 </context-group>
@@ -4361,13 +4488,6 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
4361 <context context-type="linenumber">1</context> 4488 <context context-type="linenumber">1</context>
4362 </context-group> 4489 </context-group>
4363 </trans-unit> 4490 </trans-unit>
4364 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
4365 <source>Report reason cannot be more than 300 characters long.</source>
4366 <target>Salatzeko arrazoia ezin da 300 karaktere baino luzeagoa izan.</target>
4367 <context-group name="null">
4368 <context context-type="linenumber">1</context>
4369 </context-group>
4370 </trans-unit>
4371 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118"> 4491 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
4372 <source>Moderation comment is required.</source> 4492 <source>Moderation comment is required.</source>
4373 <target>Moderazio iruzkina derrigorrezkoa da.</target> 4493 <target>Moderazio iruzkina derrigorrezkoa da.</target>
@@ -4382,13 +4502,6 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
4382 <context context-type="linenumber">1</context> 4502 <context context-type="linenumber">1</context>
4383 </context-group> 4503 </context-group>
4384 </trans-unit> 4504 </trans-unit>
4385 <trans-unit id="89d0b662dde0871cf17244e79b2cb62cd517e44f">
4386 <source>Moderation comment cannot be more than 300 characters long.</source>
4387 <target>Moderazio iruzkina ezin da 300 karaktere baino luzeagoa izan.</target>
4388 <context-group name="null">
4389 <context context-type="linenumber">1</context>
4390 </context-group>
4391 </trans-unit>
4392 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6"> 4505 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
4393 <source>The channel is required.</source> 4506 <source>The channel is required.</source>
4394 <target>Kanala derrigorrezkoa da.</target> 4507 <target>Kanala derrigorrezkoa da.</target>
@@ -4445,27 +4558,6 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
4445 <context context-type="linenumber">1</context> 4558 <context context-type="linenumber">1</context>
4446 </context-group> 4559 </context-group>
4447 </trans-unit> 4560 </trans-unit>
4448 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069">
4449 <source>Name must be at least 3 characters long.</source>
4450 <target>Izena gutxienez 3 karakterekoa izan behar da</target>
4451 <context-group name="null">
4452 <context context-type="linenumber">1</context>
4453 </context-group>
4454 </trans-unit>
4455 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482">
4456 <source>Name cannot be more than 20 characters long.</source>
4457 <target>Izena ezin da20 karaktere baino luzeagoa izan</target>
4458 <context-group name="null">
4459 <context context-type="linenumber">1</context>
4460 </context-group>
4461 </trans-unit>
4462 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9">
4463 <source>Name should be only lowercase alphanumeric characters.</source>
4464 <target>Izenak karaktere alfanumerikoak minuskulan besterik ezin ditu izan.</target>
4465 <context-group name="null">
4466 <context context-type="linenumber">1</context>
4467 </context-group>
4468 </trans-unit>
4469 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 4561 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
4470 <source>Support text must be at least 3 characters long.</source> 4562 <source>Support text must be at least 3 characters long.</source>
4471 <target>Babes testua gutxienez 3 karaktere luze izan behar da</target> 4563 <target>Babes testua gutxienez 3 karaktere luze izan behar da</target>
@@ -5103,6 +5195,13 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
5103 <context context-type="linenumber">1</context> 5195 <context context-type="linenumber">1</context>
5104 </context-group> 5196 </context-group>
5105 </trans-unit> 5197 </trans-unit>
5198 <trans-unit id="f9b4f2d8146c789cd40314f640ec4e88efbaf681">
5199 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users banned.</source>
5200 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> erabiltzaile debekatuta.</target>
5201 <context-group name="null">
5202 <context context-type="linenumber">1</context>
5203 </context-group>
5204 </trans-unit>
5106 <trans-unit id="3ab99e62550869aebc85661fca2faf46785263dd"> 5205 <trans-unit id="3ab99e62550869aebc85661fca2faf46785263dd">
5107 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> banned.</source> 5206 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> banned.</source>
5108 <target><x id="INTERPOLATION" equiv-text="{{username}}"/> erabiltzailea debekatuta.</target> 5207 <target><x id="INTERPOLATION" equiv-text="{{username}}"/> erabiltzailea debekatuta.</target>
@@ -5124,6 +5223,13 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
5124 <context context-type="linenumber">1</context> 5223 <context context-type="linenumber">1</context>
5125 </context-group> 5224 </context-group>
5126 </trans-unit> 5225 </trans-unit>
5226 <trans-unit id="ad07d34d4aadfe03c964cec02ca1d3a921e6b603">
5227 <source>If you remove this user, you will not be able to create another with the same username!</source>
5228 <target>Erabiltzaile hau kentzen baduzu, ezin izango duzu erabiltzaile-izen bera duen beste bat sortu gero!</target>
5229 <context-group name="null">
5230 <context context-type="linenumber">1</context>
5231 </context-group>
5232 </trans-unit>
5127 <trans-unit id="28220fae6799ab98ef6b41af449aa9680082357a"> 5233 <trans-unit id="28220fae6799ab98ef6b41af449aa9680082357a">
5128 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> deleted.</source> 5234 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> deleted.</source>
5129 <target><x id="INTERPOLATION" equiv-text="{{username}}"/> erabiltzailea ezabatuta.</target> 5235 <target><x id="INTERPOLATION" equiv-text="{{username}}"/> erabiltzailea ezabatuta.</target>
@@ -5131,6 +5237,13 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
5131 <context context-type="linenumber">1</context> 5237 <context context-type="linenumber">1</context>
5132 </context-group> 5238 </context-group>
5133 </trans-unit> 5239 </trans-unit>
5240 <trans-unit id="534202c90c6dcadd2989fc72c5030d5483e26096">
5241 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> email set as verified</source>
5242 <target><x id="INTERPOLATION" equiv-text="{{username}}"/> erabiltzailearen e-mail helbidea baieztatua gisa ezarri da</target>
5243 <context-group name="null">
5244 <context context-type="linenumber">1</context>
5245 </context-group>
5246 </trans-unit>
5134 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249"> 5247 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249">
5135 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source> 5248 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source>
5136 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> kontua mutututa.</target> 5249 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> kontua mutututa.</target>
@@ -5138,6 +5251,41 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
5138 <context context-type="linenumber">1</context> 5251 <context context-type="linenumber">1</context>
5139 </context-group> 5252 </context-group>
5140 </trans-unit> 5253 </trans-unit>
5254 <trans-unit id="086eda792aeb1b0d131d633b50fdd1792f5f24c6">
5255 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted.</source>
5256 <target><x id="INTERPOLATION" equiv-text="{{host}}"/> instantzia mutututa.</target>
5257 <context-group name="null">
5258 <context context-type="linenumber">1</context>
5259 </context-group>
5260 </trans-unit>
5261 <trans-unit id="bb72d6d1219e89d182e9fd09d853d83baf8d6499">
5262 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted by the instance.</source>
5263 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> kontua instantziak mutututa.</target>
5264 <context-group name="null">
5265 <context context-type="linenumber">1</context>
5266 </context-group>
5267 </trans-unit>
5268 <trans-unit id="8686834bc4afe42c1991c6c18f0bce174a0e17a6">
5269 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by the instance.</source>
5270 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> kontua instantziak desmutututa.</target>
5271 <context-group name="null">
5272 <context context-type="linenumber">1</context>
5273 </context-group>
5274 </trans-unit>
5275 <trans-unit id="35d3509161861a610b0895bf084c781e56ba2830">
5276 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted by the instance.</source>
5277 <target><x id="INTERPOLATION" equiv-text="{{host}}"/> instantzia instantziak mutututa.</target>
5278 <context-group name="null">
5279 <context context-type="linenumber">1</context>
5280 </context-group>
5281 </trans-unit>
5282 <trans-unit id="978aeec5613fa97e8a5336d3599cebb23ee5a90f">
5283 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by the instance.</source>
5284 <target><x id="INTERPOLATION" equiv-text="{{host}}"/> kontua instantziak desmutututa.</target>
5285 <context-group name="null">
5286 <context context-type="linenumber">1</context>
5287 </context-group>
5288 </trans-unit>
5141 <trans-unit id="4a09bf8724e7659fbb5ec33647529cdef7614bdc"> 5289 <trans-unit id="4a09bf8724e7659fbb5ec33647529cdef7614bdc">
5142 <source>Mute this account</source> 5290 <source>Mute this account</source>
5143 <target>Mututu kontu hau</target> 5291 <target>Mututu kontu hau</target>
@@ -5222,13 +5370,6 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
5222 <context context-type="linenumber">1</context> 5370 <context context-type="linenumber">1</context>
5223 </context-group> 5371 </context-group>
5224 </trans-unit> 5372 </trans-unit>
5225 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5226 <source>Subscribed</source>
5227 <target>Harpidetuta</target>
5228 <context-group name="null">
5229 <context context-type="linenumber">1</context>
5230 </context-group>
5231 </trans-unit>
5232 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded"> 5373 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
5233 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source> 5374 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
5234 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/>(e)ra harpidetuta</target> 5375 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/>(e)ra harpidetuta</target>
@@ -5236,9 +5377,9 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
5236 <context context-type="linenumber">1</context> 5377 <context context-type="linenumber">1</context>
5237 </context-group> 5378 </context-group>
5238 </trans-unit> 5379 </trans-unit>
5239 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471"> 5380 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5240 <source>Unsubscribed</source> 5381 <source>Subscribed</source>
5241 <target>Harpidetza kenduta</target> 5382 <target>Harpidetuta</target>
5242 <context-group name="null"> 5383 <context-group name="null">
5243 <context context-type="linenumber">1</context> 5384 <context context-type="linenumber">1</context>
5244 </context-group> 5385 </context-group>
@@ -5250,6 +5391,13 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
5250 <context context-type="linenumber">1</context> 5391 <context context-type="linenumber">1</context>
5251 </context-group> 5392 </context-group>
5252 </trans-unit> 5393 </trans-unit>
5394 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
5395 <source>Unsubscribed</source>
5396 <target>Harpidetza kenduta</target>
5397 <context-group name="null">
5398 <context context-type="linenumber">1</context>
5399 </context-group>
5400 </trans-unit>
5253 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf"> 5401 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf">
5254 <source>Moderator</source> 5402 <source>Moderator</source>
5255 <target>Moderatzailea</target> 5403 <target>Moderatzailea</target>
@@ -5278,6 +5426,20 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
5278 <context context-type="linenumber">1</context> 5426 <context context-type="linenumber">1</context>
5279 </context-group> 5427 </context-group>
5280 </trans-unit> 5428 </trans-unit>
5429 <trans-unit id="21565881ad1dff3c98738b9535b3515cec140609">
5430 <source>Welcome! Now please check your emails to verify your account and complete signup.</source>
5431 <target>Ongi etorri! Egiaztatu zure e-maila kontua baieztatzeko eta izen ematea osatzeko.</target>
5432 <context-group name="null">
5433 <context context-type="linenumber">1</context>
5434 </context-group>
5435 </trans-unit>
5436 <trans-unit id="14200e26888a07633c0f177020dce8f3ec7311a6">
5437 <source>You are now logged in as <x id="INTERPOLATION" equiv-text="{{username}}"/>!</source>
5438 <target><x id="INTERPOLATION" equiv-text="{{username}}"/> gisa hasi duzu saioa!</target>
5439 <context-group name="null">
5440 <context context-type="linenumber">1</context>
5441 </context-group>
5442 </trans-unit>
5281 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb"> 5443 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb">
5282 <source>Video to import updated.</source> 5444 <source>Video to import updated.</source>
5283 <target>Inportatzeko bideoa eguneratuta.</target> 5445 <target>Inportatzeko bideoa eguneratuta.</target>
@@ -5306,23 +5468,23 @@ Ezin izan dugu bilatzen duzun orria aurkitu.
5306 <context context-type="linenumber">1</context> 5468 <context context-type="linenumber">1</context>
5307 </context-group> 5469 </context-group>
5308 </trans-unit> 5470 </trans-unit>
5309 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5"> 5471 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
5310 <source>Info</source> 5472 <source>Upload cancelled</source>
5311 <target>Informazioa</target> 5473 <target>Igoera ezeztatuta</target>
5312 <context-group name="null"> 5474 <context-group name="null">
5313 <context context-type="linenumber">1</context> 5475 <context context-type="linenumber">1</context>
5314 </context-group> 5476 </context-group>
5315 </trans-unit> 5477 </trans-unit>
5316 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 5478 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
5317 <source>Upload cancelled</source> 5479 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
5318 <target>Igoera ezeztatuta</target> 5480 <target>Zure bideo-kuota bideo honekin gainditzen da (bideoaren tamaina: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, erabilita: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, kuota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
5319 <context-group name="null"> 5481 <context-group name="null">
5320 <context context-type="linenumber">1</context> 5482 <context context-type="linenumber">1</context>
5321 </context-group> 5483 </context-group>
5322 </trans-unit> 5484 </trans-unit>
5323 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa"> 5485 <trans-unit id="c980896ac8e08e9751545db1b7ef0e93fb8a52cd">
5324 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source> 5486 <source>Your daily video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{quotaUsedDaily}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{quotaDaily}}"/>)</source>
5325 <target>Sentitzen dugu, PeerTubek ezin du 8GB baino gehiagoko bideorik kudeatu</target> 5487 <target>Zure eguneko bideo-kuota bideo honekin gainditzen da (bideoaren tamaina: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, erabilita: <x id="INTERPOLATION_1" equiv-text="{{quotaUsedDaily}}"/>, kuota: <x id="INTERPOLATION_2" equiv-text="{{quotaDaily}}"/>)</target>
5326 <context-group name="null"> 5488 <context-group name="null">
5327 <context context-type="linenumber">1</context> 5489 <context context-type="linenumber">1</context>
5328 </context-group> 5490 </context-group>
diff --git a/client/src/locale/target/angular_fa_IR.xml b/client/src/locale/target/angular_fa_IR.xml
index fe2d0b0cf..2a59cfc34 100644
--- a/client/src/locale/target/angular_fa_IR.xml
+++ b/client/src/locale/target/angular_fa_IR.xml
@@ -288,7 +288,7 @@
288 <source>Password</source> 288 <source>Password</source>
289 <target>گذرواژه</target> 289 <target>گذرواژه</target>
290 <context-group name="null"> 290 <context-group name="null">
291 <context context-type="linenumber">12</context> 291 <context context-type="linenumber">13</context>
292 </context-group> 292 </context-group>
293 </trans-unit> 293 </trans-unit>
294 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 294 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -302,7 +302,7 @@
302 <source>Login</source> 302 <source>Login</source>
303 <target>ورود</target> 303 <target>ورود</target>
304 <context-group name="null"> 304 <context-group name="null">
305 <context context-type="linenumber">38</context> 305 <context context-type="linenumber">36</context>
306 </context-group> 306 </context-group>
307 </trans-unit> 307 </trans-unit>
308 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 308 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -330,7 +330,7 @@
330 <source>Send me an email to reset my password</source> 330 <source>Send me an email to reset my password</source>
331 <target>یک رایانامه برای بازنشانی گذرواژه برای من بÙرست</target> 331 <target>یک رایانامه برای بازنشانی گذرواژه برای من بÙرست</target>
332 <context-group name="null"> 332 <context-group name="null">
333 <context context-type="linenumber">75</context> 333 <context context-type="linenumber">80</context>
334 </context-group> 334 </context-group>
335 </trans-unit> 335 </trans-unit>
336 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 336 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -392,7 +392,7 @@
392 <source>Signup</source> 392 <source>Signup</source>
393 <target>ثبت‌نام</target> 393 <target>ثبت‌نام</target>
394 <context-group name="null"> 394 <context-group name="null">
395 <context context-type="linenumber">88</context> 395 <context context-type="linenumber">78</context>
396 </context-group> 396 </context-group>
397 </trans-unit> 397 </trans-unit>
398 <trans-unit id="e2dbf0426cbb0b573faf49dffeb7d5bdf16eda5d"> 398 <trans-unit id="e2dbf0426cbb0b573faf49dffeb7d5bdf16eda5d">
@@ -410,7 +410,7 @@
410 <source>Change the language</source> 410 <source>Change the language</source>
411 <target>تغییر زبان</target> 411 <target>تغییر زبان</target>
412 <context-group name="null"> 412 <context-group name="null">
413 <context context-type="linenumber">88</context> 413 <context context-type="linenumber">86</context>
414 </context-group> 414 </context-group>
415 </trans-unit> 415 </trans-unit>
416 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 416 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -421,7 +421,7 @@
421 نمایه‌ عمومی من 421 نمایه‌ عمومی من
422 </target> 422 </target>
423 <context-group name="null"> 423 <context-group name="null">
424 <context context-type="linenumber">18</context> 424 <context context-type="linenumber">16</context>
425 </context-group> 425 </context-group>
426 </trans-unit> 426 </trans-unit>
427 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 427 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -432,7 +432,7 @@
432 حساب کاربری من 432 حساب کاربری من
433 </target> 433 </target>
434 <context-group name="null"> 434 <context-group name="null">
435 <context context-type="linenumber">22</context> 435 <context context-type="linenumber">20</context>
436 </context-group> 436 </context-group>
437 </trans-unit> 437 </trans-unit>
438 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 438 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -443,7 +443,7 @@
443 ویدئو‌های من 443 ویدئو‌های من
444 </target> 444 </target>
445 <context-group name="null"> 445 <context-group name="null">
446 <context context-type="linenumber">26</context> 446 <context context-type="linenumber">24</context>
447 </context-group> 447 </context-group>
448 </trans-unit> 448 </trans-unit>
449 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 449 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -454,14 +454,14 @@
454 خروج 454 خروج
455 </target> 455 </target>
456 <context-group name="null"> 456 <context-group name="null">
457 <context context-type="linenumber">30</context> 457 <context context-type="linenumber">28</context>
458 </context-group> 458 </context-group>
459 </trans-unit> 459 </trans-unit>
460 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 460 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
461 <source>Create an account</source> 461 <source>Create an account</source>
462 <target>ساخت حساب</target> 462 <target>ساخت حساب</target>
463 <context-group name="null"> 463 <context-group name="null">
464 <context context-type="linenumber">39</context> 464 <context context-type="linenumber">37</context>
465 </context-group> 465 </context-group>
466 </trans-unit> 466 </trans-unit>
467 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 467 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -475,49 +475,49 @@
475 <source>Subscriptions</source> 475 <source>Subscriptions</source>
476 <target>اشتراک</target> 476 <target>اشتراک</target>
477 <context-group name="null"> 477 <context-group name="null">
478 <context context-type="linenumber">47</context> 478 <context context-type="linenumber">45</context>
479 </context-group> 479 </context-group>
480 </trans-unit> 480 </trans-unit>
481 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 481 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
482 <source>Overview</source> 482 <source>Overview</source>
483 <target>نمای‌کلی</target> 483 <target>نمای‌کلی</target>
484 <context-group name="null"> 484 <context-group name="null">
485 <context context-type="linenumber">52</context> 485 <context context-type="linenumber">50</context>
486 </context-group> 486 </context-group>
487 </trans-unit> 487 </trans-unit>
488 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 488 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
489 <source>Trending</source> 489 <source>Trending</source>
490 <target>مورد بحث</target> 490 <target>مورد بحث</target>
491 <context-group name="null"> 491 <context-group name="null">
492 <context context-type="linenumber">57</context> 492 <context context-type="linenumber">55</context>
493 </context-group> 493 </context-group>
494 </trans-unit> 494 </trans-unit>
495 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 495 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
496 <source>Recently added</source> 496 <source>Recently added</source>
497 <target>به تازگی اضاÙÙ‡ شده</target> 497 <target>به تازگی اضاÙÙ‡ شده</target>
498 <context-group name="null"> 498 <context-group name="null">
499 <context context-type="linenumber">62</context> 499 <context context-type="linenumber">60</context>
500 </context-group> 500 </context-group>
501 </trans-unit> 501 </trans-unit>
502 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 502 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
503 <source>Local</source> 503 <source>Local</source>
504 <target>محلی</target> 504 <target>محلی</target>
505 <context-group name="null"> 505 <context-group name="null">
506 <context context-type="linenumber">67</context> 506 <context context-type="linenumber">65</context>
507 </context-group> 507 </context-group>
508 </trans-unit> 508 </trans-unit>
509 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 509 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
510 <source>More</source> 510 <source>More</source>
511 <target>دیگر</target> 511 <target>دیگر</target>
512 <context-group name="null"> 512 <context-group name="null">
513 <context context-type="linenumber">72</context> 513 <context context-type="linenumber">70</context>
514 </context-group> 514 </context-group>
515 </trans-unit> 515 </trans-unit>
516 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 516 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
517 <source>Administration</source> 517 <source>Administration</source>
518 <target>مدیریت</target> 518 <target>مدیریت</target>
519 <context-group name="null"> 519 <context-group name="null">
520 <context context-type="linenumber">76</context> 520 <context context-type="linenumber">74</context>
521 </context-group> 521 </context-group>
522 </trans-unit> 522 </trans-unit>
523 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 523 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -529,7 +529,7 @@
529 </trans-unit> 529 </trans-unit>
530 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 530 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
531 <source>Toggle dark interface</source><target>Toggle dark interface</target><context-group name="null"> 531 <source>Toggle dark interface</source><target>Toggle dark interface</target><context-group name="null">
532 <context context-type="linenumber">94</context> 532 <context context-type="linenumber">92</context>
533 </context-group> 533 </context-group>
534 </trans-unit> 534 </trans-unit>
535 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 535 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -613,7 +613,7 @@
613 <source>No results.</source> 613 <source>No results.</source>
614 <target>بدون نتیجه.</target> 614 <target>بدون نتیجه.</target>
615 <context-group name="null"> 615 <context-group name="null">
616 <context context-type="linenumber">17</context> 616 <context context-type="linenumber">20</context>
617 </context-group> 617 </context-group>
618 </trans-unit> 618 </trans-unit>
619 <trans-unit id="6385c357c1de58ce92c0cf618ecf9cf74b917390"> 619 <trans-unit id="6385c357c1de58ce92c0cf618ecf9cf74b917390">
@@ -659,14 +659,14 @@
659 <source>Videos Overview</source> 659 <source>Videos Overview</source>
660 <target>نمای‌کلی ویدئو‌ها</target> 660 <target>نمای‌کلی ویدئو‌ها</target>
661 <context-group name="null"> 661 <context-group name="null">
662 <context context-type="linenumber">58</context> 662 <context context-type="linenumber">51</context>
663 </context-group> 663 </context-group>
664 </trans-unit> 664 </trans-unit>
665 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 665 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
666 <source>Local videos</source> 666 <source>Local videos</source>
667 <target>ویدئو‌های محلی</target> 667 <target>ویدئو‌های محلی</target>
668 <context-group name="null"> 668 <context-group name="null">
669 <context context-type="linenumber">61</context> 669 <context context-type="linenumber">54</context>
670 </context-group> 670 </context-group>
671 </trans-unit> 671 </trans-unit>
672 <trans-unit id="010d24ef3c43b2d8f45a4d6cba7d73e12ee1557e"> 672 <trans-unit id="010d24ef3c43b2d8f45a4d6cba7d73e12ee1557e">
@@ -680,7 +680,14 @@
680 <source>Signup enabled</source> 680 <source>Signup enabled</source>
681 <target>ثبت‌نام Ùعال است</target> 681 <target>ثبت‌نام Ùعال است</target>
682 <context-group name="null"> 682 <context-group name="null">
683 <context context-type="linenumber">93</context> 683 <context context-type="linenumber">84</context>
684 </context-group>
685 </trans-unit>
686 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
687 <source>Users</source>
688 <target>کاربران</target>
689 <context-group name="null">
690 <context context-type="linenumber">105</context>
684 </context-group> 691 </context-group>
685 </trans-unit> 692 </trans-unit>
686 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 693 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
@@ -694,14 +701,7 @@
694 <source>Administrator</source> 701 <source>Administrator</source>
695 <target>مدیر</target> 702 <target>مدیر</target>
696 <context-group name="null"> 703 <context-group name="null">
697 <context context-type="linenumber">131</context> 704 <context context-type="linenumber">155</context>
698 </context-group>
699 </trans-unit>
700 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
701 <source>Users</source>
702 <target>کاربران</target>
703 <context-group name="null">
704 <context context-type="linenumber">144</context>
705 </context-group> 705 </context-group>
706 </trans-unit> 706 </trans-unit>
707 <trans-unit id="99cb827741e93125476a0f5b676372d85d15b5fc"> 707 <trans-unit id="99cb827741e93125476a0f5b676372d85d15b5fc">
@@ -715,14 +715,14 @@
715 <source>Your Twitter username</source> 715 <source>Your Twitter username</source>
716 <target>نام‌کاربری توییتر شما</target> 716 <target>نام‌کاربری توییتر شما</target>
717 <context-group name="null"> 717 <context-group name="null">
718 <context context-type="linenumber">181</context> 718 <context context-type="linenumber">184</context>
719 </context-group> 719 </context-group>
720 </trans-unit> 720 </trans-unit>
721 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 721 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
722 <source>JavaScript</source> 722 <source>JavaScript</source>
723 <target>جاوااکسریپت</target> 723 <target>جاوااکسریپت</target>
724 <context-group name="null"> 724 <context-group name="null">
725 <context context-type="linenumber">278</context> 725 <context context-type="linenumber">294</context>
726 </context-group> 726 </context-group>
727 </trans-unit> 727 </trans-unit>
728 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 728 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -813,18 +813,25 @@
813 <context context-type="linenumber">14</context> 813 <context context-type="linenumber">14</context>
814 </context-group> 814 </context-group>
815 </trans-unit> 815 </trans-unit>
816 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
817 <source>My videos</source>
818 <target>ویديو‌های من</target>
819 <context-group name="null">
820 <context context-type="linenumber">1</context>
821 </context-group>
822 </trans-unit>
816 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6"> 823 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
817 <source>My settings</source> 824 <source>My settings</source>
818 <target>تنظیمات من</target> 825 <target>تنظیمات من</target>
819 <context-group name="null"> 826 <context-group name="null">
820 <context context-type="linenumber">3</context> 827 <context context-type="linenumber">1</context>
821 </context-group> 828 </context-group>
822 </trans-unit> 829 </trans-unit>
823 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894"> 830 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
824 <source>My videos</source> 831 <source>Info</source>
825 <target>ویديو‌های ÙÙ†</target> 832 <target>راÙنما</target>
826 <context-group name="null"> 833 <context-group name="null">
827 <context context-type="linenumber">14</context> 834 <context context-type="linenumber">1</context>
828 </context-group> 835 </context-group>
829 </trans-unit> 836 </trans-unit>
830 <trans-unit id="e7815f1c4a6d3cc157a16407a48865023cc35ec0"> 837 <trans-unit id="e7815f1c4a6d3cc157a16407a48865023cc35ec0">
@@ -1030,13 +1037,6 @@
1030 <context context-type="linenumber">1</context> 1037 <context context-type="linenumber">1</context>
1031 </context-group> 1038 </context-group>
1032 </trans-unit> 1039 </trans-unit>
1033 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
1034 <source>Info</source>
1035 <target>راهنما</target>
1036 <context-group name="null">
1037 <context context-type="linenumber">1</context>
1038 </context-group>
1039 </trans-unit>
1040 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 1040 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
1041 <source>Upload cancelled</source> 1041 <source>Upload cancelled</source>
1042 <target>بارگزاری لغوشد</target> 1042 <target>بارگزاری لغوشد</target>
diff --git a/client/src/locale/target/angular_fr_FR.xml b/client/src/locale/target/angular_fr_FR.xml
index 55f323009..23cfec618 100644
--- a/client/src/locale/target/angular_fr_FR.xml
+++ b/client/src/locale/target/angular_fr_FR.xml
@@ -227,6 +227,155 @@
227 <context context-type="linenumber">11</context> 227 <context context-type="linenumber">11</context>
228 </context-group> 228 </context-group>
229 </trans-unit> 229 </trans-unit>
230 <trans-unit id="f3e63578c50546530daf6050d2ba6f8226040f2c">
231 <source>You don't have notifications.</source>
232 <target>Vous n'avez pas de notifications.</target>
233 <context-group name="null">
234 <context context-type="linenumber">1</context>
235 </context-group>
236 </trans-unit>
237 <trans-unit id="f79d1d9ecaab3deb3d44e23017f8283a04d2a0f3">
238 <source>
239 <x id="INTERPOLATION" equiv-text="{{ notification.video.channel.displayName }}"/> published a <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>new video<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
240 </source>
241 <target>
242 <x id="INTERPOLATION" equiv-text="{{ notification.video.channel.displayName }}"/> a publié une <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>nouvelle vidéo<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
243 </target>
244 <context-group name="null">
245 <context context-type="linenumber">7</context>
246 </context-group>
247 </trans-unit>
248 <trans-unit id="04f2cb4c88c17d5f3e5ce969479b4eba9db114cb">
249 <source>
250 Your video <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> has been unblacklisted
251 </source>
252 <target>
253 Votre vidéo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> a été débloquée
254 </target>
255 <context-group name="null">
256 <context context-type="linenumber">11</context>
257 </context-group>
258 </trans-unit>
259 <trans-unit id="65514a0efdae3b173130166416700ddeb369f37f">
260 <source>
261 Your video <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.videoBlacklist.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> has been blacklisted
262 </source>
263 <target>
264 Votre vidéo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.videoBlacklist.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> a été bloquée
265 </target>
266 <context-group name="null">
267 <context context-type="linenumber">15</context>
268 </context-group>
269 </trans-unit>
270 <trans-unit id="4ea67498da562ab450950a69f4331b8c4ddfd431">
271 <source>
272 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>A new video abuse<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> has been created on video <x id="START_LINK_1" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.videoAbuse.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
273 </source>
274 <target>
275 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>Un nouveau signalement<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> a été créé sur la vidéo <x id="START_LINK_1" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.videoAbuse.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
276 </target>
277 <context-group name="null">
278 <context context-type="linenumber">19</context>
279 </context-group>
280 </trans-unit>
281 <trans-unit id="23b7d6f08c5c3b8722ecd627c3d54f4950923156">
282 <source>
283 <x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/> commented your video <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
284 </source>
285 <target>
286 <x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/> a commenté votre vidéo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
287 </target>
288 <context-group name="null">
289 <context context-type="linenumber">23</context>
290 </context-group>
291 </trans-unit>
292 <trans-unit id="2d0ee93317d4daa301eee7fec775c21c2f7b5a4b">
293 <source>
294 Your video <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> has been published
295 </source>
296 <target>
297 Votre vidéo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> a été publiée
298 </target>
299 <context-group name="null">
300 <context context-type="linenumber">27</context>
301 </context-group>
302 </trans-unit>
303 <trans-unit id="371391b88724e5ee455582f07eb97728e371f24a">
304 <source>
305 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>Your video import<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> <x id="INTERPOLATION" equiv-text="{{ notification.videoImportIdentifier }}"/> succeeded
306 </source>
307 <target>
308 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>Votre vidéo<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> <x id="INTERPOLATION" equiv-text="{{ notification.videoImportIdentifier }}"/> a été importée
309 </target>
310 <context-group name="null">
311 <context context-type="linenumber">31</context>
312 </context-group>
313 </trans-unit>
314 <trans-unit id="56e72a0a79d53e9ff8d5f92528664bcb2cf1363a">
315 <source>
316 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>Your video import<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> <x id="INTERPOLATION" equiv-text="{{ notification.videoImportIdentifier }}"/> failed
317 </source>
318 <target>
319 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>L'importation de votre vidéo<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> <x id="INTERPOLATION" equiv-text="{{ notification.videoImportIdentifier }}"/> a échoué
320 </target>
321 <context-group name="null">
322 <context context-type="linenumber">35</context>
323 </context-group>
324 </trans-unit>
325 <trans-unit id="d7f123ae20ca6bfb5ac0f897b90423fdc52d8e78">
326 <source>
327 User <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.account.name }}"/> registered<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> on your instance
328 </source>
329 <target>
330 L'utilisateur <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.account.name }}"/> a créé un compte<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> sur votre instance
331 </target>
332 <context-group name="null">
333 <context context-type="linenumber">39</context>
334 </context-group>
335 </trans-unit>
336 <trans-unit id="9a05dc5206104085b2b6654fb9137291194a72ef">
337 <source>
338 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.actorFollow.follower.displayName }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> is following
339
340 <x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/>
341 your channel <x id="INTERPOLATION_1" equiv-text="{{ notification.actorFollow.following.displayName }}"/>
342 <x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
343 <x id="START_TAG_NG-CONTAINER_1" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/>your account<x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
344 </source>
345 <target>
346 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.actorFollow.follower.displayName }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> suit
347
348 <x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/>
349 votre chaîne <x id="INTERPOLATION_1" equiv-text="{{ notification.actorFollow.following.displayName }}"/>
350 <x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
351 <x id="START_TAG_NG-CONTAINER_1" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/>votre compte<x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
352 </target>
353 <context-group name="null">
354 <context context-type="linenumber">43</context>
355 </context-group>
356 </trans-unit>
357 <trans-unit id="98b174525a2c9b4de0a510fb6eae7bdf285c0c7f">
358 <source>
359 <x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/> mentioned you on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>video <x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
360 </source>
361 <target>
362 <x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/> vous a mentionné sur la vidéo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/> <x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
363 </target>
364 <context-group name="null">
365 <context context-type="linenumber">52</context>
366 </context-group>
367 </trans-unit>
368 <trans-unit id="473117e02024f603dc2dbd24a0bf81f8722cf8dc">
369 <source>
370 <x id="START_TAG_DIV" ctype="x-div" equiv-text="&lt;div&gt;"/><x id="CLOSE_TAG_DIV" ctype="x-div" equiv-text="&lt;/div&gt;"/>
371 </source>
372 <target>
373 <x id="START_TAG_DIV" ctype="x-div" equiv-text="&lt;div&gt;"/><x id="CLOSE_TAG_DIV" ctype="x-div" equiv-text="&lt;/div&gt;"/>
374 </target>
375 <context-group name="null">
376 <context context-type="linenumber">57</context>
377 </context-group>
378 </trans-unit>
230 <trans-unit id="4b3963c6d0863118fe9e9e33447d12be3c2db081"> 379 <trans-unit id="4b3963c6d0863118fe9e9e33447d12be3c2db081">
231 <source>Unlisted</source> 380 <source>Unlisted</source>
232 <target>Non répertoriée</target> 381 <target>Non répertoriée</target>
@@ -434,6 +583,13 @@
434 <context context-type="linenumber">25</context> 583 <context context-type="linenumber">25</context>
435 </context-group> 584 </context-group>
436 </trans-unit> 585 </trans-unit>
586 <trans-unit id="c078d4901a5fac169665947cc7a6108b94dd80c7">
587 <source><x id="INTERPOLATION" equiv-text="{{ menuEntry.label }}"/></source>
588 <target><x id="INTERPOLATION" equiv-text="{{ menuEntry.label }}"/></target>
589 <context-group name="null">
590 <context context-type="linenumber">11</context>
591 </context-group>
592 </trans-unit>
437 <trans-unit id="12910217fdcdbca64bee06f511639b653d5428ea"> 593 <trans-unit id="12910217fdcdbca64bee06f511639b653d5428ea">
438 <source> 594 <source>
439 Login 595 Login
@@ -498,7 +654,7 @@
498 <source>Password</source> 654 <source>Password</source>
499 <target>Mot de passe</target> 655 <target>Mot de passe</target>
500 <context-group name="null"> 656 <context-group name="null">
501 <context context-type="linenumber">12</context> 657 <context context-type="linenumber">13</context>
502 </context-group> 658 </context-group>
503 </trans-unit> 659 </trans-unit>
504 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 660 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -512,7 +668,7 @@
512 <source>Login</source> 668 <source>Login</source>
513 <target>Se connecter</target> 669 <target>Se connecter</target>
514 <context-group name="null"> 670 <context-group name="null">
515 <context context-type="linenumber">38</context> 671 <context context-type="linenumber">36</context>
516 </context-group> 672 </context-group>
517 </trans-unit> 673 </trans-unit>
518 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 674 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -522,6 +678,17 @@
522 <context context-type="linenumber">57</context> 678 <context context-type="linenumber">57</context>
523 </context-group> 679 </context-group>
524 </trans-unit> 680 </trans-unit>
681 <trans-unit id="f876804a6725f7b950c8e4c56ca596206856e6a2">
682 <source>
683 We are sorry, you cannot recover you password because your instance administrator did not configure the PeerTube email system.
684 </source>
685 <target>
686 Désolé, vous ne pouvez pas récupérer votre mot de passe car l'administrateur de votre instance n'a pas configuré le système de mails de PeerTube.
687 </target>
688 <context-group name="null">
689 <context context-type="linenumber">63</context>
690 </context-group>
691 </trans-unit>
525 <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc"> 692 <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc">
526 <source>Email</source> 693 <source>Email</source>
527 <target>Courriel</target> 694 <target>Courriel</target>
@@ -540,7 +707,7 @@
540 <source>Send me an email to reset my password</source> 707 <source>Send me an email to reset my password</source>
541 <target>M'envoyer un courriel pour réinitialiser mon mot de passe</target> 708 <target>M'envoyer un courriel pour réinitialiser mon mot de passe</target>
542 <context-group name="null"> 709 <context-group name="null">
543 <context context-type="linenumber">75</context> 710 <context context-type="linenumber">80</context>
544 </context-group> 711 </context-group>
545 </trans-unit> 712 </trans-unit>
546 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 713 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -611,7 +778,7 @@
611 <source>Signup</source> 778 <source>Signup</source>
612 <target>Créer un compte</target> 779 <target>Créer un compte</target>
613 <context-group name="null"> 780 <context-group name="null">
614 <context context-type="linenumber">88</context> 781 <context context-type="linenumber">78</context>
615 </context-group> 782 </context-group>
616 </trans-unit> 783 </trans-unit>
617 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 784 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -681,7 +848,18 @@
681 <source>Change the language</source> 848 <source>Change the language</source>
682 <target>Changer la langue</target> 849 <target>Changer la langue</target>
683 <context-group name="null"> 850 <context-group name="null">
684 <context context-type="linenumber">88</context> 851 <context context-type="linenumber">86</context>
852 </context-group>
853 </trans-unit>
854 <trans-unit id="1c98d728375e7bd5b166d1aeb29485ef8b5d6e28">
855 <source>
856 Help to translate PeerTube!
857 </source>
858 <target>
859 Aidez à traduire PeerTube !
860 </target>
861 <context-group name="null">
862 <context context-type="linenumber">8</context>
685 </context-group> 863 </context-group>
686 </trans-unit> 864 </trans-unit>
687 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 865 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -692,7 +870,7 @@
692 Mon profil public 870 Mon profil public
693 </target> 871 </target>
694 <context-group name="null"> 872 <context-group name="null">
695 <context context-type="linenumber">18</context> 873 <context context-type="linenumber">16</context>
696 </context-group> 874 </context-group>
697 </trans-unit> 875 </trans-unit>
698 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 876 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -703,7 +881,7 @@
703 Mon compte 881 Mon compte
704 </target> 882 </target>
705 <context-group name="null"> 883 <context-group name="null">
706 <context context-type="linenumber">22</context> 884 <context context-type="linenumber">20</context>
707 </context-group> 885 </context-group>
708 </trans-unit> 886 </trans-unit>
709 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 887 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -714,7 +892,7 @@
714 Mes vidéos 892 Mes vidéos
715 </target> 893 </target>
716 <context-group name="null"> 894 <context-group name="null">
717 <context context-type="linenumber">26</context> 895 <context context-type="linenumber">24</context>
718 </context-group> 896 </context-group>
719 </trans-unit> 897 </trans-unit>
720 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 898 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -725,14 +903,14 @@
725 Se déconnecter 903 Se déconnecter
726 </target> 904 </target>
727 <context-group name="null"> 905 <context-group name="null">
728 <context context-type="linenumber">30</context> 906 <context context-type="linenumber">28</context>
729 </context-group> 907 </context-group>
730 </trans-unit> 908 </trans-unit>
731 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 909 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
732 <source>Create an account</source> 910 <source>Create an account</source>
733 <target>Créer un compte</target> 911 <target>Créer un compte</target>
734 <context-group name="null"> 912 <context-group name="null">
735 <context context-type="linenumber">39</context> 913 <context context-type="linenumber">37</context>
736 </context-group> 914 </context-group>
737 </trans-unit> 915 </trans-unit>
738 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 916 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -746,49 +924,49 @@
746 <source>Subscriptions</source> 924 <source>Subscriptions</source>
747 <target>Abonnements</target> 925 <target>Abonnements</target>
748 <context-group name="null"> 926 <context-group name="null">
749 <context context-type="linenumber">47</context> 927 <context context-type="linenumber">45</context>
750 </context-group> 928 </context-group>
751 </trans-unit> 929 </trans-unit>
752 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 930 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
753 <source>Overview</source> 931 <source>Overview</source>
754 <target>Vue d'ensemble</target> 932 <target>Vue d'ensemble</target>
755 <context-group name="null"> 933 <context-group name="null">
756 <context context-type="linenumber">52</context> 934 <context context-type="linenumber">50</context>
757 </context-group> 935 </context-group>
758 </trans-unit> 936 </trans-unit>
759 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 937 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
760 <source>Trending</source> 938 <source>Trending</source>
761 <target>Tendances</target> 939 <target>Tendances</target>
762 <context-group name="null"> 940 <context-group name="null">
763 <context context-type="linenumber">57</context> 941 <context context-type="linenumber">55</context>
764 </context-group> 942 </context-group>
765 </trans-unit> 943 </trans-unit>
766 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 944 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
767 <source>Recently added</source> 945 <source>Recently added</source>
768 <target>Récemment ajoutées</target> 946 <target>Récemment ajoutées</target>
769 <context-group name="null"> 947 <context-group name="null">
770 <context context-type="linenumber">62</context> 948 <context context-type="linenumber">60</context>
771 </context-group> 949 </context-group>
772 </trans-unit> 950 </trans-unit>
773 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 951 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
774 <source>Local</source> 952 <source>Local</source>
775 <target>Locales</target> 953 <target>Locales</target>
776 <context-group name="null"> 954 <context-group name="null">
777 <context context-type="linenumber">67</context> 955 <context context-type="linenumber">65</context>
778 </context-group> 956 </context-group>
779 </trans-unit> 957 </trans-unit>
780 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 958 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
781 <source>More</source> 959 <source>More</source>
782 <target>Plus</target> 960 <target>Plus</target>
783 <context-group name="null"> 961 <context-group name="null">
784 <context context-type="linenumber">72</context> 962 <context context-type="linenumber">70</context>
785 </context-group> 963 </context-group>
786 </trans-unit> 964 </trans-unit>
787 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 965 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
788 <source>Administration</source> 966 <source>Administration</source>
789 <target>Administration</target> 967 <target>Administration</target>
790 <context-group name="null"> 968 <context-group name="null">
791 <context context-type="linenumber">76</context> 969 <context context-type="linenumber">74</context>
792 </context-group> 970 </context-group>
793 </trans-unit> 971 </trans-unit>
794 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 972 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -802,14 +980,42 @@
802 <source>Show keyboard shortcuts</source> 980 <source>Show keyboard shortcuts</source>
803 <target>Montrer les raccourcis clavier</target> 981 <target>Montrer les raccourcis clavier</target>
804 <context-group name="null"> 982 <context-group name="null">
805 <context context-type="linenumber">91</context> 983 <context context-type="linenumber">89</context>
806 </context-group> 984 </context-group>
807 </trans-unit> 985 </trans-unit>
808 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 986 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
809 <source>Toggle dark interface</source> 987 <source>Toggle dark interface</source>
810 <target>(Dés)activer le thème sombre</target> 988 <target>(Dés)activer le thème sombre</target>
811 <context-group name="null"> 989 <context-group name="null">
812 <context context-type="linenumber">94</context> 990 <context context-type="linenumber">92</context>
991 </context-group>
992 </trans-unit>
993 <trans-unit id="2dc8a0a3763cd5c456c84630fc335398c9b86771">
994 <source>View your notifications</source>
995 <target>Voir vos notifications</target>
996 <context-group name="null">
997 <context context-type="linenumber">3</context>
998 </context-group>
999 </trans-unit>
1000 <trans-unit id="8bcabdf6b16cad0313a86c7e940c5e3ad7f9f8ab">
1001 <source>Notifications</source>
1002 <target>Notifications</target>
1003 <context-group name="null">
1004 <context context-type="linenumber">10</context>
1005 </context-group>
1006 </trans-unit>
1007 <trans-unit id="341e026e3f317aa3164916cc63a059c961a78b81">
1008 <source>Update your notification preferences</source>
1009 <target>Mettre à jour vos préférences de notification</target>
1010 <context-group name="null">
1011 <context context-type="linenumber">15</context>
1012 </context-group>
1013 </trans-unit>
1014 <trans-unit id="3d1b5c9cd76948c04fdb7bb3fe51b6c1242c1bd5">
1015 <source>See all your notifications</source>
1016 <target>Voir toutes vos notifications</target>
1017 <context-group name="null">
1018 <context context-type="linenumber">22</context>
813 </context-group> 1019 </context-group>
814 </trans-unit> 1020 </trans-unit>
815 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 1021 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -914,14 +1120,14 @@
914 <source>Display unlisted and private videos</source> 1120 <source>Display unlisted and private videos</source>
915 <target>Afficher les vidéos privées et non répertoriées</target> 1121 <target>Afficher les vidéos privées et non répertoriées</target>
916 <context-group name="null"> 1122 <context-group name="null">
917 <context context-type="linenumber">11</context> 1123 <context context-type="linenumber">14</context>
918 </context-group> 1124 </context-group>
919 </trans-unit> 1125 </trans-unit>
920 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 1126 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
921 <source>No results.</source> 1127 <source>No results.</source>
922 <target>Aucun résultat.</target> 1128 <target>Aucun résultat.</target>
923 <context-group name="null"> 1129 <context-group name="null">
924 <context context-type="linenumber">17</context> 1130 <context context-type="linenumber">20</context>
925 </context-group> 1131 </context-group>
926 </trans-unit> 1132 </trans-unit>
927 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 1133 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -979,14 +1185,64 @@
979 <context context-type="linenumber">7</context> 1185 <context context-type="linenumber">7</context>
980 </context-group> 1186 </context-group>
981 </trans-unit> 1187 </trans-unit>
982 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 1188 <trans-unit id="5fea66be16da46ed7a0775e9a62b7b5e94b77473">
1189 <source>Contact <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> administrator</source>
1190 <target>Contacter l'administrateur de <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/></target>
1191 <context-group name="null">
1192 <context context-type="linenumber">3</context>
1193 </context-group>
1194 </trans-unit>
1195 <trans-unit id="533b2b9a76ee1335cb44c01f0bfd50d43e9400b0">
1196 <source>Your name</source>
1197 <target>Votre nom</target>
1198 <context-group name="null">
1199 <context context-type="linenumber">11</context>
1200 </context-group>
1201 </trans-unit>
1202 <trans-unit id="0b892c7805a1c5afc0b7c21c3449760860fe7f3d">
1203 <source>Your email</source>
1204 <target>Votre mail</target>
1205 <context-group name="null">
1206 <context context-type="linenumber">20</context>
1207 </context-group>
1208 </trans-unit>
1209 <trans-unit id="d2815c9b510b8172d8cac4008b9709df69d636df">
1210 <source>Your message</source>
1211 <target>Votre message</target>
1212 <context-group name="null">
1213 <context context-type="linenumber">29</context>
1214 </context-group>
1215 </trans-unit>
1216 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
983 <source> 1217 <source>
984 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 1218 Cancel
985</source> 1219 </source>
986 <target> 1220 <target>
987 À propos de l'instance : <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> </target> 1221 Annuler
1222 </target>
988 <context-group name="null"> 1223 <context-group name="null">
989 <context context-type="linenumber">1</context> 1224 <context context-type="linenumber">26</context>
1225 </context-group>
1226 </trans-unit>
1227 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
1228 <source>Submit</source>
1229 <target>Envoyer</target>
1230 <context-group name="null">
1231 <context context-type="linenumber">31</context>
1232 </context-group>
1233 </trans-unit>
1234 <trans-unit id="89e55a86cb300f06139ff398c9c8bb7376f78b07">
1235 <source>About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance</source>
1236 <target>À propos de l'instance <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/></target>
1237 <context-group name="null">
1238 <context context-type="linenumber">4</context>
1239 </context-group>
1240 </trans-unit>
1241 <trans-unit id="3c1aff50472b313c70a72ee02c081b8eeb1c616c">
1242 <source>Contact administrator</source>
1243 <target>Contact de l'administrateur</target>
1244 <context-group name="null">
1245 <context context-type="linenumber">6</context>
990 </context-group> 1246 </context-group>
991 </trans-unit> 1247 </trans-unit>
992 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 1248 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -1000,47 +1256,47 @@
1000 <source>Terms</source> 1256 <source>Terms</source>
1001 <target>Conditions d'utilisation</target> 1257 <target>Conditions d'utilisation</target>
1002 <context-group name="null"> 1258 <context-group name="null">
1003 <context context-type="linenumber">44</context> 1259 <context context-type="linenumber">39</context>
1004 </context-group> 1260 </context-group>
1005 </trans-unit> 1261 </trans-unit>
1006 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 1262 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
1007 <source>User registration is allowed and</source> 1263 <source>User registration is allowed and</source>
1008 <target>La création de comptes utilisateurs est autorisée et</target> 1264 <target>La création de comptes utilisateurs est autorisée et</target>
1009 <context-group name="null"> 1265 <context-group name="null">
1010 <context context-type="linenumber">25</context> 1266 <context context-type="linenumber">29</context>
1011 </context-group> 1267 </context-group>
1012 </trans-unit> 1268 </trans-unit>
1013 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e"> 1269 <trans-unit id="7a0a7b5a5bc9ee7b7e415f87ecc404145fb51dff">
1014 <source> 1270 <source>
1015 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users. 1271 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
1016 </source> 1272 </source>
1017 <target> 1273 <target>
1018 cette instance fournit un quota de base de <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> pour les vidéos de ses utilisateurs. 1274 cette instance propose un quota d'espace de <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> pour les vidéos de ses utilisateurs.
1019 </target> 1275 </target>
1020 <context-group name="null"> 1276 <context-group name="null">
1021 <context context-type="linenumber">27</context> 1277 <context context-type="linenumber">31</context>
1022 </context-group> 1278 </context-group>
1023 </trans-unit> 1279 </trans-unit>
1024 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae"> 1280 <trans-unit id="7bee5dd41c0007820f150ee33b8257dc1aac281b">
1025 <source> 1281 <source>
1026 this instance provides unlimited space for the videos of its users. 1282 this instance provides unlimited space for the videos of its users.
1027 </source> 1283 </source>
1028 <target> 1284 <target>
1029 cette instance met à disposition de ses utilisateurs un espace de stockage vidéo illimité. 1285 cette instance propose un espace illimité pour les vidéos de ses utilisateurs.
1030 </target> 1286 </target>
1031 <context-group name="null"> 1287 <context-group name="null">
1032 <context context-type="linenumber">31</context> 1288 <context context-type="linenumber">35</context>
1033 </context-group> 1289 </context-group>
1034 </trans-unit> 1290 </trans-unit>
1035 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1"> 1291 <trans-unit id="b6e2ede24a2ee0f6ba2f1924ede2ae408ffc2574">
1036 <source> 1292 <source>
1037 User registration is currently not allowed. 1293 User registration is currently not allowed.
1038 </source> 1294 </source>
1039 <target> 1295 <target>
1040 Vous ne pouvez pas créer de comptes utilisateurs pour le moment. 1296 La création de nouveaux compte n'est pas autorisée pour l'instant.
1041 </target> 1297 </target>
1042 <context-group name="null"> 1298 <context-group name="null">
1043 <context context-type="linenumber">36</context> 1299 <context context-type="linenumber">40</context>
1044 </context-group> 1300 </context-group>
1045 </trans-unit> 1301 </trans-unit>
1046 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 1302 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1397,49 +1653,49 @@
1397 <source>Short description</source> 1653 <source>Short description</source>
1398 <target>Courte description</target> 1654 <target>Courte description</target>
1399 <context-group name="null"> 1655 <context-group name="null">
1400 <context context-type="linenumber">22</context> 1656 <context context-type="linenumber">21</context>
1401 </context-group> 1657 </context-group>
1402 </trans-unit> 1658 </trans-unit>
1403 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1659 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1404 <source>Default client route</source> 1660 <source>Default client route</source>
1405 <target>Route du client par défaut</target> 1661 <target>Route du client par défaut</target>
1406 <context-group name="null"> 1662 <context-group name="null">
1407 <context context-type="linenumber">55</context> 1663 <context context-type="linenumber">48</context>
1408 </context-group> 1664 </context-group>
1409 </trans-unit> 1665 </trans-unit>
1410 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1666 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1411 <source>Videos Overview</source> 1667 <source>Videos Overview</source>
1412 <target>Vue d'ensemble des vidéos</target> 1668 <target>Vue d'ensemble des vidéos</target>
1413 <context-group name="null"> 1669 <context-group name="null">
1414 <context context-type="linenumber">58</context> 1670 <context context-type="linenumber">51</context>
1415 </context-group> 1671 </context-group>
1416 </trans-unit> 1672 </trans-unit>
1417 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1673 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1418 <source>Videos Trending</source> 1674 <source>Videos Trending</source>
1419 <target>Vidéos tendance</target> 1675 <target>Vidéos tendance</target>
1420 <context-group name="null"> 1676 <context-group name="null">
1421 <context context-type="linenumber">59</context> 1677 <context context-type="linenumber">52</context>
1422 </context-group> 1678 </context-group>
1423 </trans-unit> 1679 </trans-unit>
1424 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1680 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1425 <source>Videos Recently Added</source> 1681 <source>Videos Recently Added</source>
1426 <target>Vidéos récemment ajoutées</target> 1682 <target>Vidéos récemment ajoutées</target>
1427 <context-group name="null"> 1683 <context-group name="null">
1428 <context context-type="linenumber">60</context> 1684 <context context-type="linenumber">53</context>
1429 </context-group> 1685 </context-group>
1430 </trans-unit> 1686 </trans-unit>
1431 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1687 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1432 <source>Local videos</source> 1688 <source>Local videos</source>
1433 <target>Vidéos locales</target> 1689 <target>Vidéos locales</target>
1434 <context-group name="null"> 1690 <context-group name="null">
1435 <context context-type="linenumber">61</context> 1691 <context context-type="linenumber">54</context>
1436 </context-group> 1692 </context-group>
1437 </trans-unit> 1693 </trans-unit>
1438 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1694 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1439 <source>Policy on videos containing sensitive content</source> 1695 <source>Policy on videos containing sensitive content</source>
1440 <target>Politique concernant les vidéos ayant du contenu sensible</target> 1696 <target>Politique concernant les vidéos ayant du contenu sensible</target>
1441 <context-group name="null"> 1697 <context-group name="null">
1442 <context context-type="linenumber">70</context> 1698 <context context-type="linenumber">61</context>
1443 </context-group> 1699 </context-group>
1444 </trans-unit> 1700 </trans-unit>
1445 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1701 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1474,23 +1730,44 @@
1474 <source>Signup enabled</source> 1730 <source>Signup enabled</source>
1475 <target>Enregistrement activé</target> 1731 <target>Enregistrement activé</target>
1476 <context-group name="null"> 1732 <context-group name="null">
1477 <context context-type="linenumber">93</context> 1733 <context context-type="linenumber">84</context>
1478 </context-group> 1734 </context-group>
1479 </trans-unit> 1735 </trans-unit>
1480 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1736 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1481 <source>Signup requires email verification</source> 1737 <source>Signup requires email verification</source>
1482 <target>L'inscription requiert la vérification par courriel</target> 1738 <target>L'inscription requiert la vérification par courriel</target>
1483 <context-group name="null"> 1739 <context-group name="null">
1484 <context context-type="linenumber">100</context> 1740 <context context-type="linenumber">91</context>
1485 </context-group> 1741 </context-group>
1486 </trans-unit> 1742 </trans-unit>
1487 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1743 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1488 <source>Signup limit</source> 1744 <source>Signup limit</source>
1489 <target>Limitation des enregistrements</target> 1745 <target>Limitation des enregistrements</target>
1490 <context-group name="null"> 1746 <context-group name="null">
1747 <context context-type="linenumber">96</context>
1748 </context-group>
1749 </trans-unit>
1750 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1751 <source>Users</source>
1752 <target>Utilisateurs</target>
1753 <context-group name="null">
1491 <context context-type="linenumber">105</context> 1754 <context context-type="linenumber">105</context>
1492 </context-group> 1755 </context-group>
1493 </trans-unit> 1756 </trans-unit>
1757 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1758 <source>User default video quota</source>
1759 <target>Quota de vidéos par défaut par utilisateur </target>
1760 <context-group name="null">
1761 <context context-type="linenumber">109</context>
1762 </context-group>
1763 </trans-unit>
1764 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1765 <source>User default daily upload limit</source>
1766 <target>La limite journalière de téléversement est atteinte</target>
1767 <context-group name="null">
1768 <context context-type="linenumber">121</context>
1769 </context-group>
1770 </trans-unit>
1494 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1771 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1495 <source>Import</source> 1772 <source>Import</source>
1496 <target>Importer</target> 1773 <target>Importer</target>
@@ -1502,49 +1779,35 @@
1502 <source>Video import with HTTP URL (i.e. YouTube) enabled</source> 1779 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1503 <target>Import de vidéo via une URL (YouTube par exemple) activé</target> 1780 <target>Import de vidéo via une URL (YouTube par exemple) activé</target>
1504 <context-group name="null"> 1781 <context-group name="null">
1505 <context context-type="linenumber">120</context> 1782 <context context-type="linenumber">141</context>
1506 </context-group> 1783 </context-group>
1507 </trans-unit> 1784 </trans-unit>
1508 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e"> 1785 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e">
1509 <source>Video import with a torrent file or a magnet URI enabled</source> 1786 <source>Video import with a torrent file or a magnet URI enabled</source>
1510 <target>Import de vidéo avec un fichier torrent ou URL magnet activé</target> 1787 <target>Import de vidéo avec un fichier torrent ou URL magnet activé</target>
1511 <context-group name="null"> 1788 <context-group name="null">
1512 <context context-type="linenumber">127</context> 1789 <context context-type="linenumber">148</context>
1513 </context-group> 1790 </context-group>
1514 </trans-unit> 1791 </trans-unit>
1515 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1792 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1516 <source>Administrator</source> 1793 <source>Administrator</source>
1517 <target>Administrateur</target> 1794 <target>Administrateur</target>
1518 <context-group name="null"> 1795 <context-group name="null">
1519 <context context-type="linenumber">131</context> 1796 <context context-type="linenumber">155</context>
1520 </context-group> 1797 </context-group>
1521 </trans-unit> 1798 </trans-unit>
1522 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1799 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1523 <source>Admin email</source> 1800 <source>Admin email</source>
1524 <target>Email de l'administrateur</target> 1801 <target>Email de l'administrateur</target>
1525 <context-group name="null"> 1802 <context-group name="null">
1526 <context context-type="linenumber">134</context> 1803 <context context-type="linenumber">158</context>
1527 </context-group>
1528 </trans-unit>
1529 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1530 <source>Users</source>
1531 <target>Utilisateurs</target>
1532 <context-group name="null">
1533 <context context-type="linenumber">144</context>
1534 </context-group>
1535 </trans-unit>
1536 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1537 <source>User default video quota</source>
1538 <target>Quota de vidéos par défaut par utilisateur </target>
1539 <context-group name="null">
1540 <context context-type="linenumber">147</context>
1541 </context-group> 1804 </context-group>
1542 </trans-unit> 1805 </trans-unit>
1543 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe"> 1806 <trans-unit id="f9bda6652199995a4bd4424f2e35b748eb0bda8a">
1544 <source>User default daily upload limit</source> 1807 <source>Enable contact form</source>
1545 <target>La limite journalière de téléversement est atteinte</target> 1808 <target>Activer le formulaire de contact</target>
1546 <context-group name="null"> 1809 <context-group name="null">
1547 <context context-type="linenumber">161</context> 1810 <context context-type="linenumber">169</context>
1548 </context-group> 1811 </context-group>
1549 </trans-unit> 1812 </trans-unit>
1550 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1813 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1565,21 +1828,32 @@
1565 <source>Your Twitter username</source> 1828 <source>Your Twitter username</source>
1566 <target>Votre identifiant Twitter</target> 1829 <target>Votre identifiant Twitter</target>
1567 <context-group name="null"> 1830 <context-group name="null">
1568 <context context-type="linenumber">181</context> 1831 <context context-type="linenumber">184</context>
1569 </context-group> 1832 </context-group>
1570 </trans-unit> 1833 </trans-unit>
1571 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1834 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1572 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1835 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1573 <target>Indique le compte Twitter pour le site ou la plateforme sur laquelle le contenu a été publié.</target> 1836 <target>Indique le compte Twitter pour le site ou la plateforme sur laquelle le contenu a été publié.</target>
1574 <context-group name="null"> 1837 <context-group name="null">
1575 <context context-type="linenumber">184</context> 1838 <context context-type="linenumber">187</context>
1576 </context-group> 1839 </context-group>
1577 </trans-unit> 1840 </trans-unit>
1578 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1841 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1579 <source>Instance whitelisted by Twitter</source> 1842 <source>Instance whitelisted by Twitter</source>
1580 <target>Instance sur la liste blanche de Twitter</target> 1843 <target>Instance sur la liste blanche de Twitter</target>
1581 <context-group name="null"> 1844 <context-group name="null">
1582 <context context-type="linenumber">198</context> 1845 <context context-type="linenumber">199</context>
1846 </context-group>
1847 </trans-unit>
1848 <trans-unit id="f1276a50033dfc7a71290086d0f57d89e3438e6b">
1849 <source>If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.&lt;br /&gt;
1850 If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.&lt;br /&gt;&lt;br /&gt;
1851 Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on &lt;a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'&gt;https://cards-dev.twitter.com/validator&lt;/a&gt; to see if you instance is whitelisted.</source>
1852 <target>Si votre instance est autorisée par Twitter, un lecteur de vidéo sera inséré dans le flux Twitter pour les partages de vidéo depuis PeerTube.&lt;br /&gt;
1853 Si votre instance n'est pas autorisée, une carte sera inséré avec une image et un lien vers votre instance PeerTube.&lt;br /&gt;&lt;br /&gt;
1854 Selectionnez cette case, sauvegardez la configuration et pour tester si votre instance est autorisée par Twitter, insérez l'URL d'une vidéo de votre instance (https://example.com/videos/watch/blabla) sur &lt;a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'&gt;https://cards-dev.twitter.com/validator&lt;/a&gt;.</target>
1855 <context-group name="null">
1856 <context context-type="linenumber">200</context>
1583 </context-group> 1857 </context-group>
1584 </trans-unit> 1858 </trans-unit>
1585 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1859 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1593,35 +1867,49 @@
1593 <source>Transcoding</source> 1867 <source>Transcoding</source>
1594 <target>Encodage</target> 1868 <target>Encodage</target>
1595 <context-group name="null"> 1869 <context-group name="null">
1596 <context context-type="linenumber">210</context> 1870 <context context-type="linenumber">215</context>
1597 </context-group> 1871 </context-group>
1598 </trans-unit> 1872 </trans-unit>
1599 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1873 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1600 <source>Transcoding enabled</source> 1874 <source>Transcoding enabled</source>
1601 <target>Encodage activé</target> 1875 <target>Encodage activé</target>
1602 <context-group name="null"> 1876 <context-group name="null">
1603 <context context-type="linenumber">215</context> 1877 <context context-type="linenumber">221</context>
1604 </context-group> 1878 </context-group>
1605 </trans-unit> 1879 </trans-unit>
1606 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1880 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1607 <source>If you disable transcoding, many videos from your users will not work!</source> 1881 <source>If you disable transcoding, many videos from your users will not work!</source>
1608 <target>Si vous désactivez le transcodage, de nombreuses vidéos d'utilisateurs ne fonctionneront pas !</target> 1882 <target>Si vous désactivez le transcodage, de nombreuses vidéos d'utilisateurs ne fonctionneront pas !</target>
1609 <context-group name="null"> 1883 <context-group name="null">
1610 <context context-type="linenumber">216</context> 1884 <context context-type="linenumber">222</context>
1885 </context-group>
1886 </trans-unit>
1887 <trans-unit id="0050a55afb9c565df1f9b3f750c2d4adb697698f">
1888 <source>Allow additional extensions</source>
1889 <target>Permettre des extensions additionnelles</target>
1890 <context-group name="null">
1891 <context context-type="linenumber">231</context>
1892 </context-group>
1893 </trans-unit>
1894 <trans-unit id="9b82c3a407ee5a98c92483fbd987be8db8384c33">
1895 <source>Allow your users to upload .mkv, .mov, .avi, .flv videos</source>
1896 <target>Autoriser vos utilisateurs à publier des vidéos .mkv, .mov, .avi et .flv.</target>
1897 <context-group name="null">
1898 <context context-type="linenumber">232</context>
1611 </context-group> 1899 </context-group>
1612 </trans-unit> 1900 </trans-unit>
1613 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1901 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1614 <source>Transcoding threads</source> 1902 <source>Transcoding threads</source>
1615 <target>Nombre de threads pour l'encodage</target> 1903 <target>Nombre de threads pour l'encodage</target>
1616 <context-group name="null"> 1904 <context-group name="null">
1617 <context context-type="linenumber">223</context> 1905 <context context-type="linenumber">237</context>
1618 </context-group> 1906 </context-group>
1619 </trans-unit> 1907 </trans-unit>
1620 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1908 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1621 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1909 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1622 <target>Résolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> activée</target> 1910 <target>Résolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> activée</target>
1623 <context-group name="null"> 1911 <context-group name="null">
1624 <context context-type="linenumber">239</context> 1912 <context context-type="linenumber">252</context>
1625 </context-group> 1913 </context-group>
1626 </trans-unit> 1914 </trans-unit>
1627 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1915 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1636,105 +1924,105 @@
1636 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1924 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1637 </target> 1925 </target>
1638 <context-group name="null"> 1926 <context-group name="null">
1639 <context context-type="linenumber">244</context> 1927 <context context-type="linenumber">260</context>
1640 </context-group> 1928 </context-group>
1641 </trans-unit> 1929 </trans-unit>
1642 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1930 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1643 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1931 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1644 <target>Certain fichiers ne sont pas fédérés (miniature, sous-titre). Nous les récupérons directement depuis l'instance d'origine et nous les gardons en cache.</target> 1932 <target>Certain fichiers ne sont pas fédérés (miniature, sous-titre). Nous les récupérons directement depuis l'instance d'origine et nous les gardons en cache.</target>
1645 <context-group name="null"> 1933 <context-group name="null">
1646 <context context-type="linenumber">249</context> 1934 <context context-type="linenumber">265</context>
1647 </context-group> 1935 </context-group>
1648 </trans-unit> 1936 </trans-unit>
1649 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1937 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1650 <source>Previews cache size</source> 1938 <source>Previews cache size</source>
1651 <target>Taille du cache des prévisualisations </target> 1939 <target>Taille du cache des prévisualisations </target>
1652 <context-group name="null"> 1940 <context-group name="null">
1653 <context context-type="linenumber">254</context> 1941 <context context-type="linenumber">271</context>
1654 </context-group> 1942 </context-group>
1655 </trans-unit> 1943 </trans-unit>
1656 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1944 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1657 <source>Video captions cache size</source> 1945 <source>Video captions cache size</source>
1658 <target>Taille du cache des sous-titres</target> 1946 <target>Taille du cache des sous-titres</target>
1659 <context-group name="null"> 1947 <context-group name="null">
1660 <context context-type="linenumber">265</context> 1948 <context context-type="linenumber">280</context>
1661 </context-group> 1949 </context-group>
1662 </trans-unit> 1950 </trans-unit>
1663 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1951 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1664 <source>Customizations</source> 1952 <source>Customizations</source>
1665 <target>Personnalisations</target> 1953 <target>Personnalisations</target>
1666 <context-group name="null"> 1954 <context-group name="null">
1667 <context context-type="linenumber">275</context> 1955 <context context-type="linenumber">289</context>
1668 </context-group> 1956 </context-group>
1669 </trans-unit> 1957 </trans-unit>
1670 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1958 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1671 <source>JavaScript</source> 1959 <source>JavaScript</source>
1672 <target>JavaScript</target> 1960 <target>JavaScript</target>
1673 <context-group name="null"> 1961 <context-group name="null">
1674 <context context-type="linenumber">278</context> 1962 <context context-type="linenumber">294</context>
1675 </context-group> 1963 </context-group>
1676 </trans-unit> 1964 </trans-unit>
1677 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1965 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1678 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1966 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1679 <target>Écrivez directement du code JavaScript.&lt;br /&gt;Exemple : &lt;pre&gt;console.log('mon instance est super géniale');&lt;/pre&gt;</target> 1967 <target>Écrivez directement du code JavaScript.&lt;br /&gt;Exemple : &lt;pre&gt;console.log('mon instance est super géniale');&lt;/pre&gt;</target>
1680 <context-group name="null"> 1968 <context-group name="null">
1681 <context context-type="linenumber">281</context> 1969 <context context-type="linenumber">297</context>
1682 </context-group> 1970 </context-group>
1683 </trans-unit> 1971 </trans-unit>
1684 <trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5"> 1972 <trans-unit id="d7caa08cd9b3119881bbaec3f5a3c5707f573dde">
1685 <source> 1973 <source>
1686 Write directly CSS code. Example:&lt;br /&gt; 1974 Write directly CSS code. Example:&lt;br /&gt;
1687 &lt;pre&gt; 1975 &lt;pre&gt;
1688 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/> 1976 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1689 background-color: red; 1977 background-color: red;
1690 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/> 1978 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1691 &lt;/pre&gt; 1979 &lt;/pre&gt;
1692 1980
1693 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example: 1981 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1694 &lt;pre&gt; 1982 &lt;pre&gt;
1695 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/> 1983 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1696 color: red; 1984 color: red;
1697 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/> 1985 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1698 &lt;/pre&gt; 1986 &lt;/pre&gt;
1699 </source> 1987 </source>
1700 <target> 1988 <target>
1701 Écrivez directement du code CSS. Exemple :&lt;br /&gt; 1989 Écrivez directement du code CSS. Par exemple:&lt;br /&gt;
1702 &lt;pre&gt; 1990 &lt;pre&gt;
1703 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/> 1991 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1704 background-color: red; 1992 background-color: red;
1705 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/> 1993 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1706 &lt;/pre&gt; 1994 &lt;/pre&gt;
1707 1995
1708 Ajoutez le préfixe &lt;em&gt;#custom-css&lt;/em&gt; pour remplacer les styles. Exemple: 1996 Ajoutez le préfixe &lt;em&gt;#custom-css&lt;/em&gt; pour surcharger les styles. Par exemple:
1709 &lt;pre&gt; 1997 &lt;pre&gt;
1710 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/> 1998 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1711 color: red; 1999 color: red;
1712 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/> 2000 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1713 &lt;/pre&gt; 2001 &lt;/pre&gt;
1714 </target> 2002 </target>
1715 <context-group name="null"> 2003 <context-group name="null">
1716 <context context-type="linenumber">297</context> 2004 <context context-type="linenumber">311</context>
1717 </context-group> 2005 </context-group>
1718 </trans-unit> 2006 </trans-unit>
1719 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab"> 2007 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab">
1720 <source>Advanced configuration</source> 2008 <source>Advanced configuration</source>
1721 <target>Configuration avancée</target> 2009 <target>Configuration avancée</target>
1722 <context-group name="null"> 2010 <context-group name="null">
1723 <context context-type="linenumber">207</context> 2011 <context context-type="linenumber">212</context>
1724 </context-group> 2012 </context-group>
1725 </trans-unit> 2013 </trans-unit>
1726 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 2014 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1727 <source>Update configuration</source> 2015 <source>Update configuration</source>
1728 <target>Mettre à jour la configuration</target> 2016 <target>Mettre à jour la configuration</target>
1729 <context-group name="null"> 2017 <context-group name="null">
1730 <context context-type="linenumber">325</context> 2018 <context context-type="linenumber">340</context>
1731 </context-group> 2019 </context-group>
1732 </trans-unit> 2020 </trans-unit>
1733 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 2021 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1734 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 2022 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1735 <target>Il semblerait que la configuration soit invalide. Merci de chercher des erreurs potentielles dans les différents onglets.</target> 2023 <target>Il semblerait que la configuration soit invalide. Merci de chercher des erreurs potentielles dans les différents onglets.</target>
1736 <context-group name="null"> 2024 <context-group name="null">
1737 <context context-type="linenumber">326</context> 2025 <context context-type="linenumber">341</context>
1738 </context-group> 2026 </context-group>
1739 </trans-unit> 2027 </trans-unit>
1740 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 2028 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -2026,11 +2314,25 @@
2026 <context context-type="linenumber">133</context> 2314 <context context-type="linenumber">133</context>
2027 </context-group> 2315 </context-group>
2028 </trans-unit> 2316 </trans-unit>
2317 <trans-unit id="02ba1a65db92d1d0ab4ba380086e9be61891aaa5">
2318 <source>User's email must be verified to login</source>
2319 <target>L'adresse mail de l'utilisateur doit être vérifiée afin de se connecter</target>
2320 <context-group name="null">
2321 <context context-type="linenumber">72</context>
2322 </context-group>
2323 </trans-unit>
2324 <trans-unit id="79cee9973620b2592ff2824c525aa8ed0b5e2b8b">
2325 <source>User's email is verified / User can login without email verification</source>
2326 <target>L'adresse mail de l'utilisateur est vérifié / L'utilisateur peut se connecter sans vérification mail</target>
2327 <context-group name="null">
2328 <context context-type="linenumber">76</context>
2329 </context-group>
2330 </trans-unit>
2029 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee"> 2331 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee">
2030 <source>Ban reason:</source> 2332 <source>Ban reason:</source>
2031 <target>Raison du bannissement :</target> 2333 <target>Raison du bannissement :</target>
2032 <context-group name="null"> 2334 <context-group name="null">
2033 <context context-type="linenumber">92</context> 2335 <context context-type="linenumber">95</context>
2034 </context-group> 2336 </context-group>
2035 </trans-unit> 2337 </trans-unit>
2036 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 2338 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -2097,7 +2399,7 @@
2097 <source>Actions</source> 2399 <source>Actions</source>
2098 <target>Actions</target> 2400 <target>Actions</target>
2099 <context-group name="null"> 2401 <context-group name="null">
2100 <context context-type="linenumber">33</context> 2402 <context context-type="linenumber">35</context>
2101 </context-group> 2403 </context-group>
2102 </trans-unit> 2404 </trans-unit>
2103 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 2405 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -2132,14 +2434,14 @@
2132 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 2434 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2133 <target>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 2435 <target>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2134 <context-group name="null"> 2436 <context-group name="null">
2135 <context context-type="linenumber">10</context> 2437 <context context-type="linenumber">11</context>
2136 </context-group> 2438 </context-group>
2137 </trans-unit> 2439 </trans-unit>
2138 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f"> 2440 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
2139 <source>Blacklist reason:</source> 2441 <source>Blacklist reason:</source>
2140 <target>Raison de mise sur liste noire :</target> 2442 <target>Raison de mise sur liste noire :</target>
2141 <context-group name="null"> 2443 <context-group name="null">
2142 <context context-type="linenumber">41</context> 2444 <context context-type="linenumber">43</context>
2143 </context-group> 2445 </context-group>
2144 </trans-unit> 2446 </trans-unit>
2145 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 2447 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -2198,69 +2500,6 @@
2198 <context context-type="linenumber">23</context> 2500 <context context-type="linenumber">23</context>
2199 </context-group> 2501 </context-group>
2200 </trans-unit> 2502 </trans-unit>
2201 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2202 <source>My settings</source>
2203 <target>Mes paramètres</target>
2204 <context-group name="null">
2205 <context context-type="linenumber">3</context>
2206 </context-group>
2207 </trans-unit>
2208 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2209 <source>My library</source>
2210 <target>Ma bibliothèque</target>
2211 <context-group name="null">
2212 <context context-type="linenumber">7</context>
2213 </context-group>
2214 </trans-unit>
2215 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2216 <source>My channels</source>
2217 <target>Mes chaînes</target>
2218 <context-group name="null">
2219 <context context-type="linenumber">12</context>
2220 </context-group>
2221 </trans-unit>
2222 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2223 <source>My videos</source>
2224 <target>Mes vidéos</target>
2225 <context-group name="null">
2226 <context context-type="linenumber">14</context>
2227 </context-group>
2228 </trans-unit>
2229 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2230 <source>My subscriptions</source>
2231 <target>Mes abonnements</target>
2232 <context-group name="null">
2233 <context context-type="linenumber">16</context>
2234 </context-group>
2235 </trans-unit>
2236 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
2237 <source>My imports</source>
2238 <target>Mes imports</target>
2239 <context-group name="null">
2240 <context context-type="linenumber">18</context>
2241 </context-group>
2242 </trans-unit>
2243 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
2244 <source>Misc</source>
2245 <target>Divers</target>
2246 <context-group name="null">
2247 <context context-type="linenumber">24</context>
2248 </context-group>
2249 </trans-unit>
2250 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2251 <source>Muted instances</source>
2252 <target>Instances muettes</target>
2253 <context-group name="null">
2254 <context context-type="linenumber">2</context>
2255 </context-group>
2256 </trans-unit>
2257 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
2258 <source>Ownership changes</source>
2259 <target>Changements de propriétaires</target>
2260 <context-group name="null">
2261 <context context-type="linenumber">33</context>
2262 </context-group>
2263 </trans-unit>
2264 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 2503 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
2265 <source>Video quota:</source> 2504 <source>Video quota:</source>
2266 <target>Quota de vidéos :</target> 2505 <target>Quota de vidéos :</target>
@@ -2272,21 +2511,21 @@
2272 <source>Profile</source> 2511 <source>Profile</source>
2273 <target>Profil</target> 2512 <target>Profil</target>
2274 <context-group name="null"> 2513 <context-group name="null">
2275 <context context-type="linenumber">8</context> 2514 <context context-type="linenumber">7</context>
2276 </context-group> 2515 </context-group>
2277 </trans-unit> 2516 </trans-unit>
2278 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 2517 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
2279 <source>Video settings</source> 2518 <source>Video settings</source>
2280 <target>Paramètres de la vidéo</target> 2519 <target>Paramètres de la vidéo</target>
2281 <context-group name="null"> 2520 <context-group name="null">
2282 <context context-type="linenumber">15</context> 2521 <context context-type="linenumber">16</context>
2283 </context-group> 2522 </context-group>
2284 </trans-unit> 2523 </trans-unit>
2285 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 2524 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
2286 <source>Danger zone</source> 2525 <source>Danger zone</source>
2287 <target>Zone dangereuse</target> 2526 <target>Zone dangereuse</target>
2288 <context-group name="null"> 2527 <context-group name="null">
2289 <context context-type="linenumber">18</context> 2528 <context context-type="linenumber">19</context>
2290 </context-group> 2529 </context-group>
2291 </trans-unit> 2530 </trans-unit>
2292 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 2531 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -2314,13 +2553,6 @@
2314 <context context-type="linenumber">35</context> 2553 <context context-type="linenumber">35</context>
2315 </context-group> 2554 </context-group>
2316 </trans-unit> 2555 </trans-unit>
2317 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
2318 <source>Submit</source>
2319 <target>Envoyer</target>
2320 <context-group name="null">
2321 <context context-type="linenumber">24</context>
2322 </context-group>
2323 </trans-unit>
2324 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 2556 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
2325 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 2557 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2326 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> vues</target> 2558 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> vues</target>
@@ -2480,6 +2712,55 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2480 <context context-type="linenumber">47</context> 2712 <context context-type="linenumber">47</context>
2481 </context-group> 2713 </context-group>
2482 </trans-unit> 2714 </trans-unit>
2715 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2716 <source>Muted instances</source>
2717 <target>Instances muettes</target>
2718 <context-group name="null">
2719 <context context-type="linenumber">2</context>
2720 </context-group>
2721 </trans-unit>
2722 <trans-unit id="e8e93a7ae9a47c035bf5170b105c418b1deae530">
2723 <source>History enabled</source>
2724 <target>Historique activé</target>
2725 <context-group name="null">
2726 <context context-type="linenumber">4</context>
2727 </context-group>
2728 </trans-unit>
2729 <trans-unit id="0f1fd6758625c6a39d796378d362cdcc2b092123">
2730 <source>Delete history</source>
2731 <target>Supprimer l'historique</target>
2732 <context-group name="null">
2733 <context context-type="linenumber">8</context>
2734 </context-group>
2735 </trans-unit>
2736 <trans-unit id="6b4dc5732f1f2211833d4b5e76deb5985f3749af">
2737 <source>You don't have videos history yet.</source>
2738 <target>Vous n'avez pas d'historique de vidéos pour l'instant.</target>
2739 <context-group name="null">
2740 <context context-type="linenumber">13</context>
2741 </context-group>
2742 </trans-unit>
2743 <trans-unit id="6aec8cb024acc333218d72f279caa8ea623bb628">
2744 <source><x id="INTERPOLATION" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2745 <target><x id="INTERPOLATION" equiv-text="{{ video.views | myNumberFormatter }}"/> vues</target>
2746 <context-group name="null">
2747 <context context-type="linenumber">22</context>
2748 </context-group>
2749 </trans-unit>
2750 <trans-unit id="3a6903ba6b8cf2d828d0c86fd1feb09a27be4105">
2751 <source>Notification preferences</source>
2752 <target>Préférences de notification</target>
2753 <context-group name="null">
2754 <context context-type="linenumber">2</context>
2755 </context-group>
2756 </trans-unit>
2757 <trans-unit id="1da23f4068fd3796fbcb24d0c42bb62f92c96829">
2758 <source>Mark all as read</source>
2759 <target>Tout marqué comme lu</target>
2760 <context-group name="null">
2761 <context context-type="linenumber">4</context>
2762 </context-group>
2763 </trans-unit>
2483 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 2764 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
2484 <source>Change password</source> 2765 <source>Change password</source>
2485 <target>Changer le mot de passe</target> 2766 <target>Changer le mot de passe</target>
@@ -2578,6 +2859,20 @@ Quand vous mettrez en ligne une vidéo sur cette chaîne, la vidéo affichera au
2578 <context context-type="linenumber">4</context> 2859 <context context-type="linenumber">4</context>
2579 </context-group> 2860 </context-group>
2580 </trans-unit> 2861 </trans-unit>
2862 <trans-unit id="dd3b6c367381ddfa8f317b8e9b31c55368c65136">
2863 <source>Activities</source>
2864 <target>Activités</target>
2865 <context-group name="null">
2866 <context context-type="linenumber">2</context>
2867 </context-group>
2868 </trans-unit>
2869 <trans-unit id="847dffd493abbb2a5c71f3313f0eb730dd88a355">
2870 <source>Web</source>
2871 <target>Web</target>
2872 <context-group name="null">
2873 <context context-type="linenumber">3</context>
2874 </context-group>
2875 </trans-unit>
2581 <trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd"> 2876 <trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd">
2582 <source> 2877 <source>
2583 Sorry, but we couldn't find the page you were looking for. 2878 Sorry, but we couldn't find the page you were looking for.
@@ -2686,6 +2981,13 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
2686 <context context-type="linenumber">159</context> 2981 <context context-type="linenumber">159</context>
2687 </context-group> 2982 </context-group>
2688 </trans-unit> 2983 </trans-unit>
2984 <trans-unit id="385811ab5a5c3e96e0db46c9ce1fc3147d8cd4c7">
2985 <source>Sorry, but something went wrong</source>
2986 <target>Désolé, mais quelque chose s'est mal passé</target>
2987 <context-group name="null">
2988 <context context-type="linenumber">49</context>
2989 </context-group>
2990 </trans-unit>
2689 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2"> 2991 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2">
2690 <source> 2992 <source>
2691 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video. 2993 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video.
@@ -2722,14 +3024,14 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
2722 <source>Publish will be available when upload is finished</source> 3024 <source>Publish will be available when upload is finished</source>
2723 <target>Vous pourrez publier cette vidéo lorsque l'envoi sera terminé</target> 3025 <target>Vous pourrez publier cette vidéo lorsque l'envoi sera terminé</target>
2724 <context-group name="null"> 3026 <context-group name="null">
2725 <context context-type="linenumber">53</context> 3027 <context context-type="linenumber">58</context>
2726 </context-group> 3028 </context-group>
2727 </trans-unit> 3029 </trans-unit>
2728 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 3030 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2729 <source>Publish</source> 3031 <source>Publish</source>
2730 <target>Publier</target> 3032 <target>Publier</target>
2731 <context-group name="null"> 3033 <context-group name="null">
2732 <context context-type="linenumber">60</context> 3034 <context context-type="linenumber">65</context>
2733 </context-group> 3035 </context-group>
2734 </trans-unit> 3036 </trans-unit>
2735 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 3037 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -2912,14 +3214,14 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
2912 <source>Wait transcoding before publishing the video</source> 3214 <source>Wait transcoding before publishing the video</source>
2913 <target>Attendre l'encodage avant de publier la vidéo</target> 3215 <target>Attendre l'encodage avant de publier la vidéo</target>
2914 <context-group name="null"> 3216 <context-group name="null">
2915 <context context-type="linenumber">130</context> 3217 <context context-type="linenumber">131</context>
2916 </context-group> 3218 </context-group>
2917 </trans-unit> 3219 </trans-unit>
2918 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 3220 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2919 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 3221 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
2920 <target>Si vous décidez de ne pas attendre la fin du traitement avant la publication de la vidéo, elle pourrait bien être injouable.</target> 3222 <target>Si vous décidez de ne pas attendre la fin du traitement avant la publication de la vidéo, elle pourrait bien être injouable.</target>
2921 <context-group name="null"> 3223 <context-group name="null">
2922 <context context-type="linenumber">131</context> 3224 <context context-type="linenumber">132</context>
2923 </context-group> 3225 </context-group>
2924 </trans-unit> 3226 </trans-unit>
2925 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 3227 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2933,49 +3235,49 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
2933 <source>Add another caption</source> 3235 <source>Add another caption</source>
2934 <target>Ajouter un nouveau sous-titre</target> 3236 <target>Ajouter un nouveau sous-titre</target>
2935 <context-group name="null"> 3237 <context-group name="null">
2936 <context context-type="linenumber">146</context> 3238 <context context-type="linenumber">147</context>
2937 </context-group> 3239 </context-group>
2938 </trans-unit> 3240 </trans-unit>
2939 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 3241 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2940 <source>See the subtitle file</source> 3242 <source>See the subtitle file</source>
2941 <target>Voir le fichier de sous-titres</target> 3243 <target>Voir le fichier de sous-titres</target>
2942 <context-group name="null"> 3244 <context-group name="null">
2943 <context context-type="linenumber">155</context> 3245 <context context-type="linenumber">156</context>
2944 </context-group> 3246 </context-group>
2945 </trans-unit> 3247 </trans-unit>
2946 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee"> 3248 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee">
2947 <source>Already uploaded ✔</source> 3249 <source>Already uploaded ✔</source>
2948 <target>Déjà téléversé ✔</target> 3250 <target>Déjà téléversé ✔</target>
2949 <context-group name="null"> 3251 <context-group name="null">
2950 <context context-type="linenumber">159</context> 3252 <context context-type="linenumber">160</context>
2951 </context-group> 3253 </context-group>
2952 </trans-unit> 3254 </trans-unit>
2953 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad"> 3255 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad">
2954 <source>Will be created on update</source> 3256 <source>Will be created on update</source>
2955 <target>Sera créé après la mise à jour</target> 3257 <target>Sera créé après la mise à jour</target>
2956 <context-group name="null"> 3258 <context-group name="null">
2957 <context context-type="linenumber">167</context> 3259 <context context-type="linenumber">168</context>
2958 </context-group> 3260 </context-group>
2959 </trans-unit> 3261 </trans-unit>
2960 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 3262 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2961 <source>Cancel create</source> 3263 <source>Cancel create</source>
2962 <target>Annuler la création</target> 3264 <target>Annuler la création</target>
2963 <context-group name="null"> 3265 <context-group name="null">
2964 <context context-type="linenumber">169</context> 3266 <context context-type="linenumber">170</context>
2965 </context-group> 3267 </context-group>
2966 </trans-unit> 3268 </trans-unit>
2967 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393"> 3269 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393">
2968 <source>Will be deleted on update</source> 3270 <source>Will be deleted on update</source>
2969 <target>Sera supprimé après la mise à jour</target> 3271 <target>Sera supprimé après la mise à jour</target>
2970 <context-group name="null"> 3272 <context-group name="null">
2971 <context context-type="linenumber">175</context> 3273 <context context-type="linenumber">176</context>
2972 </context-group> 3274 </context-group>
2973 </trans-unit> 3275 </trans-unit>
2974 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 3276 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2975 <source>Cancel deletion</source> 3277 <source>Cancel deletion</source>
2976 <target>Annuler la suppression</target> 3278 <target>Annuler la suppression</target>
2977 <context-group name="null"> 3279 <context-group name="null">
2978 <context context-type="linenumber">177</context> 3280 <context context-type="linenumber">178</context>
2979 </context-group> 3281 </context-group>
2980 </trans-unit> 3282 </trans-unit>
2981 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0"> 3283 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0">
@@ -2986,28 +3288,28 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
2986 Pas de sous-titres pour le moment. 3288 Pas de sous-titres pour le moment.
2987 </target> 3289 </target>
2988 <context-group name="null"> 3290 <context-group name="null">
2989 <context context-type="linenumber">182</context> 3291 <context context-type="linenumber">183</context>
2990 </context-group> 3292 </context-group>
2991 </trans-unit> 3293 </trans-unit>
2992 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 3294 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2993 <source>Captions</source> 3295 <source>Captions</source>
2994 <target>Sous-titres</target> 3296 <target>Sous-titres</target>
2995 <context-group name="null"> 3297 <context-group name="null">
2996 <context context-type="linenumber">139</context> 3298 <context context-type="linenumber">140</context>
2997 </context-group> 3299 </context-group>
2998 </trans-unit> 3300 </trans-unit>
2999 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 3301 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
3000 <source>Upload thumbnail</source> 3302 <source>Upload thumbnail</source>
3001 <target>Téléverser une vignette</target> 3303 <target>Téléverser une vignette</target>
3002 <context-group name="null"> 3304 <context-group name="null">
3003 <context context-type="linenumber">195</context> 3305 <context context-type="linenumber">196</context>
3004 </context-group> 3306 </context-group>
3005 </trans-unit> 3307 </trans-unit>
3006 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 3308 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
3007 <source>Upload preview</source> 3309 <source>Upload preview</source>
3008 <target>Téléverser un aperçu</target> 3310 <target>Téléverser un aperçu</target>
3009 <context-group name="null"> 3311 <context-group name="null">
3010 <context context-type="linenumber">202</context> 3312 <context context-type="linenumber">203</context>
3011 </context-group> 3313 </context-group>
3012 </trans-unit> 3314 </trans-unit>
3013 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 3315 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -3021,14 +3323,14 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
3021 <source>Short text to tell people how they can support you (membership platform...).</source> 3323 <source>Short text to tell people how they can support you (membership platform...).</source>
3022 <target>Courte description des moyens qu'ont les utilisateurs de vous soutenir (financement participatif, etc.).</target> 3324 <target>Courte description des moyens qu'ont les utilisateurs de vous soutenir (financement participatif, etc.).</target>
3023 <context-group name="null"> 3325 <context-group name="null">
3024 <context context-type="linenumber">209</context> 3326 <context context-type="linenumber">210</context>
3025 </context-group> 3327 </context-group>
3026 </trans-unit> 3328 </trans-unit>
3027 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 3329 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
3028 <source>Advanced settings</source> 3330 <source>Advanced settings</source>
3029 <target>Paramétrage avancé</target> 3331 <target>Paramétrage avancé</target>
3030 <context-group name="null"> 3332 <context-group name="null">
3031 <context context-type="linenumber">190</context> 3333 <context context-type="linenumber">191</context>
3032 </context-group> 3334 </context-group>
3033 </trans-unit> 3335 </trans-unit>
3034 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 3336 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -3095,15 +3397,17 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
3095 <context context-type="linenumber">3</context> 3397 <context context-type="linenumber">3</context>
3096 </context-group> 3398 </context-group>
3097 </trans-unit> 3399 </trans-unit>
3098 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb"> 3400 <trans-unit id="827b1376aa35c7a7de90f7724d6a51ccfa20c908">
3099 <source> 3401 <source>
3100 Cancel 3402 Your report will be sent to moderators of <x id="INTERPOLATION" equiv-text="{{ currentHost }}"/>.
3101 </source> 3403 <x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/> It will be forwarded to origin instance <x id="INTERPOLATION_1" equiv-text="{{ originHost }}"/> too.<x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
3404 </source>
3102 <target> 3405 <target>
3103 Annuler 3406 Votre signalement sera envoyé aux modérateurs de <x id="INTERPOLATION" equiv-text="{{ currentHost }}"/>.
3104 </target> 3407 <x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/> Il sera également transmis à l'instance d'origine <x id="INTERPOLATION_1" equiv-text="{{ originHost }}"/><x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
3408 </target>
3105 <context-group name="null"> 3409 <context-group name="null">
3106 <context context-type="linenumber">19</context> 3410 <context context-type="linenumber">9</context>
3107 </context-group> 3411 </context-group>
3108 </trans-unit> 3412 </trans-unit>
3109 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 3413 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
@@ -3491,9 +3795,23 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
3491 <context context-type="linenumber">14</context> 3795 <context context-type="linenumber">14</context>
3492 </context-group> 3796 </context-group>
3493 </trans-unit> 3797 </trans-unit>
3494 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08"> 3798 <trans-unit id="e0e3a472479c8ce1b78f682ffadbe59daf04d331">
3495 <source>Error getting about from server</source> 3799 <source>Cannot get about information from server</source>
3496 <target>Erreur lors de la récupération des informations 'à propos' du serveur</target> 3800 <target>Impossible d'obtenir la description du serveur</target>
3801 <context-group name="null">
3802 <context context-type="linenumber">1</context>
3803 </context-group>
3804 </trans-unit>
3805 <trans-unit id="9e601a3b227bb70afbb9b59cd43547b710af1e10">
3806 <source>Your message has been sent.</source>
3807 <target>Votre message a été envoyé</target>
3808 <context-group name="null">
3809 <context context-type="linenumber">1</context>
3810 </context-group>
3811 </trans-unit>
3812 <trans-unit id="8d6d4f48dae547bb32e0669cda5a665dc8db536c">
3813 <source>You already sent this form recently</source>
3814 <target>Vous avez déjà rempli ce formulaire récemment</target>
3497 <context-group name="null"> 3815 <context-group name="null">
3498 <context context-type="linenumber">1</context> 3816 <context context-type="linenumber">1</context>
3499 </context-group> 3817 </context-group>
@@ -3519,13 +3837,6 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
3519 <context context-type="linenumber">1</context> 3837 <context context-type="linenumber">1</context>
3520 </context-group> 3838 </context-group>
3521 </trans-unit> 3839 </trans-unit>
3522 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
3523 <source>Error</source>
3524 <target>Erreur</target>
3525 <context-group name="null">
3526 <context context-type="linenumber">1</context>
3527 </context-group>
3528 </trans-unit>
3529 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6"> 3840 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
3530 <source>240p</source> 3841 <source>240p</source>
3531 <target>240p</target> 3842 <target>240p</target>
@@ -3568,13 +3879,6 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
3568 <context context-type="linenumber">1</context> 3879 <context context-type="linenumber">1</context>
3569 </context-group> 3880 </context-group>
3570 </trans-unit> 3881 </trans-unit>
3571 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
3572 <source>Success</source>
3573 <target>Réussite</target>
3574 <context-group name="null">
3575 <context context-type="linenumber">1</context>
3576 </context-group>
3577 </trans-unit>
3578 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 3882 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
3579 <source>Configuration updated.</source> 3883 <source>Configuration updated.</source>
3580 <target>La configuration a été mise à jour.</target> 3884 <target>La configuration a été mise à jour.</target>
@@ -3841,6 +4145,13 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
3841 <context context-type="linenumber">1</context> 4145 <context context-type="linenumber">1</context>
3842 </context-group> 4146 </context-group>
3843 </trans-unit> 4147 </trans-unit>
4148 <trans-unit id="910ed85f550272401b134a40d019ab3359fe883f">
4149 <source>Set Email as Verified</source>
4150 <target>Définir l'adresse mail comme vérifiée</target>
4151 <context-group name="null">
4152 <context context-type="linenumber">1</context>
4153 </context-group>
4154 </trans-unit>
3844 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf"> 4155 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf">
3845 <source>You cannot ban root.</source> 4156 <source>You cannot ban root.</source>
3846 <target>Vous ne pouvez pas bannir root.</target> 4157 <target>Vous ne pouvez pas bannir root.</target>
@@ -3883,6 +4194,13 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
3883 <context context-type="linenumber">1</context> 4194 <context context-type="linenumber">1</context>
3884 </context-group> 4195 </context-group>
3885 </trans-unit> 4196 </trans-unit>
4197 <trans-unit id="f4a8f2ef1fbfc19e1e049e69f63c40063c0d0650">
4198 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users email set as verified.</source>
4199 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> adresses mail d'utilisateurs ont été vérifiées.</target>
4200 <context-group name="null">
4201 <context context-type="linenumber">1</context>
4202 </context-group>
4203 </trans-unit>
3886 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de"> 4204 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de">
3887 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source> 4205 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source>
3888 <target>Compte <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> réactivé.</target> 4206 <target>Compte <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> réactivé.</target>
@@ -3897,6 +4215,48 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
3897 <context context-type="linenumber">1</context> 4215 <context context-type="linenumber">1</context>
3898 </context-group> 4216 </context-group>
3899 </trans-unit> 4217 </trans-unit>
4218 <trans-unit id="80057baa3b97a4349304bdaa0a880e6f4778561f">
4219 <source>My videos history</source>
4220 <target>Mon historique de vidéos</target>
4221 <context-group name="null">
4222 <context context-type="linenumber">1</context>
4223 </context-group>
4224 </trans-unit>
4225 <trans-unit id="05f6dda1754741495451b8658bd2248856765d95">
4226 <source>Videos history is enabled</source>
4227 <target>Historique de vidéos activé</target>
4228 <context-group name="null">
4229 <context context-type="linenumber">1</context>
4230 </context-group>
4231 </trans-unit>
4232 <trans-unit id="6bb9ade8637c5e35fb5cb36cf7dbec71c65d4013">
4233 <source>Videos history is disabled</source>
4234 <target>Historique de vidéos désactivé</target>
4235 <context-group name="null">
4236 <context context-type="linenumber">1</context>
4237 </context-group>
4238 </trans-unit>
4239 <trans-unit id="8453a7a55b8b23bbbc293cd0939fb59a73307de8">
4240 <source>Delete videos history</source>
4241 <target>Supprimer l'historique de vidéos</target>
4242 <context-group name="null">
4243 <context context-type="linenumber">1</context>
4244 </context-group>
4245 </trans-unit>
4246 <trans-unit id="f8f86df8a1ae711944c3ab819bb19bf360dfa7a4">
4247 <source>Are you sure you want to delete all your videos history?</source>
4248 <target>Êtes vous sur de vouloir supprimer toutes les vidéos de votre historique ?</target>
4249 <context-group name="null">
4250 <context context-type="linenumber">1</context>
4251 </context-group>
4252 </trans-unit>
4253 <trans-unit id="195d5ba6c8bd05762d9318d0afd0b094fd776164">
4254 <source>Videos history deleted</source>
4255 <target>Historique de vidéos supprimé</target>
4256 <context-group name="null">
4257 <context context-type="linenumber">1</context>
4258 </context-group>
4259 </trans-unit>
3900 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e"> 4260 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e">
3901 <source>Ownership accepted</source> 4261 <source>Ownership accepted</source>
3902 <target>Changement de propriété accepté</target> 4262 <target>Changement de propriété accepté</target>
@@ -3946,6 +4306,76 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
3946 <context context-type="linenumber">1</context> 4306 <context context-type="linenumber">1</context>
3947 </context-group> 4307 </context-group>
3948 </trans-unit> 4308 </trans-unit>
4309 <trans-unit id="7c193bf704577e514b63497c4f366511afdb6585">
4310 <source>New video from your subscriptions</source>
4311 <target>Nouvelle vidéo depuis vos souscriptions</target>
4312 <context-group name="null">
4313 <context context-type="linenumber">1</context>
4314 </context-group>
4315 </trans-unit>
4316 <trans-unit id="ba897defa2e6c34d5ee3d10edf8d797a35e7e3e5">
4317 <source>New comment on your video</source>
4318 <target>Nouveau commentaire sur votre vidéo</target>
4319 <context-group name="null">
4320 <context context-type="linenumber">1</context>
4321 </context-group>
4322 </trans-unit>
4323 <trans-unit id="0a9650640ddd1dfadfe456891d6d4f6093ad428e">
4324 <source>New video abuse on local video</source>
4325 <target>Nouveau signalement sur une vidéo locale</target>
4326 <context-group name="null">
4327 <context context-type="linenumber">1</context>
4328 </context-group>
4329 </trans-unit>
4330 <trans-unit id="abac8b7629cfcd85bff25770f83ea229f646f996">
4331 <source>One of your video is blacklisted/unblacklisted</source>
4332 <target>Une de vos vidéos a été bloquée/débloquée</target>
4333 <context-group name="null">
4334 <context context-type="linenumber">1</context>
4335 </context-group>
4336 </trans-unit>
4337 <trans-unit id="f3eff4df9e4aa9dab411e6eb83833a33016a88bc">
4338 <source>Video published (after transcoding/scheduled update)</source>
4339 <target>Vidéo publiée (après transcodage / mise à jour programmée)</target>
4340 <context-group name="null">
4341 <context context-type="linenumber">1</context>
4342 </context-group>
4343 </trans-unit>
4344 <trans-unit id="ec7ddc265da1df78011ae7677d62a2ae10aef7a4">
4345 <source>Video import finished</source>
4346 <target>Import de vidéo terminé</target>
4347 <context-group name="null">
4348 <context context-type="linenumber">1</context>
4349 </context-group>
4350 </trans-unit>
4351 <trans-unit id="c327bbac87cca61f5c52f5825d564878e98b9034">
4352 <source>A new user registered on your instance</source>
4353 <target>Nouveau compte créé sur votre instance</target>
4354 <context-group name="null">
4355 <context context-type="linenumber">1</context>
4356 </context-group>
4357 </trans-unit>
4358 <trans-unit id="f407b90e99a04e2e0d1872c02f01eadbf53e08e2">
4359 <source>You or your channel(s) has a new follower</source>
4360 <target>Vous (ou votre chaîne) avez un nouveau suiveur</target>
4361 <context-group name="null">
4362 <context context-type="linenumber">1</context>
4363 </context-group>
4364 </trans-unit>
4365 <trans-unit id="14c3050a9da4c1bc49d555c45d5660804d08e83b">
4366 <source>Someone mentioned you in video comments</source>
4367 <target>Quelqu'un vous a mentionné dans les commentaires d'une vidéo</target>
4368 <context-group name="null">
4369 <context context-type="linenumber">1</context>
4370 </context-group>
4371 </trans-unit>
4372 <trans-unit id="a0f04081717f5f00c0a2c723903c3a2d4c296401">
4373 <source>Preferences saved</source>
4374 <target>Préférences sauvegardées</target>
4375 <context-group name="null">
4376 <context context-type="linenumber">1</context>
4377 </context-group>
4378 </trans-unit>
3949 <trans-unit id="db4ff52375f6a25ad0472e92754c8c265ae47c6b"> 4379 <trans-unit id="db4ff52375f6a25ad0472e92754c8c265ae47c6b">
3950 <source>Profile updated.</source> 4380 <source>Profile updated.</source>
3951 <target>Profil mis à jour.</target> 4381 <target>Profil mis à jour.</target>
@@ -3995,23 +4425,16 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
3995 <context context-type="linenumber">1</context> 4425 <context context-type="linenumber">1</context>
3996 </context-group> 4426 </context-group>
3997 </trans-unit> 4427 </trans-unit>
3998 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 4428 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
3999 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 4429 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
4000 <target>Voulez-vous vraiment supprimer <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> ? Ceci supprimera aussi toutes les vidéos téléversées dans cette chaîne.</target> 4430 <target>Chaîne vidéo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> supprimée.</target>
4001 <context-group name="null">
4002 <context context-type="linenumber">1</context>
4003 </context-group>
4004 </trans-unit>
4005 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
4006 <source>Please type the name of the video channel to confirm</source>
4007 <target>Merci de confirmer le nom de la chaîne</target>
4008 <context-group name="null"> 4431 <context-group name="null">
4009 <context context-type="linenumber">1</context> 4432 <context context-type="linenumber">1</context>
4010 </context-group> 4433 </context-group>
4011 </trans-unit> 4434 </trans-unit>
4012 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 4435 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
4013 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 4436 <source>My videos</source>
4014 <target>Chaîne vidéo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> supprimée.</target> 4437 <target>Mes vidéos</target>
4015 <context-group name="null"> 4438 <context-group name="null">
4016 <context context-type="linenumber">1</context> 4439 <context context-type="linenumber">1</context>
4017 </context-group> 4440 </context-group>
@@ -4086,16 +4509,58 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
4086 <context context-type="linenumber">1</context> 4509 <context context-type="linenumber">1</context>
4087 </context-group> 4510 </context-group>
4088 </trans-unit> 4511 </trans-unit>
4089 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 4512 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
4090 <source>Channels</source> 4513 <source>My library</source>
4091 <target>Ch®nes</target> 4514 <target>Ma bibliothèque</target>
4092 <context-group name="null"> 4515 <context-group name="null">
4093 <context context-type="linenumber">1</context> 4516 <context context-type="linenumber">1</context>
4094 </context-group> 4517 </context-group>
4095 </trans-unit> 4518 </trans-unit>
4096 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d"> 4519 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
4097 <source>Video imports</source> 4520 <source>My channels</source>
4098 <target>Importations de vidéos</target> 4521 <target>Mes chaînes</target>
4522 <context-group name="null">
4523 <context context-type="linenumber">1</context>
4524 </context-group>
4525 </trans-unit>
4526 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
4527 <source>My subscriptions</source>
4528 <target>Mes abonnements</target>
4529 <context-group name="null">
4530 <context context-type="linenumber">1</context>
4531 </context-group>
4532 </trans-unit>
4533 <trans-unit id="4f953496ca94b4f83af049ff715172df2729fb79">
4534 <source>My history</source>
4535 <target>Mon historique</target>
4536 <context-group name="null">
4537 <context context-type="linenumber">1</context>
4538 </context-group>
4539 </trans-unit>
4540 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
4541 <source>Misc</source>
4542 <target>Divers</target>
4543 <context-group name="null">
4544 <context context-type="linenumber">1</context>
4545 </context-group>
4546 </trans-unit>
4547 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
4548 <source>Ownership changes</source>
4549 <target>Changements de propriétaires</target>
4550 <context-group name="null">
4551 <context context-type="linenumber">1</context>
4552 </context-group>
4553 </trans-unit>
4554 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
4555 <source>My settings</source>
4556 <target>Mes paramètres</target>
4557 <context-group name="null">
4558 <context context-type="linenumber">1</context>
4559 </context-group>
4560 </trans-unit>
4561 <trans-unit id="0e2434e7d84145c4e8a930ccc4c26c3cb2887e0d">
4562 <source>My notifications</source>
4563 <target>Mes notifications</target>
4099 <context-group name="null"> 4564 <context-group name="null">
4100 <context context-type="linenumber">1</context> 4565 <context context-type="linenumber">1</context>
4101 </context-group> 4566 </context-group>
@@ -4221,6 +4686,13 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
4221 <context context-type="linenumber">1</context> 4686 <context context-type="linenumber">1</context>
4222 </context-group> 4687 </context-group>
4223 </trans-unit> 4688 </trans-unit>
4689 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
4690 <source>Error</source>
4691 <target>Erreur</target>
4692 <context-group name="null">
4693 <context context-type="linenumber">1</context>
4694 </context-group>
4695 </trans-unit>
4224 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 4696 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
4225 <source>You need to reconnect.</source> 4697 <source>You need to reconnect.</source>
4226 <target>Vous devez vous reconnecter.</target> 4698 <target>Vous devez vous reconnecter.</target>
@@ -4242,6 +4714,20 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
4242 <context context-type="linenumber">1</context> 4714 <context context-type="linenumber">1</context>
4243 </context-group> 4715 </context-group>
4244 </trans-unit> 4716 </trans-unit>
4717 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4718 <source>Info</source>
4719 <target>Info</target>
4720 <context-group name="null">
4721 <context context-type="linenumber">1</context>
4722 </context-group>
4723 </trans-unit>
4724 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
4725 <source>Success</source>
4726 <target>Réussite</target>
4727 <context-group name="null">
4728 <context context-type="linenumber">1</context>
4729 </context-group>
4730 </trans-unit>
4245 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 4731 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
4246 <source>Incorrect username or password.</source> 4732 <source>Incorrect username or password.</source>
4247 <target>Nom d'utilisateur ou mot de passe incorrects.</target> 4733 <target>Nom d'utilisateur ou mot de passe incorrects.</target>
@@ -4459,6 +4945,62 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
4459 <context context-type="linenumber">1</context> 4945 <context context-type="linenumber">1</context>
4460 </context-group> 4946 </context-group>
4461 </trans-unit> 4947 </trans-unit>
4948 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4949 <source>Email is required.</source>
4950 <target>Le courriel est requis.</target>
4951 <context-group name="null">
4952 <context context-type="linenumber">1</context>
4953 </context-group>
4954 </trans-unit>
4955 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4956 <source>Email must be valid.</source>
4957 <target>Le courriel doit être valide.</target>
4958 <context-group name="null">
4959 <context context-type="linenumber">1</context>
4960 </context-group>
4961 </trans-unit>
4962 <trans-unit id="ac451f128840b34804ea69c820dc3566f476fb33">
4963 <source>Your name is required.</source>
4964 <target>Votre nom doit être rempli.</target>
4965 <context-group name="null">
4966 <context context-type="linenumber">1</context>
4967 </context-group>
4968 </trans-unit>
4969 <trans-unit id="1fc4633008a2431fdec891d58efcc8b865d7de1a">
4970 <source>Your name must be at least 1 character long.</source>
4971 <target>Votre nom doit contenir au moins un caractère.</target>
4972 <context-group name="null">
4973 <context context-type="linenumber">1</context>
4974 </context-group>
4975 </trans-unit>
4976 <trans-unit id="c7b44b92c0ce3ccd2f804d001e13da399524e11b">
4977 <source>Your name cannot be more than 120 characters long.</source>
4978 <target>Votre nom ne peut pas contenir plus de 120 caractères.</target>
4979 <context-group name="null">
4980 <context context-type="linenumber">1</context>
4981 </context-group>
4982 </trans-unit>
4983 <trans-unit id="40b35cf927f9f9a59404a6c914ec4632690b69b2">
4984 <source>A message is required.</source>
4985 <target>Votre message doit être rempli.</target>
4986 <context-group name="null">
4987 <context context-type="linenumber">1</context>
4988 </context-group>
4989 </trans-unit>
4990 <trans-unit id="d8d4a23f467ee3e93ca0edb1198c233ed633cf64">
4991 <source>The message must be at least 3 characters long.</source>
4992 <target>Votre message doit contenir au moins 3 caractères.</target>
4993 <context-group name="null">
4994 <context context-type="linenumber">1</context>
4995 </context-group>
4996 </trans-unit>
4997 <trans-unit id="07422f6141cfcabaf3c2ce77e3e063222849ef60">
4998 <source>The message cannot be more than 5000 characters long.</source>
4999 <target>Le message ne peut pas contenir plus de 5000 caractères.</target>
5000 <context-group name="null">
5001 <context context-type="linenumber">1</context>
5002 </context-group>
5003 </trans-unit>
4462 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 5004 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
4463 <source>Username is required.</source> 5005 <source>Username is required.</source>
4464 <target>Le nom d'utilisateur est requis.</target> 5006 <target>Le nom d'utilisateur est requis.</target>
@@ -4480,37 +5022,23 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
4480 <context context-type="linenumber">1</context> 5022 <context context-type="linenumber">1</context>
4481 </context-group> 5023 </context-group>
4482 </trans-unit> 5024 </trans-unit>
4483 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea"> 5025 <trans-unit id="6330d25a3bc6f55dfd5177da6e681d1d3b1a2b1a">
4484 <source>Username must be at least 3 characters long.</source> 5026 <source>Username must be at least 1 character long.</source>
4485 <target>Le nom d'utilisateur doit être composé d'au moins 3 caractères.</target> 5027 <target>Votre nom d'utilisateur doit contenir au moins un caractère.</target>
4486 <context-group name="null">
4487 <context context-type="linenumber">1</context>
4488 </context-group>
4489 </trans-unit>
4490 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
4491 <source>Username cannot be more than 20 characters long.</source>
4492 <target>Le nom d'utilisateur ne peut pas faire plus de 20 caractères.</target>
4493 <context-group name="null"> 5028 <context-group name="null">
4494 <context context-type="linenumber">1</context> 5029 <context context-type="linenumber">1</context>
4495 </context-group> 5030 </context-group>
4496 </trans-unit> 5031 </trans-unit>
4497 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9"> 5032 <trans-unit id="aaaf3d00c35f809eebc7fd68a3f7b8b0230b197a">
4498 <source>Username should be only lowercase alphanumeric characters.</source> 5033 <source>Username cannot be more than 50 characters long.</source>
4499 <target>Le nom d'utilisateur ne doit être composé que de caractères alphanumériques en minuscule.</target> 5034 <target>Votre nom d'utilisateur ne peut pas contenir plus de 50 caractères.</target>
4500 <context-group name="null"> 5035 <context-group name="null">
4501 <context context-type="linenumber">1</context> 5036 <context context-type="linenumber">1</context>
4502 </context-group> 5037 </context-group>
4503 </trans-unit> 5038 </trans-unit>
4504 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0"> 5039 <trans-unit id="6f3e95be2538a22da07beaefc39bb2195683990c">
4505 <source>Email is required.</source> 5040 <source>Username should be lowercase alphanumeric; dots and underscores are allowed.</source>
4506 <target>Le courriel est requis.</target> 5041 <target>Le nom d'utilisateur peut contenir des minuscules, des chiffres, des points et des tirets bas.</target>
4507 <context-group name="null">
4508 <context context-type="linenumber">1</context>
4509 </context-group>
4510 </trans-unit>
4511 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4512 <source>Email must be valid.</source>
4513 <target>Le courriel doit être valide.</target>
4514 <context-group name="null"> 5042 <context-group name="null">
4515 <context context-type="linenumber">1</context> 5043 <context context-type="linenumber">1</context>
4516 </context-group> 5044 </context-group>
@@ -4578,16 +5106,16 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
4578 <context context-type="linenumber">1</context> 5106 <context context-type="linenumber">1</context>
4579 </context-group> 5107 </context-group>
4580 </trans-unit> 5108 </trans-unit>
4581 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674"> 5109 <trans-unit id="085b2d6f79819a72a2b56cada4ef5085ba51d90c">
4582 <source>Display name must be at least 3 characters long.</source> 5110 <source>Display name must be at least 1 character long.</source>
4583 <target>Le nom d'affichage doit être composé d'au moins 3 caractères.</target> 5111 <target>Votre nom affiché doit contenir au moins un caractère.</target>
4584 <context-group name="null"> 5112 <context-group name="null">
4585 <context context-type="linenumber">1</context> 5113 <context context-type="linenumber">1</context>
4586 </context-group> 5114 </context-group>
4587 </trans-unit> 5115 </trans-unit>
4588 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9"> 5116 <trans-unit id="5a920575b8e1067f5b11c66a4a36d3ced87756f1">
4589 <source>Display name cannot be more than 120 characters long.</source> 5117 <source>Display name cannot be more than 50 characters long.</source>
4590 <target>Le nom d'affichage ne peut pas faire plus de 120 caractères.</target> 5118 <target>Votre nom affiché ne peut pas contenir plus de 50 caractères.</target>
4591 <context-group name="null"> 5119 <context-group name="null">
4592 <context context-type="linenumber">1</context> 5120 <context context-type="linenumber">1</context>
4593 </context-group> 5121 </context-group>
@@ -4641,13 +5169,6 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
4641 <context context-type="linenumber">1</context> 5169 <context context-type="linenumber">1</context>
4642 </context-group> 5170 </context-group>
4643 </trans-unit> 5171 </trans-unit>
4644 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
4645 <source>Report reason cannot be more than 300 characters long.</source>
4646 <target>La raison du signalement ne peut pas dépasser 300 caractères.</target>
4647 <context-group name="null">
4648 <context context-type="linenumber">1</context>
4649 </context-group>
4650 </trans-unit>
4651 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118"> 5172 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
4652 <source>Moderation comment is required.</source> 5173 <source>Moderation comment is required.</source>
4653 <target>Un commentaire de modération est requis.</target> 5174 <target>Un commentaire de modération est requis.</target>
@@ -4662,13 +5183,6 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
4662 <context context-type="linenumber">1</context> 5183 <context context-type="linenumber">1</context>
4663 </context-group> 5184 </context-group>
4664 </trans-unit> 5185 </trans-unit>
4665 <trans-unit id="89d0b662dde0871cf17244e79b2cb62cd517e44f">
4666 <source>Moderation comment cannot be more than 300 characters long.</source>
4667 <target>Le commentaire de modération doit faire au plus 300 caractères.</target>
4668 <context-group name="null">
4669 <context context-type="linenumber">1</context>
4670 </context-group>
4671 </trans-unit>
4672 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6"> 5186 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
4673 <source>The channel is required.</source> 5187 <source>The channel is required.</source>
4674 <target>La chaîne est requise.</target> 5188 <target>La chaîne est requise.</target>
@@ -4725,23 +5239,23 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
4725 <context context-type="linenumber">1</context> 5239 <context context-type="linenumber">1</context>
4726 </context-group> 5240 </context-group>
4727 </trans-unit> 5241 </trans-unit>
4728 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069"> 5242 <trans-unit id="b8b59b6284a14fc71268cf722ed98c62c5af4a76">
4729 <source>Name must be at least 3 characters long.</source> 5243 <source>Name must be at least 1 character long.</source>
4730 <target>Le nom doit faire au moins 3 caractères.</target> 5244 <target>Le nom doit contenir au moins un caractère.</target>
4731 <context-group name="null"> 5245 <context-group name="null">
4732 <context context-type="linenumber">1</context> 5246 <context context-type="linenumber">1</context>
4733 </context-group> 5247 </context-group>
4734 </trans-unit> 5248 </trans-unit>
4735 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482"> 5249 <trans-unit id="e14cd37d29f13eac7384c339e4f1df58d96e4e3d">
4736 <source>Name cannot be more than 20 characters long.</source> 5250 <source>Name cannot be more than 50 characters long.</source>
4737 <target>Le nom doit faire au plus 20 caractères.</target> 5251 <target>Le nom ne peut pas contenir plus de 50 caractères.</target>
4738 <context-group name="null"> 5252 <context-group name="null">
4739 <context context-type="linenumber">1</context> 5253 <context context-type="linenumber">1</context>
4740 </context-group> 5254 </context-group>
4741 </trans-unit> 5255 </trans-unit>
4742 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9"> 5256 <trans-unit id="135185da003b14cbb69521f570fa617a00bbbe18">
4743 <source>Name should be only lowercase alphanumeric characters.</source> 5257 <source>Name should be lowercase alphanumeric; dots and underscores are allowed.</source>
4744 <target>Le nom doit contenir seulement des caractères alphanumériques minuscules.</target> 5258 <target>Le nom peut contenir des minuscules, des chiffres, des points et des tirets bas.</target>
4745 <context-group name="null"> 5259 <context-group name="null">
4746 <context context-type="linenumber">1</context> 5260 <context context-type="linenumber">1</context>
4747 </context-group> 5261 </context-group>
@@ -5425,6 +5939,13 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
5425 <context context-type="linenumber">1</context> 5939 <context context-type="linenumber">1</context>
5426 </context-group> 5940 </context-group>
5427 </trans-unit> 5941 </trans-unit>
5942 <trans-unit id="534202c90c6dcadd2989fc72c5030d5483e26096">
5943 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> email set as verified</source>
5944 <target>L'adresse mail de l'utilisateur <x id="INTERPOLATION" equiv-text="{{username}}"/> a été vérifiée</target>
5945 <context-group name="null">
5946 <context context-type="linenumber">1</context>
5947 </context-group>
5948 </trans-unit>
5428 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249"> 5949 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249">
5429 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source> 5950 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source>
5430 <target>Comptes <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muets.</target> 5951 <target>Comptes <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muets.</target>
@@ -5551,13 +6072,6 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
5551 <context context-type="linenumber">1</context> 6072 <context context-type="linenumber">1</context>
5552 </context-group> 6073 </context-group>
5553 </trans-unit> 6074 </trans-unit>
5554 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5555 <source>Subscribed</source>
5556 <target>Abonné</target>
5557 <context-group name="null">
5558 <context context-type="linenumber">1</context>
5559 </context-group>
5560 </trans-unit>
5561 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded"> 6075 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
5562 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source> 6076 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
5563 <target>Abonné à <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target> 6077 <target>Abonné à <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
@@ -5565,9 +6079,9 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
5565 <context context-type="linenumber">1</context> 6079 <context context-type="linenumber">1</context>
5566 </context-group> 6080 </context-group>
5567 </trans-unit> 6081 </trans-unit>
5568 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471"> 6082 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5569 <source>Unsubscribed</source> 6083 <source>Subscribed</source>
5570 <target>Désabonné</target> 6084 <target>Abonné</target>
5571 <context-group name="null"> 6085 <context-group name="null">
5572 <context context-type="linenumber">1</context> 6086 <context context-type="linenumber">1</context>
5573 </context-group> 6087 </context-group>
@@ -5579,6 +6093,13 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
5579 <context context-type="linenumber">1</context> 6093 <context context-type="linenumber">1</context>
5580 </context-group> 6094 </context-group>
5581 </trans-unit> 6095 </trans-unit>
6096 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
6097 <source>Unsubscribed</source>
6098 <target>Désabonné</target>
6099 <context-group name="null">
6100 <context context-type="linenumber">1</context>
6101 </context-group>
6102 </trans-unit>
5582 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf"> 6103 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf">
5583 <source>Moderator</source> 6104 <source>Moderator</source>
5584 <target>Modérateur</target> 6105 <target>Modérateur</target>
@@ -5607,6 +6128,20 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
5607 <context context-type="linenumber">1</context> 6128 <context context-type="linenumber">1</context>
5608 </context-group> 6129 </context-group>
5609 </trans-unit> 6130 </trans-unit>
6131 <trans-unit id="21565881ad1dff3c98738b9535b3515cec140609">
6132 <source>Welcome! Now please check your emails to verify your account and complete signup.</source>
6133 <target>Bienvenue ! Veuillez maintenant consulter vos mails afin de vérifier votre compte et compéter l'inscription. </target>
6134 <context-group name="null">
6135 <context context-type="linenumber">1</context>
6136 </context-group>
6137 </trans-unit>
6138 <trans-unit id="14200e26888a07633c0f177020dce8f3ec7311a6">
6139 <source>You are now logged in as <x id="INTERPOLATION" equiv-text="{{username}}"/>!</source>
6140 <target>Vous êtes maintenant connecté en tant que <x id="INTERPOLATION" equiv-text="{{username}}"/> !</target>
6141 <context-group name="null">
6142 <context context-type="linenumber">1</context>
6143 </context-group>
6144 </trans-unit>
5610 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb"> 6145 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb">
5611 <source>Video to import updated.</source> 6146 <source>Video to import updated.</source>
5612 <target>Les vidéos à importer ont été mises à jour</target> 6147 <target>Les vidéos à importer ont été mises à jour</target>
@@ -5635,13 +6170,6 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
5635 <context context-type="linenumber">1</context> 6170 <context context-type="linenumber">1</context>
5636 </context-group> 6171 </context-group>
5637 </trans-unit> 6172 </trans-unit>
5638 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
5639 <source>Info</source>
5640 <target>Info</target>
5641 <context-group name="null">
5642 <context context-type="linenumber">1</context>
5643 </context-group>
5644 </trans-unit>
5645 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 6173 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
5646 <source>Upload cancelled</source> 6174 <source>Upload cancelled</source>
5647 <target>Mise en ligne annulée</target> 6175 <target>Mise en ligne annulée</target>
@@ -5649,13 +6177,6 @@ Assurez-vous d'avoir les droits de diffusion de ce contenu afin d'éviter toute
5649 <context context-type="linenumber">1</context> 6177 <context context-type="linenumber">1</context>
5650 </context-group> 6178 </context-group>
5651 </trans-unit> 6179 </trans-unit>
5652 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa">
5653 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
5654 <target>Désolé, mais PeerTube ne gère pas les vidéos d'une taille &gt; 8 Go</target>
5655 <context-group name="null">
5656 <context context-type="linenumber">1</context>
5657 </context-group>
5658 </trans-unit>
5659 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee"> 6180 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
5660 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source> 6181 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
5661 <target>Votre quota est dépassé avec cette vidéo (taille de la vidéo : <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target> 6182 <target>Votre quota est dépassé avec cette vidéo (taille de la vidéo : <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
diff --git a/client/src/locale/target/angular_gl_ES.xml b/client/src/locale/target/angular_gl_ES.xml
index e2695304b..ab07180b2 100644
--- a/client/src/locale/target/angular_gl_ES.xml
+++ b/client/src/locale/target/angular_gl_ES.xml
@@ -103,7 +103,7 @@
103 <source>Password</source> 103 <source>Password</source>
104 <target>Contrasinal</target> 104 <target>Contrasinal</target>
105 <context-group name="null"> 105 <context-group name="null">
106 <context context-type="linenumber">12</context> 106 <context context-type="linenumber">13</context>
107 </context-group> 107 </context-group>
108 </trans-unit> 108 </trans-unit>
109 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 109 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -117,7 +117,7 @@
117 <source>Login</source> 117 <source>Login</source>
118 <target>Conectar</target> 118 <target>Conectar</target>
119 <context-group name="null"> 119 <context-group name="null">
120 <context context-type="linenumber">38</context> 120 <context context-type="linenumber">36</context>
121 </context-group> 121 </context-group>
122 </trans-unit> 122 </trans-unit>
123 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 123 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -145,7 +145,7 @@
145 <source>Send me an email to reset my password</source> 145 <source>Send me an email to reset my password</source>
146 <target>Envíenme un correo para restablecer o contrasinal</target> 146 <target>Envíenme un correo para restablecer o contrasinal</target>
147 <context-group name="null"> 147 <context-group name="null">
148 <context context-type="linenumber">75</context> 148 <context context-type="linenumber">80</context>
149 </context-group> 149 </context-group>
150 </trans-unit> 150 </trans-unit>
151 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 151 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -202,7 +202,7 @@
202 <source>Signup</source> 202 <source>Signup</source>
203 <target>Abrir conta</target> 203 <target>Abrir conta</target>
204 <context-group name="null"> 204 <context-group name="null">
205 <context context-type="linenumber">88</context> 205 <context context-type="linenumber">78</context>
206 </context-group> 206 </context-group>
207 </trans-unit> 207 </trans-unit>
208 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a"> 208 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a">
@@ -238,14 +238,14 @@
238 <source>Change the language</source> 238 <source>Change the language</source>
239 <target>Cambiar o idioma</target> 239 <target>Cambiar o idioma</target>
240 <context-group name="null"> 240 <context-group name="null">
241 <context context-type="linenumber">88</context> 241 <context context-type="linenumber">86</context>
242 </context-group> 242 </context-group>
243 </trans-unit> 243 </trans-unit>
244 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 244 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
245 <source>Create an account</source> 245 <source>Create an account</source>
246 <target>Crear unha conta</target> 246 <target>Crear unha conta</target>
247 <context-group name="null"> 247 <context-group name="null">
248 <context context-type="linenumber">39</context> 248 <context context-type="linenumber">37</context>
249 </context-group> 249 </context-group>
250 </trans-unit> 250 </trans-unit>
251 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 251 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -259,35 +259,35 @@
259 <source>Trending</source> 259 <source>Trending</source>
260 <target>En voga</target> 260 <target>En voga</target>
261 <context-group name="null"> 261 <context-group name="null">
262 <context context-type="linenumber">57</context> 262 <context context-type="linenumber">55</context>
263 </context-group> 263 </context-group>
264 </trans-unit> 264 </trans-unit>
265 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 265 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
266 <source>Recently added</source> 266 <source>Recently added</source>
267 <target>Últimos engadidos</target> 267 <target>Últimos engadidos</target>
268 <context-group name="null"> 268 <context-group name="null">
269 <context context-type="linenumber">62</context> 269 <context context-type="linenumber">60</context>
270 </context-group> 270 </context-group>
271 </trans-unit> 271 </trans-unit>
272 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 272 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
273 <source>Local</source> 273 <source>Local</source>
274 <target>Local</target> 274 <target>Local</target>
275 <context-group name="null"> 275 <context-group name="null">
276 <context context-type="linenumber">67</context> 276 <context context-type="linenumber">65</context>
277 </context-group> 277 </context-group>
278 </trans-unit> 278 </trans-unit>
279 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 279 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
280 <source>More</source> 280 <source>More</source>
281 <target>Máis</target> 281 <target>Máis</target>
282 <context-group name="null"> 282 <context-group name="null">
283 <context context-type="linenumber">72</context> 283 <context context-type="linenumber">70</context>
284 </context-group> 284 </context-group>
285 </trans-unit> 285 </trans-unit>
286 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 286 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
287 <source>Administration</source> 287 <source>Administration</source>
288 <target>Administración</target> 288 <target>Administración</target>
289 <context-group name="null"> 289 <context-group name="null">
290 <context context-type="linenumber">76</context> 290 <context context-type="linenumber">74</context>
291 </context-group> 291 </context-group>
292 </trans-unit> 292 </trans-unit>
293 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 293 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -399,7 +399,7 @@
399 <source>No results.</source> 399 <source>No results.</source>
400 <target>Sin resultados.</target> 400 <target>Sin resultados.</target>
401 <context-group name="null"> 401 <context-group name="null">
402 <context context-type="linenumber">17</context> 402 <context context-type="linenumber">20</context>
403 </context-group> 403 </context-group>
404 </trans-unit> 404 </trans-unit>
405 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b"> 405 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b">
@@ -416,17 +416,6 @@
416 <context context-type="linenumber">7</context> 416 <context context-type="linenumber">7</context>
417 </context-group> 417 </context-group>
418 </trans-unit> 418 </trans-unit>
419 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2">
420 <source>
421 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance
422</source>
423 <target>
424 Acerca da instancia <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/>
425</target>
426 <context-group name="null">
427 <context context-type="linenumber">1</context>
428 </context-group>
429 </trans-unit>
430 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 419 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
431 <source>Description</source> 420 <source>Description</source>
432 <target>Descrición</target> 421 <target>Descrición</target>
@@ -438,47 +427,14 @@
438 <source>Terms</source> 427 <source>Terms</source>
439 <target>Termos</target> 428 <target>Termos</target>
440 <context-group name="null"> 429 <context-group name="null">
441 <context context-type="linenumber">44</context> 430 <context context-type="linenumber">39</context>
442 </context-group> 431 </context-group>
443 </trans-unit> 432 </trans-unit>
444 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 433 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
445 <source>User registration is allowed and</source> 434 <source>User registration is allowed and</source>
446 <target>O rexistro está aberto e</target> 435 <target>O rexistro está aberto e</target>
447 <context-group name="null"> 436 <context-group name="null">
448 <context context-type="linenumber">25</context> 437 <context context-type="linenumber">29</context>
449 </context-group>
450 </trans-unit>
451 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
452 <source>
453 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
454 </source>
455 <target>
456 esta instancia proporciona unha cota inicial de <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> para os vídeos das súas usuarias.
457 </target>
458 <context-group name="null">
459 <context context-type="linenumber">27</context>
460 </context-group>
461 </trans-unit>
462 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
463 <source>
464 this instance provides unlimited space for the videos of its users.
465 </source>
466 <target>
467 esta instancia non limita o espazo para os videos das súas usuarias.
468 </target>
469 <context-group name="null">
470 <context context-type="linenumber">31</context>
471 </context-group>
472 </trans-unit>
473 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
474 <source>
475 User registration is currently not allowed.
476 </source>
477 <target>
478 En este momento non está aberto o rexistro de novas usuarias.
479 </target>
480 <context-group name="null">
481 <context context-type="linenumber">36</context>
482 </context-group> 438 </context-group>
483 </trans-unit> 439 </trans-unit>
484 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 440 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -744,42 +700,42 @@
744 <source>Short description</source> 700 <source>Short description</source>
745 <target>Descrición curta</target> 701 <target>Descrición curta</target>
746 <context-group name="null"> 702 <context-group name="null">
747 <context context-type="linenumber">22</context> 703 <context context-type="linenumber">21</context>
748 </context-group> 704 </context-group>
749 </trans-unit> 705 </trans-unit>
750 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 706 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
751 <source>Default client route</source> 707 <source>Default client route</source>
752 <target>Ruta ao cliente por omisión</target> 708 <target>Ruta ao cliente por omisión</target>
753 <context-group name="null"> 709 <context-group name="null">
754 <context context-type="linenumber">55</context> 710 <context context-type="linenumber">48</context>
755 </context-group> 711 </context-group>
756 </trans-unit> 712 </trans-unit>
757 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 713 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
758 <source>Videos Trending</source> 714 <source>Videos Trending</source>
759 <target>Vídeos de moda</target> 715 <target>Vídeos de moda</target>
760 <context-group name="null"> 716 <context-group name="null">
761 <context context-type="linenumber">59</context> 717 <context context-type="linenumber">52</context>
762 </context-group> 718 </context-group>
763 </trans-unit> 719 </trans-unit>
764 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 720 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
765 <source>Videos Recently Added</source> 721 <source>Videos Recently Added</source>
766 <target>Vídeos engadidos recentemente</target> 722 <target>Vídeos engadidos recentemente</target>
767 <context-group name="null"> 723 <context-group name="null">
768 <context context-type="linenumber">60</context> 724 <context context-type="linenumber">53</context>
769 </context-group> 725 </context-group>
770 </trans-unit> 726 </trans-unit>
771 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 727 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
772 <source>Local videos</source> 728 <source>Local videos</source>
773 <target>Vídeos en local</target> 729 <target>Vídeos en local</target>
774 <context-group name="null"> 730 <context-group name="null">
775 <context context-type="linenumber">61</context> 731 <context context-type="linenumber">54</context>
776 </context-group> 732 </context-group>
777 </trans-unit> 733 </trans-unit>
778 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 734 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
779 <source>Policy on videos containing sensitive content</source> 735 <source>Policy on videos containing sensitive content</source>
780 <target>Política para os vídeos con contido sensible</target> 736 <target>Política para os vídeos con contido sensible</target>
781 <context-group name="null"> 737 <context-group name="null">
782 <context context-type="linenumber">70</context> 738 <context context-type="linenumber">61</context>
783 </context-group> 739 </context-group>
784 </trans-unit> 740 </trans-unit>
785 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 741 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -814,16 +770,30 @@
814 <source>Signup enabled</source> 770 <source>Signup enabled</source>
815 <target>Rexistro activado</target> 771 <target>Rexistro activado</target>
816 <context-group name="null"> 772 <context-group name="null">
817 <context context-type="linenumber">93</context> 773 <context context-type="linenumber">84</context>
818 </context-group> 774 </context-group>
819 </trans-unit> 775 </trans-unit>
820 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 776 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
821 <source>Signup limit</source> 777 <source>Signup limit</source>
822 <target>Rexistro limitado</target> 778 <target>Rexistro limitado</target>
823 <context-group name="null"> 779 <context-group name="null">
780 <context context-type="linenumber">96</context>
781 </context-group>
782 </trans-unit>
783 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
784 <source>Users</source>
785 <target>Usuarias</target>
786 <context-group name="null">
824 <context context-type="linenumber">105</context> 787 <context context-type="linenumber">105</context>
825 </context-group> 788 </context-group>
826 </trans-unit> 789 </trans-unit>
790 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
791 <source>User default video quota</source>
792 <target>Cota de vídeo por omisión para a usuaria</target>
793 <context-group name="null">
794 <context context-type="linenumber">109</context>
795 </context-group>
796 </trans-unit>
827 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 797 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
828 <source>Import</source> 798 <source>Import</source>
829 <target>Importar</target> 799 <target>Importar</target>
@@ -835,35 +805,21 @@
835 <source>Video import with a torrent file or a magnet URI enabled</source> 805 <source>Video import with a torrent file or a magnet URI enabled</source>
836 <target>Importación de vídeo con un ficheiro torrent ou URI magnet activada</target> 806 <target>Importación de vídeo con un ficheiro torrent ou URI magnet activada</target>
837 <context-group name="null"> 807 <context-group name="null">
838 <context context-type="linenumber">127</context> 808 <context context-type="linenumber">148</context>
839 </context-group> 809 </context-group>
840 </trans-unit> 810 </trans-unit>
841 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 811 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
842 <source>Administrator</source> 812 <source>Administrator</source>
843 <target>Administración</target> 813 <target>Administración</target>
844 <context-group name="null"> 814 <context-group name="null">
845 <context context-type="linenumber">131</context> 815 <context context-type="linenumber">155</context>
846 </context-group> 816 </context-group>
847 </trans-unit> 817 </trans-unit>
848 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 818 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
849 <source>Admin email</source> 819 <source>Admin email</source>
850 <target>Correo-e da Admin</target> 820 <target>Correo-e da Admin</target>
851 <context-group name="null"> 821 <context-group name="null">
852 <context context-type="linenumber">134</context> 822 <context context-type="linenumber">158</context>
853 </context-group>
854 </trans-unit>
855 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
856 <source>Users</source>
857 <target>Usuarias</target>
858 <context-group name="null">
859 <context context-type="linenumber">144</context>
860 </context-group>
861 </trans-unit>
862 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
863 <source>User default video quota</source>
864 <target>Cota de vídeo por omisión para a usuaria</target>
865 <context-group name="null">
866 <context context-type="linenumber">147</context>
867 </context-group> 823 </context-group>
868 </trans-unit> 824 </trans-unit>
869 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 825 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -884,21 +840,21 @@
884 <source>Your Twitter username</source> 840 <source>Your Twitter username</source>
885 <target>O seu alcume na Twitter</target> 841 <target>O seu alcume na Twitter</target>
886 <context-group name="null"> 842 <context-group name="null">
887 <context context-type="linenumber">181</context> 843 <context context-type="linenumber">184</context>
888 </context-group> 844 </context-group>
889 </trans-unit> 845 </trans-unit>
890 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 846 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
891 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 847 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
892 <target>Indica a conta na Twitter para o sitio web ou plataforma para a cal o contido foi publicado.</target> 848 <target>Indica a conta na Twitter para o sitio web ou plataforma para a cal o contido foi publicado.</target>
893 <context-group name="null"> 849 <context-group name="null">
894 <context context-type="linenumber">184</context> 850 <context context-type="linenumber">187</context>
895 </context-group> 851 </context-group>
896 </trans-unit> 852 </trans-unit>
897 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 853 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
898 <source>Instance whitelisted by Twitter</source> 854 <source>Instance whitelisted by Twitter</source>
899 <target>Instancia na lista blanca por Twitter</target> 855 <target>Instancia na lista blanca por Twitter</target>
900 <context-group name="null"> 856 <context-group name="null">
901 <context context-type="linenumber">198</context> 857 <context context-type="linenumber">199</context>
902 </context-group> 858 </context-group>
903 </trans-unit> 859 </trans-unit>
904 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 860 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -912,98 +868,98 @@
912 <source>Transcoding</source> 868 <source>Transcoding</source>
913 <target>Recodificando</target> 869 <target>Recodificando</target>
914 <context-group name="null"> 870 <context-group name="null">
915 <context context-type="linenumber">210</context> 871 <context context-type="linenumber">215</context>
916 </context-group> 872 </context-group>
917 </trans-unit> 873 </trans-unit>
918 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 874 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
919 <source>Transcoding enabled</source> 875 <source>Transcoding enabled</source>
920 <target>Recodificación activada</target> 876 <target>Recodificación activada</target>
921 <context-group name="null"> 877 <context-group name="null">
922 <context context-type="linenumber">215</context> 878 <context context-type="linenumber">221</context>
923 </context-group> 879 </context-group>
924 </trans-unit> 880 </trans-unit>
925 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 881 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
926 <source>If you disable transcoding, many videos from your users will not work!</source> 882 <source>If you disable transcoding, many videos from your users will not work!</source>
927 <target>Si desactiva a recodificación moitos vídeos das súas usuarias non funcionarán!</target> 883 <target>Si desactiva a recodificación moitos vídeos das súas usuarias non funcionarán!</target>
928 <context-group name="null"> 884 <context-group name="null">
929 <context context-type="linenumber">216</context> 885 <context context-type="linenumber">222</context>
930 </context-group> 886 </context-group>
931 </trans-unit> 887 </trans-unit>
932 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 888 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
933 <source>Transcoding threads</source> 889 <source>Transcoding threads</source>
934 <target>Fíos de recodificación</target> 890 <target>Fíos de recodificación</target>
935 <context-group name="null"> 891 <context-group name="null">
936 <context context-type="linenumber">223</context> 892 <context context-type="linenumber">237</context>
937 </context-group> 893 </context-group>
938 </trans-unit> 894 </trans-unit>
939 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 895 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
940 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 896 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
941 <target>Resolución <x id="INTERPOLATION" equiv-text="{{resolution}}"/> activada</target> 897 <target>Resolución <x id="INTERPOLATION" equiv-text="{{resolution}}"/> activada</target>
942 <context-group name="null"> 898 <context-group name="null">
943 <context context-type="linenumber">239</context> 899 <context context-type="linenumber">252</context>
944 </context-group> 900 </context-group>
945 </trans-unit> 901 </trans-unit>
946 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 902 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
947 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 903 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
948 <target>Algúns ficheiros non se federan (vista previa, comentarios). Recollémolos directamente desde a instancia de orixe e almacenámolos.</target> 904 <target>Algúns ficheiros non se federan (vista previa, comentarios). Recollémolos directamente desde a instancia de orixe e almacenámolos.</target>
949 <context-group name="null"> 905 <context-group name="null">
950 <context context-type="linenumber">249</context> 906 <context context-type="linenumber">265</context>
951 </context-group> 907 </context-group>
952 </trans-unit> 908 </trans-unit>
953 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 909 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
954 <source>Previews cache size</source> 910 <source>Previews cache size</source>
955 <target>Tamaño da caché de vista previa</target> 911 <target>Tamaño da caché de vista previa</target>
956 <context-group name="null"> 912 <context-group name="null">
957 <context context-type="linenumber">254</context> 913 <context context-type="linenumber">271</context>
958 </context-group> 914 </context-group>
959 </trans-unit> 915 </trans-unit>
960 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 916 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
961 <source>Video captions cache size</source> 917 <source>Video captions cache size</source>
962 <target>Tamaño da caché de comentarios no vídeo</target> 918 <target>Tamaño da caché de comentarios no vídeo</target>
963 <context-group name="null"> 919 <context-group name="null">
964 <context context-type="linenumber">265</context> 920 <context context-type="linenumber">280</context>
965 </context-group> 921 </context-group>
966 </trans-unit> 922 </trans-unit>
967 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 923 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
968 <source>Customizations</source> 924 <source>Customizations</source>
969 <target>Personalizacións</target> 925 <target>Personalizacións</target>
970 <context-group name="null"> 926 <context-group name="null">
971 <context context-type="linenumber">275</context> 927 <context context-type="linenumber">289</context>
972 </context-group> 928 </context-group>
973 </trans-unit> 929 </trans-unit>
974 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 930 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
975 <source>JavaScript</source> 931 <source>JavaScript</source>
976 <target>JavaScript</target> 932 <target>JavaScript</target>
977 <context-group name="null"> 933 <context-group name="null">
978 <context context-type="linenumber">278</context> 934 <context context-type="linenumber">294</context>
979 </context-group> 935 </context-group>
980 </trans-unit> 936 </trans-unit>
981 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 937 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
982 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 938 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
983 <target>Escribir código JavaScript directamente.&lt;br /&gt;Exemplo: &lt;pre&gt;console.log('a miña instancia é tremenda');&lt;/pre&gt;</target> 939 <target>Escribir código JavaScript directamente.&lt;br /&gt;Exemplo: &lt;pre&gt;console.log('a miña instancia é tremenda');&lt;/pre&gt;</target>
984 <context-group name="null"> 940 <context-group name="null">
985 <context context-type="linenumber">281</context> 941 <context context-type="linenumber">297</context>
986 </context-group> 942 </context-group>
987 </trans-unit> 943 </trans-unit>
988 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab"> 944 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab">
989 <source>Advanced configuration</source> 945 <source>Advanced configuration</source>
990 <target>Configuración avanzada</target> 946 <target>Configuración avanzada</target>
991 <context-group name="null"> 947 <context-group name="null">
992 <context context-type="linenumber">207</context> 948 <context context-type="linenumber">212</context>
993 </context-group> 949 </context-group>
994 </trans-unit> 950 </trans-unit>
995 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 951 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
996 <source>Update configuration</source> 952 <source>Update configuration</source>
997 <target>Actualizar configuración</target> 953 <target>Actualizar configuración</target>
998 <context-group name="null"> 954 <context-group name="null">
999 <context context-type="linenumber">325</context> 955 <context context-type="linenumber">340</context>
1000 </context-group> 956 </context-group>
1001 </trans-unit> 957 </trans-unit>
1002 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 958 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1003 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 959 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1004 <target>Semella que a configuración non é válida. Por favor busque os erros potenciais nas diferentes pestanas.</target> 960 <target>Semella que a configuración non é válida. Por favor busque os erros potenciais nas diferentes pestanas.</target>
1005 <context-group name="null"> 961 <context-group name="null">
1006 <context context-type="linenumber">326</context> 962 <context context-type="linenumber">341</context>
1007 </context-group> 963 </context-group>
1008 </trans-unit> 964 </trans-unit>
1009 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 965 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
diff --git a/client/src/locale/target/angular_it_IT.xml b/client/src/locale/target/angular_it_IT.xml
index dea48b4a7..c3bcc704c 100644
--- a/client/src/locale/target/angular_it_IT.xml
+++ b/client/src/locale/target/angular_it_IT.xml
@@ -479,7 +479,7 @@
479 <source>Password</source> 479 <source>Password</source>
480 <target>Password</target> 480 <target>Password</target>
481 <context-group name="null"> 481 <context-group name="null">
482 <context context-type="linenumber">12</context> 482 <context context-type="linenumber">13</context>
483 </context-group> 483 </context-group>
484 </trans-unit> 484 </trans-unit>
485 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 485 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -493,7 +493,7 @@
493 <source>Login</source> 493 <source>Login</source>
494 <target>Accedi</target> 494 <target>Accedi</target>
495 <context-group name="null"> 495 <context-group name="null">
496 <context context-type="linenumber">38</context> 496 <context context-type="linenumber">36</context>
497 </context-group> 497 </context-group>
498 </trans-unit> 498 </trans-unit>
499 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 499 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -521,7 +521,7 @@
521 <source>Send me an email to reset my password</source> 521 <source>Send me an email to reset my password</source>
522 <target>Inviami un email per resettare la password</target> 522 <target>Inviami un email per resettare la password</target>
523 <context-group name="null"> 523 <context-group name="null">
524 <context context-type="linenumber">75</context> 524 <context context-type="linenumber">80</context>
525 </context-group> 525 </context-group>
526 </trans-unit> 526 </trans-unit>
527 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 527 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -585,7 +585,7 @@
585 <source>Signup</source> 585 <source>Signup</source>
586 <target>Registrati</target> 586 <target>Registrati</target>
587 <context-group name="null"> 587 <context-group name="null">
588 <context context-type="linenumber">88</context> 588 <context context-type="linenumber">78</context>
589 </context-group> 589 </context-group>
590 </trans-unit> 590 </trans-unit>
591 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 591 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -613,6 +613,19 @@
613 <context context-type="linenumber">6</context> 613 <context context-type="linenumber">6</context>
614 </context-group> 614 </context-group>
615 </trans-unit> 615 </trans-unit>
616 <trans-unit id="7c603b9ed878097782e2b8908f662e2344b46061">
617 <source>
618 Filters
619 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/><x id="INTERPOLATION" equiv-text="{{ numberOfFilters() }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
620 </source>
621 <target>
622 Filtri
623 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/><x id="INTERPOLATION" equiv-text="{{ numberOfFilters() }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
624 </target>
625 <context-group name="null">
626 <context context-type="linenumber">16</context>
627 </context-group>
628 </trans-unit>
616 <trans-unit id="e2dbf0426cbb0b573faf49dffeb7d5bdf16eda5d"> 629 <trans-unit id="e2dbf0426cbb0b573faf49dffeb7d5bdf16eda5d">
617 <source> 630 <source>
618 No results found 631 No results found
@@ -642,7 +655,7 @@
642 <source>Change the language</source> 655 <source>Change the language</source>
643 <target>Cambia lingua</target> 656 <target>Cambia lingua</target>
644 <context-group name="null"> 657 <context-group name="null">
645 <context context-type="linenumber">88</context> 658 <context context-type="linenumber">86</context>
646 </context-group> 659 </context-group>
647 </trans-unit> 660 </trans-unit>
648 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 661 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -653,7 +666,7 @@
653 Il mio profilo pubblico 666 Il mio profilo pubblico
654 </target> 667 </target>
655 <context-group name="null"> 668 <context-group name="null">
656 <context context-type="linenumber">18</context> 669 <context context-type="linenumber">16</context>
657 </context-group> 670 </context-group>
658 </trans-unit> 671 </trans-unit>
659 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 672 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -664,7 +677,7 @@
664 Il mio account 677 Il mio account
665 </target> 678 </target>
666 <context-group name="null"> 679 <context-group name="null">
667 <context context-type="linenumber">22</context> 680 <context context-type="linenumber">20</context>
668 </context-group> 681 </context-group>
669 </trans-unit> 682 </trans-unit>
670 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 683 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -675,7 +688,7 @@
675 I miei video 688 I miei video
676 </target> 689 </target>
677 <context-group name="null"> 690 <context-group name="null">
678 <context context-type="linenumber">26</context> 691 <context context-type="linenumber">24</context>
679 </context-group> 692 </context-group>
680 </trans-unit> 693 </trans-unit>
681 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 694 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -686,14 +699,14 @@
686 Esci 699 Esci
687 </target> 700 </target>
688 <context-group name="null"> 701 <context-group name="null">
689 <context context-type="linenumber">30</context> 702 <context context-type="linenumber">28</context>
690 </context-group> 703 </context-group>
691 </trans-unit> 704 </trans-unit>
692 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 705 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
693 <source>Create an account</source> 706 <source>Create an account</source>
694 <target>Crea un account</target> 707 <target>Crea un account</target>
695 <context-group name="null"> 708 <context-group name="null">
696 <context context-type="linenumber">39</context> 709 <context context-type="linenumber">37</context>
697 </context-group> 710 </context-group>
698 </trans-unit> 711 </trans-unit>
699 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 712 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -707,49 +720,49 @@
707 <source>Subscriptions</source> 720 <source>Subscriptions</source>
708 <target>Iscrizioni</target> 721 <target>Iscrizioni</target>
709 <context-group name="null"> 722 <context-group name="null">
710 <context context-type="linenumber">47</context> 723 <context context-type="linenumber">45</context>
711 </context-group> 724 </context-group>
712 </trans-unit> 725 </trans-unit>
713 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 726 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
714 <source>Overview</source> 727 <source>Overview</source>
715 <target>Panoramica</target> 728 <target>Panoramica</target>
716 <context-group name="null"> 729 <context-group name="null">
717 <context context-type="linenumber">52</context> 730 <context context-type="linenumber">50</context>
718 </context-group> 731 </context-group>
719 </trans-unit> 732 </trans-unit>
720 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 733 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
721 <source>Trending</source> 734 <source>Trending</source>
722 <target>Popolari</target> 735 <target>Popolari</target>
723 <context-group name="null"> 736 <context-group name="null">
724 <context context-type="linenumber">57</context> 737 <context context-type="linenumber">55</context>
725 </context-group> 738 </context-group>
726 </trans-unit> 739 </trans-unit>
727 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 740 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
728 <source>Recently added</source> 741 <source>Recently added</source>
729 <target>Aggiunti di recente</target> 742 <target>Aggiunti di recente</target>
730 <context-group name="null"> 743 <context-group name="null">
731 <context context-type="linenumber">62</context> 744 <context context-type="linenumber">60</context>
732 </context-group> 745 </context-group>
733 </trans-unit> 746 </trans-unit>
734 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 747 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
735 <source>Local</source> 748 <source>Local</source>
736 <target>Locali</target> 749 <target>Locali</target>
737 <context-group name="null"> 750 <context-group name="null">
738 <context context-type="linenumber">67</context> 751 <context context-type="linenumber">65</context>
739 </context-group> 752 </context-group>
740 </trans-unit> 753 </trans-unit>
741 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 754 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
742 <source>More</source> 755 <source>More</source>
743 <target>Altro</target> 756 <target>Altro</target>
744 <context-group name="null"> 757 <context-group name="null">
745 <context context-type="linenumber">72</context> 758 <context context-type="linenumber">70</context>
746 </context-group> 759 </context-group>
747 </trans-unit> 760 </trans-unit>
748 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 761 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
749 <source>Administration</source> 762 <source>Administration</source>
750 <target>Amministrazione</target> 763 <target>Amministrazione</target>
751 <context-group name="null"> 764 <context-group name="null">
752 <context context-type="linenumber">76</context> 765 <context context-type="linenumber">74</context>
753 </context-group> 766 </context-group>
754 </trans-unit> 767 </trans-unit>
755 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 768 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -763,14 +776,14 @@
763 <source>Show keyboard shortcuts</source> 776 <source>Show keyboard shortcuts</source>
764 <target>Mostra scorciatoie della tastiera</target> 777 <target>Mostra scorciatoie della tastiera</target>
765 <context-group name="null"> 778 <context-group name="null">
766 <context context-type="linenumber">91</context> 779 <context context-type="linenumber">89</context>
767 </context-group> 780 </context-group>
768 </trans-unit> 781 </trans-unit>
769 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 782 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
770 <source>Toggle dark interface</source> 783 <source>Toggle dark interface</source>
771 <target>(Dis)attiva l'interfaccia sicura</target> 784 <target>(Dis)attiva l'interfaccia sicura</target>
772 <context-group name="null"> 785 <context-group name="null">
773 <context context-type="linenumber">94</context> 786 <context context-type="linenumber">92</context>
774 </context-group> 787 </context-group>
775 </trans-unit> 788 </trans-unit>
776 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 789 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -875,14 +888,14 @@
875 <source>Display unlisted and private videos</source> 888 <source>Display unlisted and private videos</source>
876 <target>Mostra video privati e non elencati</target> 889 <target>Mostra video privati e non elencati</target>
877 <context-group name="null"> 890 <context-group name="null">
878 <context context-type="linenumber">11</context> 891 <context context-type="linenumber">14</context>
879 </context-group> 892 </context-group>
880 </trans-unit> 893 </trans-unit>
881 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 894 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
882 <source>No results.</source> 895 <source>No results.</source>
883 <target>Nessun risultato.</target> 896 <target>Nessun risultato.</target>
884 <context-group name="null"> 897 <context-group name="null">
885 <context context-type="linenumber">17</context> 898 <context context-type="linenumber">20</context>
886 </context-group> 899 </context-group>
887 </trans-unit> 900 </trans-unit>
888 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 901 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -940,15 +953,22 @@
940 <context context-type="linenumber">7</context> 953 <context context-type="linenumber">7</context>
941 </context-group> 954 </context-group>
942 </trans-unit> 955 </trans-unit>
943 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 956 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
944 <source> 957 <source>
945 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 958 Cancel
946</source> 959 </source>
947 <target> 960 <target>
948 Riguardo all'istanza <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> 961 Annulla
949</target> 962 </target>
950 <context-group name="null"> 963 <context-group name="null">
951 <context context-type="linenumber">1</context> 964 <context context-type="linenumber">26</context>
965 </context-group>
966 </trans-unit>
967 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
968 <source>Submit</source>
969 <target>Invia</target>
970 <context-group name="null">
971 <context context-type="linenumber">31</context>
952 </context-group> 972 </context-group>
953 </trans-unit> 973 </trans-unit>
954 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 974 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -962,47 +982,14 @@
962 <source>Terms</source> 982 <source>Terms</source>
963 <target>Termini</target> 983 <target>Termini</target>
964 <context-group name="null"> 984 <context-group name="null">
965 <context context-type="linenumber">44</context> 985 <context context-type="linenumber">39</context>
966 </context-group> 986 </context-group>
967 </trans-unit> 987 </trans-unit>
968 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 988 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
969 <source>User registration is allowed and</source> 989 <source>User registration is allowed and</source>
970 <target>È permessa la registrazione di nuovi utenti e</target> 990 <target>È permessa la registrazione di nuovi utenti e</target>
971 <context-group name="null"> 991 <context-group name="null">
972 <context context-type="linenumber">25</context> 992 <context context-type="linenumber">29</context>
973 </context-group>
974 </trans-unit>
975 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
976 <source>
977 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
978 </source>
979 <target>
980 questa istanza fornisce una quota base di <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> per i video dei suoi utenti.
981 </target>
982 <context-group name="null">
983 <context context-type="linenumber">27</context>
984 </context-group>
985 </trans-unit>
986 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
987 <source>
988 this instance provides unlimited space for the videos of its users.
989 </source>
990 <target>
991 questa istanza fornisce spazio illimitato per i video dei suoi utenti.
992 </target>
993 <context-group name="null">
994 <context context-type="linenumber">31</context>
995 </context-group>
996 </trans-unit>
997 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
998 <source>
999 User registration is currently not allowed.
1000 </source>
1001 <target>
1002 La registrazione di nuovi utenti al momento non è permessa.
1003 </target>
1004 <context-group name="null">
1005 <context context-type="linenumber">36</context>
1006 </context-group> 993 </context-group>
1007 </trans-unit> 994 </trans-unit>
1008 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 995 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1346,49 +1333,49 @@
1346 <source>Short description</source> 1333 <source>Short description</source>
1347 <target>Breve descrizione</target> 1334 <target>Breve descrizione</target>
1348 <context-group name="null"> 1335 <context-group name="null">
1349 <context context-type="linenumber">22</context> 1336 <context context-type="linenumber">21</context>
1350 </context-group> 1337 </context-group>
1351 </trans-unit> 1338 </trans-unit>
1352 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1339 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1353 <source>Default client route</source> 1340 <source>Default client route</source>
1354 <target>Percorso predefinito del client</target> 1341 <target>Percorso predefinito del client</target>
1355 <context-group name="null"> 1342 <context-group name="null">
1356 <context context-type="linenumber">55</context> 1343 <context context-type="linenumber">48</context>
1357 </context-group> 1344 </context-group>
1358 </trans-unit> 1345 </trans-unit>
1359 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1346 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1360 <source>Videos Overview</source> 1347 <source>Videos Overview</source>
1361 <target>Panoramica dei video</target> 1348 <target>Panoramica dei video</target>
1362 <context-group name="null"> 1349 <context-group name="null">
1363 <context context-type="linenumber">58</context> 1350 <context context-type="linenumber">51</context>
1364 </context-group> 1351 </context-group>
1365 </trans-unit> 1352 </trans-unit>
1366 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1353 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1367 <source>Videos Trending</source> 1354 <source>Videos Trending</source>
1368 <target>Video popolari</target> 1355 <target>Video popolari</target>
1369 <context-group name="null"> 1356 <context-group name="null">
1370 <context context-type="linenumber">59</context> 1357 <context context-type="linenumber">52</context>
1371 </context-group> 1358 </context-group>
1372 </trans-unit> 1359 </trans-unit>
1373 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1360 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1374 <source>Videos Recently Added</source> 1361 <source>Videos Recently Added</source>
1375 <target>Video aggiunti di recente</target> 1362 <target>Video aggiunti di recente</target>
1376 <context-group name="null"> 1363 <context-group name="null">
1377 <context context-type="linenumber">60</context> 1364 <context context-type="linenumber">53</context>
1378 </context-group> 1365 </context-group>
1379 </trans-unit> 1366 </trans-unit>
1380 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1367 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1381 <source>Local videos</source> 1368 <source>Local videos</source>
1382 <target>Video locali</target> 1369 <target>Video locali</target>
1383 <context-group name="null"> 1370 <context-group name="null">
1384 <context context-type="linenumber">61</context> 1371 <context context-type="linenumber">54</context>
1385 </context-group> 1372 </context-group>
1386 </trans-unit> 1373 </trans-unit>
1387 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1374 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1388 <source>Policy on videos containing sensitive content</source> 1375 <source>Policy on videos containing sensitive content</source>
1389 <target>Policy su video che contengono contenuti sensibili</target> 1376 <target>Policy su video che contengono contenuti sensibili</target>
1390 <context-group name="null"> 1377 <context-group name="null">
1391 <context context-type="linenumber">70</context> 1378 <context context-type="linenumber">61</context>
1392 </context-group> 1379 </context-group>
1393 </trans-unit> 1380 </trans-unit>
1394 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1381 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1423,23 +1410,44 @@
1423 <source>Signup enabled</source> 1410 <source>Signup enabled</source>
1424 <target>Registrazione abilitata</target> 1411 <target>Registrazione abilitata</target>
1425 <context-group name="null"> 1412 <context-group name="null">
1426 <context context-type="linenumber">93</context> 1413 <context context-type="linenumber">84</context>
1427 </context-group> 1414 </context-group>
1428 </trans-unit> 1415 </trans-unit>
1429 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1416 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1430 <source>Signup requires email verification</source> 1417 <source>Signup requires email verification</source>
1431 <target>La registrazione richiede una verifica via email</target> 1418 <target>La registrazione richiede una verifica via email</target>
1432 <context-group name="null"> 1419 <context-group name="null">
1433 <context context-type="linenumber">100</context> 1420 <context context-type="linenumber">91</context>
1434 </context-group> 1421 </context-group>
1435 </trans-unit> 1422 </trans-unit>
1436 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1423 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1437 <source>Signup limit</source> 1424 <source>Signup limit</source>
1438 <target>Limite registrazioni</target> 1425 <target>Limite registrazioni</target>
1439 <context-group name="null"> 1426 <context-group name="null">
1427 <context context-type="linenumber">96</context>
1428 </context-group>
1429 </trans-unit>
1430 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1431 <source>Users</source>
1432 <target>Utenti</target>
1433 <context-group name="null">
1440 <context context-type="linenumber">105</context> 1434 <context context-type="linenumber">105</context>
1441 </context-group> 1435 </context-group>
1442 </trans-unit> 1436 </trans-unit>
1437 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1438 <source>User default video quota</source>
1439 <target>Quota standard per i video dell'utente</target>
1440 <context-group name="null">
1441 <context context-type="linenumber">109</context>
1442 </context-group>
1443 </trans-unit>
1444 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1445 <source>User default daily upload limit</source>
1446 <target>Limite giornaliero per il caricamento</target>
1447 <context-group name="null">
1448 <context context-type="linenumber">121</context>
1449 </context-group>
1450 </trans-unit>
1443 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1451 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1444 <source>Import</source> 1452 <source>Import</source>
1445 <target>Carica</target> 1453 <target>Carica</target>
@@ -1451,49 +1459,28 @@
1451 <source>Video import with HTTP URL (i.e. YouTube) enabled</source> 1459 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1452 <target>Importazione video con indirizzo HTTP (es. YouTube) abilitata</target> 1460 <target>Importazione video con indirizzo HTTP (es. YouTube) abilitata</target>
1453 <context-group name="null"> 1461 <context-group name="null">
1454 <context context-type="linenumber">120</context> 1462 <context context-type="linenumber">141</context>
1455 </context-group> 1463 </context-group>
1456 </trans-unit> 1464 </trans-unit>
1457 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e"> 1465 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e">
1458 <source>Video import with a torrent file or a magnet URI enabled</source> 1466 <source>Video import with a torrent file or a magnet URI enabled</source>
1459 <target>Carica video con un file torrent o un URI magnete attivo</target> 1467 <target>Carica video con un file torrent o un URI magnete attivo</target>
1460 <context-group name="null"> 1468 <context-group name="null">
1461 <context context-type="linenumber">127</context> 1469 <context context-type="linenumber">148</context>
1462 </context-group> 1470 </context-group>
1463 </trans-unit> 1471 </trans-unit>
1464 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1472 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1465 <source>Administrator</source> 1473 <source>Administrator</source>
1466 <target>Amministratore</target> 1474 <target>Amministratore</target>
1467 <context-group name="null"> 1475 <context-group name="null">
1468 <context context-type="linenumber">131</context> 1476 <context context-type="linenumber">155</context>
1469 </context-group> 1477 </context-group>
1470 </trans-unit> 1478 </trans-unit>
1471 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1479 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1472 <source>Admin email</source> 1480 <source>Admin email</source>
1473 <target>Email Amministratore</target> 1481 <target>Email Amministratore</target>
1474 <context-group name="null"> 1482 <context-group name="null">
1475 <context context-type="linenumber">134</context> 1483 <context context-type="linenumber">158</context>
1476 </context-group>
1477 </trans-unit>
1478 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1479 <source>Users</source>
1480 <target>Utenti</target>
1481 <context-group name="null">
1482 <context context-type="linenumber">144</context>
1483 </context-group>
1484 </trans-unit>
1485 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1486 <source>User default video quota</source>
1487 <target>Quota standard per i video dell'utente</target>
1488 <context-group name="null">
1489 <context context-type="linenumber">147</context>
1490 </context-group>
1491 </trans-unit>
1492 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1493 <source>User default daily upload limit</source>
1494 <target>Limite giornaliero per il caricamento</target>
1495 <context-group name="null">
1496 <context context-type="linenumber">161</context>
1497 </context-group> 1484 </context-group>
1498 </trans-unit> 1485 </trans-unit>
1499 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1486 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1514,21 +1501,21 @@
1514 <source>Your Twitter username</source> 1501 <source>Your Twitter username</source>
1515 <target>Il tuo username Twitter</target> 1502 <target>Il tuo username Twitter</target>
1516 <context-group name="null"> 1503 <context-group name="null">
1517 <context context-type="linenumber">181</context> 1504 <context context-type="linenumber">184</context>
1518 </context-group> 1505 </context-group>
1519 </trans-unit> 1506 </trans-unit>
1520 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1507 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1521 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1508 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1522 <target>Indica l'account Twitter per il sito web o la piattaforma in cui il contenuto e' stato pubblicato.</target> 1509 <target>Indica l'account Twitter per il sito web o la piattaforma in cui il contenuto e' stato pubblicato.</target>
1523 <context-group name="null"> 1510 <context-group name="null">
1524 <context context-type="linenumber">184</context> 1511 <context context-type="linenumber">187</context>
1525 </context-group> 1512 </context-group>
1526 </trans-unit> 1513 </trans-unit>
1527 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1514 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1528 <source>Instance whitelisted by Twitter</source> 1515 <source>Instance whitelisted by Twitter</source>
1529 <target>Istanza inserita in white list da Twitter</target> 1516 <target>Istanza inserita in white list da Twitter</target>
1530 <context-group name="null"> 1517 <context-group name="null">
1531 <context context-type="linenumber">198</context> 1518 <context context-type="linenumber">199</context>
1532 </context-group> 1519 </context-group>
1533 </trans-unit> 1520 </trans-unit>
1534 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1521 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1542,35 +1529,35 @@
1542 <source>Transcoding</source> 1529 <source>Transcoding</source>
1543 <target>Trascrizione</target> 1530 <target>Trascrizione</target>
1544 <context-group name="null"> 1531 <context-group name="null">
1545 <context context-type="linenumber">210</context> 1532 <context context-type="linenumber">215</context>
1546 </context-group> 1533 </context-group>
1547 </trans-unit> 1534 </trans-unit>
1548 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1535 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1549 <source>Transcoding enabled</source> 1536 <source>Transcoding enabled</source>
1550 <target>Trascrizione attivata</target> 1537 <target>Trascrizione attivata</target>
1551 <context-group name="null"> 1538 <context-group name="null">
1552 <context context-type="linenumber">215</context> 1539 <context context-type="linenumber">221</context>
1553 </context-group> 1540 </context-group>
1554 </trans-unit> 1541 </trans-unit>
1555 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1542 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1556 <source>If you disable transcoding, many videos from your users will not work!</source> 1543 <source>If you disable transcoding, many videos from your users will not work!</source>
1557 <target>Se disatitvi la trascrizione, molti video dai tuoi utenti non funzioneranno.</target> 1544 <target>Se disatitvi la trascrizione, molti video dai tuoi utenti non funzioneranno.</target>
1558 <context-group name="null"> 1545 <context-group name="null">
1559 <context context-type="linenumber">216</context> 1546 <context context-type="linenumber">222</context>
1560 </context-group> 1547 </context-group>
1561 </trans-unit> 1548 </trans-unit>
1562 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1549 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1563 <source>Transcoding threads</source> 1550 <source>Transcoding threads</source>
1564 <target>Trascrizione thread</target> 1551 <target>Trascrizione thread</target>
1565 <context-group name="null"> 1552 <context-group name="null">
1566 <context context-type="linenumber">223</context> 1553 <context context-type="linenumber">237</context>
1567 </context-group> 1554 </context-group>
1568 </trans-unit> 1555 </trans-unit>
1569 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1556 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1570 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1557 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1571 <target>Risoluzione <x id="INTERPOLATION" equiv-text="{{resolution}}"/> abilitata</target> 1558 <target>Risoluzione <x id="INTERPOLATION" equiv-text="{{resolution}}"/> abilitata</target>
1572 <context-group name="null"> 1559 <context-group name="null">
1573 <context context-type="linenumber">239</context> 1560 <context context-type="linenumber">252</context>
1574 </context-group> 1561 </context-group>
1575 </trans-unit> 1562 </trans-unit>
1576 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1563 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1585,68 +1572,48 @@
1585 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1572 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1586 </target> 1573 </target>
1587 <context-group name="null"> 1574 <context-group name="null">
1588 <context context-type="linenumber">244</context> 1575 <context context-type="linenumber">260</context>
1589 </context-group> 1576 </context-group>
1590 </trans-unit> 1577 </trans-unit>
1591 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1578 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1592 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1579 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1593 <target>Alcuni file non sono federati (anteprime, sottotitoli). Li recuperiamo direttamente dall'istanza di origine e li mettiamo in cache.</target> 1580 <target>Alcuni file non sono federati (anteprime, sottotitoli). Li recuperiamo direttamente dall'istanza di origine e li mettiamo in cache.</target>
1594 <context-group name="null"> 1581 <context-group name="null">
1595 <context context-type="linenumber">249</context> 1582 <context context-type="linenumber">265</context>
1596 </context-group> 1583 </context-group>
1597 </trans-unit> 1584 </trans-unit>
1598 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1585 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1599 <source>Previews cache size</source> 1586 <source>Previews cache size</source>
1600 <target>Dimensione del cache per la previsualizzazione</target> 1587 <target>Dimensione del cache per la previsualizzazione</target>
1601 <context-group name="null"> 1588 <context-group name="null">
1602 <context context-type="linenumber">254</context> 1589 <context context-type="linenumber">271</context>
1603 </context-group> 1590 </context-group>
1604 </trans-unit> 1591 </trans-unit>
1605 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1592 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1606 <source>Video captions cache size</source> 1593 <source>Video captions cache size</source>
1607 <target>Dimensione </target> 1594 <target>Dimensione </target>
1608 <context-group name="null"> 1595 <context-group name="null">
1609 <context context-type="linenumber">265</context> 1596 <context context-type="linenumber">280</context>
1610 </context-group> 1597 </context-group>
1611 </trans-unit> 1598 </trans-unit>
1612 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1599 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1613 <source>Customizations</source> 1600 <source>Customizations</source>
1614 <target>Personalizzazioni</target> 1601 <target>Personalizzazioni</target>
1615 <context-group name="null"> 1602 <context-group name="null">
1616 <context context-type="linenumber">275</context> 1603 <context context-type="linenumber">289</context>
1617 </context-group> 1604 </context-group>
1618 </trans-unit> 1605 </trans-unit>
1619 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1606 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1620 <source>JavaScript</source> 1607 <source>JavaScript</source>
1621 <target>JavaScript</target> 1608 <target>JavaScript</target>
1622 <context-group name="null"> 1609 <context-group name="null">
1623 <context context-type="linenumber">278</context> 1610 <context context-type="linenumber">294</context>
1624 </context-group> 1611 </context-group>
1625 </trans-unit> 1612 </trans-unit>
1626 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1613 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1627 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1614 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1628 <target>Scrivi direttamente codice JavaScript .&lt;br /&gt;Esempio: &lt;pre&gt;console.log('La mia istanza spacca!');&lt;/pre&gt;</target> 1615 <target>Scrivi direttamente codice JavaScript .&lt;br /&gt;Esempio: &lt;pre&gt;console.log('La mia istanza spacca!');&lt;/pre&gt;</target>
1629 <context-group name="null"> 1616 <context-group name="null">
1630 <context context-type="linenumber">281</context>
1631 </context-group>
1632 </trans-unit>
1633 <trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5">
1634 <source>
1635 Write directly CSS code. Example:&lt;br /&gt;
1636 &lt;pre&gt;
1637 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1638 background-color: red;
1639 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1640 &lt;/pre&gt;
1641
1642 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1643 &lt;pre&gt;
1644 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1645 color: red;
1646 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1647 &lt;/pre&gt;
1648 </source>
1649 <context-group name="null">
1650 <context context-type="linenumber">297</context> 1617 <context context-type="linenumber">297</context>
1651 </context-group> 1618 </context-group>
1652 </trans-unit> 1619 </trans-unit>
@@ -1654,21 +1621,21 @@
1654 <source>Advanced configuration</source> 1621 <source>Advanced configuration</source>
1655 <target>Configurazione avanzata</target> 1622 <target>Configurazione avanzata</target>
1656 <context-group name="null"> 1623 <context-group name="null">
1657 <context context-type="linenumber">207</context> 1624 <context context-type="linenumber">212</context>
1658 </context-group> 1625 </context-group>
1659 </trans-unit> 1626 </trans-unit>
1660 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1627 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1661 <source>Update configuration</source> 1628 <source>Update configuration</source>
1662 <target>Aggiorna configurazione</target> 1629 <target>Aggiorna configurazione</target>
1663 <context-group name="null"> 1630 <context-group name="null">
1664 <context context-type="linenumber">325</context> 1631 <context context-type="linenumber">340</context>
1665 </context-group> 1632 </context-group>
1666 </trans-unit> 1633 </trans-unit>
1667 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1634 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1668 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1635 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1669 <target>Sembra che la configurazione sia valida. Per favore cerca potenziali errori nelle altre tab</target> 1636 <target>Sembra che la configurazione sia valida. Per favore cerca potenziali errori nelle altre tab</target>
1670 <context-group name="null"> 1637 <context-group name="null">
1671 <context context-type="linenumber">326</context> 1638 <context context-type="linenumber">341</context>
1672 </context-group> 1639 </context-group>
1673 </trans-unit> 1640 </trans-unit>
1674 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1641 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1901,6 +1868,10 @@
1901 Transcoding is enabled on server. The video quota only take in account <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>original<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> video. <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> 1868 Transcoding is enabled on server. The video quota only take in account <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>original<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> video. <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>
1902 At most, this user could use ~ <x id="INTERPOLATION" equiv-text="{{ computeQuotaWithTranscoding() | bytes: 0 }}"/>. 1869 At most, this user could use ~ <x id="INTERPOLATION" equiv-text="{{ computeQuotaWithTranscoding() | bytes: 0 }}"/>.
1903 </source> 1870 </source>
1871 <target>
1872 Il Transcoding e abilitato sul server. La quota video considera solo <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>originale<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> video. <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>
1873 In totale, questo utente potrebbe usare ~ <x id="INTERPOLATION" equiv-text="{{ computeQuotaWithTranscoding() | bytes: 0 }}"/>.
1874 </target>
1904 <context-group name="null"> 1875 <context-group name="null">
1905 <context context-type="linenumber">65</context> 1876 <context context-type="linenumber">65</context>
1906 </context-group> 1877 </context-group>
@@ -1947,7 +1918,7 @@
1947 <source>Ban reason:</source> 1918 <source>Ban reason:</source>
1948 <target>Motivo ban:</target> 1919 <target>Motivo ban:</target>
1949 <context-group name="null"> 1920 <context-group name="null">
1950 <context context-type="linenumber">92</context> 1921 <context context-type="linenumber">95</context>
1951 </context-group> 1922 </context-group>
1952 </trans-unit> 1923 </trans-unit>
1953 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 1924 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -2012,7 +1983,7 @@
2012 <source>Actions</source> 1983 <source>Actions</source>
2013 <target>Azioni</target> 1984 <target>Azioni</target>
2014 <context-group name="null"> 1985 <context-group name="null">
2015 <context context-type="linenumber">33</context> 1986 <context context-type="linenumber">35</context>
2016 </context-group> 1987 </context-group>
2017 </trans-unit> 1988 </trans-unit>
2018 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 1989 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -2047,14 +2018,14 @@
2047 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 2018 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2048 <target>Data <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 2019 <target>Data <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2049 <context-group name="null"> 2020 <context-group name="null">
2050 <context context-type="linenumber">10</context> 2021 <context context-type="linenumber">11</context>
2051 </context-group> 2022 </context-group>
2052 </trans-unit> 2023 </trans-unit>
2053 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f"> 2024 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
2054 <source>Blacklist reason:</source> 2025 <source>Blacklist reason:</source>
2055 <target>motivo per essere in Blacklist:</target> 2026 <target>motivo per essere in Blacklist:</target>
2056 <context-group name="null"> 2027 <context-group name="null">
2057 <context context-type="linenumber">41</context> 2028 <context context-type="linenumber">43</context>
2058 </context-group> 2029 </context-group>
2059 </trans-unit> 2030 </trans-unit>
2060 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 2031 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -2106,69 +2077,6 @@
2106 <context context-type="linenumber">23</context> 2077 <context context-type="linenumber">23</context>
2107 </context-group> 2078 </context-group>
2108 </trans-unit> 2079 </trans-unit>
2109 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2110 <source>My settings</source>
2111 <target>Le mie impostazioni</target>
2112 <context-group name="null">
2113 <context context-type="linenumber">3</context>
2114 </context-group>
2115 </trans-unit>
2116 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2117 <source>My library</source>
2118 <target>La mia libreria</target>
2119 <context-group name="null">
2120 <context context-type="linenumber">7</context>
2121 </context-group>
2122 </trans-unit>
2123 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2124 <source>My channels</source>
2125 <target>I miei canali</target>
2126 <context-group name="null">
2127 <context context-type="linenumber">12</context>
2128 </context-group>
2129 </trans-unit>
2130 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2131 <source>My videos</source>
2132 <target>I miei video</target>
2133 <context-group name="null">
2134 <context context-type="linenumber">14</context>
2135 </context-group>
2136 </trans-unit>
2137 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2138 <source>My subscriptions</source>
2139 <target>Le mie sottoscrizioni</target>
2140 <context-group name="null">
2141 <context context-type="linenumber">16</context>
2142 </context-group>
2143 </trans-unit>
2144 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
2145 <source>My imports</source>
2146 <target>Le mie importazioni</target>
2147 <context-group name="null">
2148 <context context-type="linenumber">18</context>
2149 </context-group>
2150 </trans-unit>
2151 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
2152 <source>Misc</source>
2153 <target>Altro</target>
2154 <context-group name="null">
2155 <context context-type="linenumber">24</context>
2156 </context-group>
2157 </trans-unit>
2158 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2159 <source>Muted instances</source>
2160 <target>Istanze silenziate</target>
2161 <context-group name="null">
2162 <context context-type="linenumber">2</context>
2163 </context-group>
2164 </trans-unit>
2165 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
2166 <source>Ownership changes</source>
2167 <target>Cambi di proprietario</target>
2168 <context-group name="null">
2169 <context context-type="linenumber">33</context>
2170 </context-group>
2171 </trans-unit>
2172 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 2080 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
2173 <source>Video quota:</source> 2081 <source>Video quota:</source>
2174 <target>Quota video:</target> 2082 <target>Quota video:</target>
@@ -2180,21 +2088,21 @@
2180 <source>Profile</source> 2088 <source>Profile</source>
2181 <target>Profilo</target> 2089 <target>Profilo</target>
2182 <context-group name="null"> 2090 <context-group name="null">
2183 <context context-type="linenumber">8</context> 2091 <context context-type="linenumber">7</context>
2184 </context-group> 2092 </context-group>
2185 </trans-unit> 2093 </trans-unit>
2186 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 2094 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
2187 <source>Video settings</source> 2095 <source>Video settings</source>
2188 <target>Impostazione video</target> 2096 <target>Impostazione video</target>
2189 <context-group name="null"> 2097 <context-group name="null">
2190 <context context-type="linenumber">15</context> 2098 <context context-type="linenumber">16</context>
2191 </context-group> 2099 </context-group>
2192 </trans-unit> 2100 </trans-unit>
2193 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 2101 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
2194 <source>Danger zone</source> 2102 <source>Danger zone</source>
2195 <target>Zona pericolosa</target> 2103 <target>Zona pericolosa</target>
2196 <context-group name="null"> 2104 <context-group name="null">
2197 <context context-type="linenumber">18</context> 2105 <context context-type="linenumber">19</context>
2198 </context-group> 2106 </context-group>
2199 </trans-unit> 2107 </trans-unit>
2200 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 2108 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -2222,13 +2130,6 @@
2222 <context context-type="linenumber">35</context> 2130 <context context-type="linenumber">35</context>
2223 </context-group> 2131 </context-group>
2224 </trans-unit> 2132 </trans-unit>
2225 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
2226 <source>Submit</source>
2227 <target>Invia</target>
2228 <context-group name="null">
2229 <context context-type="linenumber">24</context>
2230 </context-group>
2231 </trans-unit>
2232 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 2133 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
2233 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 2134 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2234 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> visualizzazioni</target> 2135 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> visualizzazioni</target>
@@ -2292,6 +2193,8 @@
2292 <trans-unit id="74728de5289ea2ff3f553bc2b48f1811680b931a"> 2193 <trans-unit id="74728de5289ea2ff3f553bc2b48f1811680b931a">
2293 <source>Short text to tell people how they can support your channel (membership platform...).&lt;br /&gt;&lt;br /&gt; 2194 <source>Short text to tell people how they can support your channel (membership platform...).&lt;br /&gt;&lt;br /&gt;
2294When you will upload a video in this channel, the video support field will be automatically filled by this text.</source> 2195When you will upload a video in this channel, the video support field will be automatically filled by this text.</source>
2196 <target>Breve testo per dire alla gente come possono supportare il tuo canale (iscrizione piattaforma...).&lt;br /&gt;&lt;br /&gt;
2197Quando tu carichi un video su questo canale. il campo di supporto per il video verra riempito con questo testo.</target>
2295 <context-group name="null"> 2198 <context-group name="null">
2296 <context context-type="linenumber">52</context> 2199 <context context-type="linenumber">52</context>
2297 </context-group> 2200 </context-group>
@@ -2386,6 +2289,13 @@ When you will upload a video in this channel, the video support field will be au
2386 <context context-type="linenumber">47</context> 2289 <context context-type="linenumber">47</context>
2387 </context-group> 2290 </context-group>
2388 </trans-unit> 2291 </trans-unit>
2292 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2293 <source>Muted instances</source>
2294 <target>Istanze silenziate</target>
2295 <context-group name="null">
2296 <context context-type="linenumber">2</context>
2297 </context-group>
2298 </trans-unit>
2389 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 2299 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
2390 <source>Change password</source> 2300 <source>Change password</source>
2391 <target>Cambia password</target> 2301 <target>Cambia password</target>
@@ -2616,14 +2526,14 @@ When you will upload a video in this channel, the video support field will be au
2616 <source>Publish will be available when upload is finished</source> 2526 <source>Publish will be available when upload is finished</source>
2617 <target>La pubblicazione sarà disponibile quando il caricamento sarà completato</target> 2527 <target>La pubblicazione sarà disponibile quando il caricamento sarà completato</target>
2618 <context-group name="null"> 2528 <context-group name="null">
2619 <context context-type="linenumber">53</context> 2529 <context context-type="linenumber">58</context>
2620 </context-group> 2530 </context-group>
2621 </trans-unit> 2531 </trans-unit>
2622 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 2532 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2623 <source>Publish</source> 2533 <source>Publish</source>
2624 <target>Pubblica</target> 2534 <target>Pubblica</target>
2625 <context-group name="null"> 2535 <context-group name="null">
2626 <context context-type="linenumber">60</context> 2536 <context context-type="linenumber">65</context>
2627 </context-group> 2537 </context-group>
2628 </trans-unit> 2538 </trans-unit>
2629 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 2539 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -2802,12 +2712,12 @@ When you will upload a video in this channel, the video support field will be au
2802 </trans-unit> 2712 </trans-unit>
2803 <trans-unit id="7e549f41b715552ffe69b85c14a690d9d81c85f0"> 2713 <trans-unit id="7e549f41b715552ffe69b85c14a690d9d81c85f0">
2804 <source>Wait transcoding before publishing the video</source><target>Wait transcoding before publishing the video</target><context-group name="null"> 2714 <source>Wait transcoding before publishing the video</source><target>Wait transcoding before publishing the video</target><context-group name="null">
2805 <context context-type="linenumber">130</context> 2715 <context context-type="linenumber">131</context>
2806 </context-group> 2716 </context-group>
2807 </trans-unit> 2717 </trans-unit>
2808 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 2718 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2809 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source><target>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</target><context-group name="null"> 2719 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source><target>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</target><context-group name="null">
2810 <context context-type="linenumber">131</context> 2720 <context context-type="linenumber">132</context>
2811 </context-group> 2721 </context-group>
2812 </trans-unit> 2722 </trans-unit>
2813 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2723 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2821,45 +2731,45 @@ When you will upload a video in this channel, the video support field will be au
2821 <source>Add another caption</source> 2731 <source>Add another caption</source>
2822 <target>Aggiungi un'altra descrizione</target> 2732 <target>Aggiungi un'altra descrizione</target>
2823 <context-group name="null"> 2733 <context-group name="null">
2824 <context context-type="linenumber">146</context> 2734 <context context-type="linenumber">147</context>
2825 </context-group> 2735 </context-group>
2826 </trans-unit> 2736 </trans-unit>
2827 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 2737 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2828 <source>See the subtitle file</source> 2738 <source>See the subtitle file</source>
2829 <target>Guarda il file dei sottotitoli</target> 2739 <target>Guarda il file dei sottotitoli</target>
2830 <context-group name="null"> 2740 <context-group name="null">
2831 <context context-type="linenumber">155</context> 2741 <context context-type="linenumber">156</context>
2832 </context-group> 2742 </context-group>
2833 </trans-unit> 2743 </trans-unit>
2834 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 2744 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2835 <source>Cancel create</source> 2745 <source>Cancel create</source>
2836 <target>Annulla creazione</target> 2746 <target>Annulla creazione</target>
2837 <context-group name="null"> 2747 <context-group name="null">
2838 <context context-type="linenumber">169</context> 2748 <context context-type="linenumber">170</context>
2839 </context-group> 2749 </context-group>
2840 </trans-unit> 2750 </trans-unit>
2841 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 2751 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2842 <source>Cancel deletion</source> 2752 <source>Cancel deletion</source>
2843 <target>Annulla creazione</target> 2753 <target>Annulla creazione</target>
2844 <context-group name="null"> 2754 <context-group name="null">
2845 <context context-type="linenumber">177</context> 2755 <context context-type="linenumber">178</context>
2846 </context-group> 2756 </context-group>
2847 </trans-unit> 2757 </trans-unit>
2848 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 2758 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2849 <source>Captions</source><target>Captions</target><context-group name="null"> 2759 <source>Captions</source><target>Captions</target><context-group name="null">
2850 <context context-type="linenumber">139</context> 2760 <context context-type="linenumber">140</context>
2851 </context-group> 2761 </context-group>
2852 </trans-unit> 2762 </trans-unit>
2853 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 2763 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
2854 <source>Upload thumbnail</source> 2764 <source>Upload thumbnail</source>
2855 <target>Carica miniatura</target> 2765 <target>Carica miniatura</target>
2856 <context-group name="null"> 2766 <context-group name="null">
2857 <context context-type="linenumber">195</context> 2767 <context context-type="linenumber">196</context>
2858 </context-group> 2768 </context-group>
2859 </trans-unit> 2769 </trans-unit>
2860 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 2770 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
2861 <source>Upload preview</source><target>Upload preview</target><context-group name="null"> 2771 <source>Upload preview</source><target>Upload preview</target><context-group name="null">
2862 <context context-type="linenumber">202</context> 2772 <context context-type="linenumber">203</context>
2863 </context-group> 2773 </context-group>
2864 </trans-unit> 2774 </trans-unit>
2865 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 2775 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -2871,14 +2781,14 @@ When you will upload a video in this channel, the video support field will be au
2871 </trans-unit> 2781 </trans-unit>
2872 <trans-unit id="f61f989de6fc12f99369a90800e4b5462d3f10a0"> 2782 <trans-unit id="f61f989de6fc12f99369a90800e4b5462d3f10a0">
2873 <source>Short text to tell people how they can support you (membership platform...).</source><target>Short text to tell people how they can support you (membership platform...).</target><context-group name="null"> 2783 <source>Short text to tell people how they can support you (membership platform...).</source><target>Short text to tell people how they can support you (membership platform...).</target><context-group name="null">
2874 <context context-type="linenumber">209</context> 2784 <context context-type="linenumber">210</context>
2875 </context-group> 2785 </context-group>
2876 </trans-unit> 2786 </trans-unit>
2877 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 2787 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
2878 <source>Advanced settings</source> 2788 <source>Advanced settings</source>
2879 <target>Impostazioni avanzate</target> 2789 <target>Impostazioni avanzate</target>
2880 <context-group name="null"> 2790 <context-group name="null">
2881 <context context-type="linenumber">190</context> 2791 <context context-type="linenumber">191</context>
2882 </context-group> 2792 </context-group>
2883 </trans-unit> 2793 </trans-unit>
2884 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 2794 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -2938,17 +2848,6 @@ When you will upload a video in this channel, the video support field will be au
2938 <context context-type="linenumber">3</context> 2848 <context context-type="linenumber">3</context>
2939 </context-group> 2849 </context-group>
2940 </trans-unit> 2850 </trans-unit>
2941 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
2942 <source>
2943 Cancel
2944 </source>
2945 <target>
2946 Annulla
2947 </target>
2948 <context-group name="null">
2949 <context context-type="linenumber">19</context>
2950 </context-group>
2951 </trans-unit>
2952 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 2851 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
2953 <source>Share</source> 2852 <source>Share</source>
2954 <target>Condividi</target> 2853 <target>Condividi</target>
@@ -2970,6 +2869,9 @@ When you will upload a video in this channel, the video support field will be au
2970 <source> 2869 <source>
2971 The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites). 2870 The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites).
2972 </source> 2871 </source>
2872 <target>
2873 L'url non è sicuro (no HTTPS), quindi il video "incluso" non funzionerà su siti HTTPS (il browser blocca richieste verso siti HTTP su siti in cui HTTPS è abilitato).
2874 </target>
2973 <context-group name="null"> 2875 <context-group name="null">
2974 <context context-type="linenumber">45</context> 2876 <context context-type="linenumber">45</context>
2975 </context-group> 2877 </context-group>
@@ -2992,6 +2894,9 @@ When you will upload a video in this channel, the video support field will be au
2992 <source> 2894 <source>
2993 The video is being imported, it will be available when the import is finished. 2895 The video is being imported, it will be available when the import is finished.
2994 </source> 2896 </source>
2897 <target>
2898 Il video è nella fase di import, sarà disponibile quando l'import sarà completato.
2899 </target>
2995 <context-group name="null"> 2900 <context-group name="null">
2996 <context context-type="linenumber">11</context> 2901 <context context-type="linenumber">11</context>
2997 </context-group> 2902 </context-group>
@@ -3028,6 +2933,9 @@ When you will upload a video in this channel, the video support field will be au
3028 <source> 2933 <source>
3029 Published <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views 2934 Published <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views
3030 </source> 2935 </source>
2936 <target>
2937 Pubblicato <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> visioni
2938 </target>
3031 <context-group name="null"> 2939 <context-group name="null">
3032 <context context-type="linenumber">37</context> 2940 <context context-type="linenumber">37</context>
3033 </context-group> 2941 </context-group>
@@ -3262,13 +3170,6 @@ Altri video</target>
3262 <context context-type="linenumber">14</context> 3170 <context context-type="linenumber">14</context>
3263 </context-group> 3171 </context-group>
3264 </trans-unit> 3172 </trans-unit>
3265 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
3266 <source>Error getting about from server</source>
3267 <target>Errore durante la comunicazione con il server</target>
3268 <context-group name="null">
3269 <context context-type="linenumber">1</context>
3270 </context-group>
3271 </trans-unit>
3272 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 3173 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
3273 <source>No description</source> 3174 <source>No description</source>
3274 <target>Nessuna descrizione</target> 3175 <target>Nessuna descrizione</target>
@@ -3290,15 +3191,17 @@ Altri video</target>
3290 <context context-type="linenumber">1</context> 3191 <context context-type="linenumber">1</context>
3291 </context-group> 3192 </context-group>
3292 </trans-unit> 3193 </trans-unit>
3293 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d"> 3194 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
3294 <source>Error</source> 3195 <source>240p</source>
3295 <target>Errore</target> 3196 <target>240p</target>
3296 <context-group name="null"> 3197 <context-group name="null">
3297 <context context-type="linenumber">1</context> 3198 <context context-type="linenumber">1</context>
3298 </context-group> 3199 </context-group>
3299 </trans-unit> 3200 </trans-unit>
3300 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba"> 3201 <trans-unit id="c8cfad7e7a16c57c42535331b65cb7de40d8402e">
3301 <source>Success</source><target>Success</target><context-group name="null"> 3202 <source>360p</source>
3203 <target>360p</target>
3204 <context-group name="null">
3302 <context context-type="linenumber">1</context> 3205 <context context-type="linenumber">1</context>
3303 </context-group> 3206 </context-group>
3304 </trans-unit> 3207 </trans-unit>
@@ -3316,6 +3219,48 @@ Altri video</target>
3316 <context context-type="linenumber">1</context> 3219 <context context-type="linenumber">1</context>
3317 </context-group> 3220 </context-group>
3318 </trans-unit> 3221 </trans-unit>
3222 <trans-unit id="54adc67482fdaa0d361a2992bc91e064dc61cc9a">
3223 <source>100MB</source>
3224 <target>100MB</target>
3225 <context-group name="null">
3226 <context context-type="linenumber">1</context>
3227 </context-group>
3228 </trans-unit>
3229 <trans-unit id="cd34ef1f476d5422f49f6ed429f61fc1cfcb1174">
3230 <source>500MB</source>
3231 <target>500MB</target>
3232 <context-group name="null">
3233 <context context-type="linenumber">1</context>
3234 </context-group>
3235 </trans-unit>
3236 <trans-unit id="4a47b4beea31cac6e5970b6bc522902f545acc8b">
3237 <source>1GB</source>
3238 <target>1GB</target>
3239 <context-group name="null">
3240 <context context-type="linenumber">1</context>
3241 </context-group>
3242 </trans-unit>
3243 <trans-unit id="b26d0cac75638623098ab7e06e16b096d1f55cc8">
3244 <source>5GB</source>
3245 <target>5GB</target>
3246 <context-group name="null">
3247 <context context-type="linenumber">1</context>
3248 </context-group>
3249 </trans-unit>
3250 <trans-unit id="f9fc4e7ec6743cb6f69bea2d0859a655ed44ffae">
3251 <source>20GB</source>
3252 <target>20GB</target>
3253 <context-group name="null">
3254 <context context-type="linenumber">1</context>
3255 </context-group>
3256 </trans-unit>
3257 <trans-unit id="a56e3f92fe16d97ee4f05051ea61c466ecb51d5e">
3258 <source>50GB</source>
3259 <target>50GB</target>
3260 <context-group name="null">
3261 <context context-type="linenumber">1</context>
3262 </context-group>
3263 </trans-unit>
3319 <trans-unit id="31dcc0c63f6234ace8caa84ae1abc33d4022122d"> 3264 <trans-unit id="31dcc0c63f6234ace8caa84ae1abc33d4022122d">
3320 <source>10MB</source> 3265 <source>10MB</source>
3321 <target>10MB</target> 3266 <target>10MB</target>
@@ -3400,6 +3345,13 @@ Altri video</target>
3400 <context context-type="linenumber">1</context> 3345 <context context-type="linenumber">1</context>
3401 </context-group> 3346 </context-group>
3402 </trans-unit> 3347 </trans-unit>
3348 <trans-unit id="4d8f527638f3e0b518a96e07d41d886bcce01246">
3349 <source>enabled</source>
3350 <target>attivato</target>
3351 <context-group name="null">
3352 <context context-type="linenumber">1</context>
3353 </context-group>
3354 </trans-unit>
3403 <trans-unit id="795733aac948794cadeb3be6386882efac2c38ad"> 3355 <trans-unit id="795733aac948794cadeb3be6386882efac2c38ad">
3404 <source>disabled</source> 3356 <source>disabled</source>
3405 <target>disabilitato</target> 3357 <target>disabilitato</target>
@@ -3421,6 +3373,13 @@ Altri video</target>
3421 <context context-type="linenumber">1</context> 3373 <context context-type="linenumber">1</context>
3422 </context-group> 3374 </context-group>
3423 </trans-unit> 3375 </trans-unit>
3376 <trans-unit id="586bee8c27a761611eb05661524cc7ca944b5978">
3377 <source>Delete this report</source>
3378 <target>Elimina questa segnalazione</target>
3379 <context-group name="null">
3380 <context context-type="linenumber">1</context>
3381 </context-group>
3382 </trans-unit>
3424 <trans-unit id="cf3b28ba29a907b334ab0e6dccd080a60ba23321"> 3383 <trans-unit id="cf3b28ba29a907b334ab0e6dccd080a60ba23321">
3425 <source>Update moderation comment</source> 3384 <source>Update moderation comment</source>
3426 <target>Modifica commento di moderazione</target> 3385 <target>Modifica commento di moderazione</target>
@@ -3442,6 +3401,13 @@ Altri video</target>
3442 <context context-type="linenumber">1</context> 3401 <context context-type="linenumber">1</context>
3443 </context-group> 3402 </context-group>
3444 </trans-unit> 3403 </trans-unit>
3404 <trans-unit id="73b70e37cddaa6494d8a666b6cba90dc80595599">
3405 <source>Do you really want to delete this abuse report?</source>
3406 <target>Vuoi veramente eliminare questa segnalazione di abuso?</target>
3407 <context-group name="null">
3408 <context context-type="linenumber">1</context>
3409 </context-group>
3410 </trans-unit>
3445 <trans-unit id="6a7938b8780c27540ea70cc0f8f4d928c8916cf9"> 3411 <trans-unit id="6a7938b8780c27540ea70cc0f8f4d928c8916cf9">
3446 <source>Abuse deleted.</source><target>Abuse deleted.</target><context-group name="null"> 3412 <source>Abuse deleted.</source><target>Abuse deleted.</target><context-group name="null">
3447 <context context-type="linenumber">1</context> 3413 <context context-type="linenumber">1</context>
@@ -3501,6 +3467,13 @@ Altri video</target>
3501 <context context-type="linenumber">1</context> 3467 <context context-type="linenumber">1</context>
3502 </context-group> 3468 </context-group>
3503 </trans-unit> 3469 </trans-unit>
3470 <trans-unit id="b708d332e3f89b24745e749fa530210f0bdea329">
3471 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users deleted.</source>
3472 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> utenti eliminati.</target>
3473 <context-group name="null">
3474 <context context-type="linenumber">1</context>
3475 </context-group>
3476 </trans-unit>
3504 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e"> 3477 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e">
3505 <source>Ownership accepted</source><target>Ownership accepted</target><context-group name="null"> 3478 <source>Ownership accepted</source><target>Ownership accepted</target><context-group name="null">
3506 <context context-type="linenumber">1</context> 3479 <context context-type="linenumber">1</context>
@@ -3576,6 +3549,13 @@ Altri video</target>
3576 <context context-type="linenumber">1</context> 3549 <context context-type="linenumber">1</context>
3577 </context-group> 3550 </context-group>
3578 </trans-unit> 3551 </trans-unit>
3552 <trans-unit id="f359f6adf6cccca7770019f947ed594169ee7d47">
3553 <source>This name already exists on this instance.</source>
3554 <target>Questo nome esiste già nell'istanza.</target>
3555 <context-group name="null">
3556 <context context-type="linenumber">1</context>
3557 </context-group>
3558 </trans-unit>
3579 <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795"> 3559 <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795">
3580 <source>Create</source> 3560 <source>Create</source>
3581 <target>Crea</target> 3561 <target>Crea</target>
@@ -3590,23 +3570,16 @@ Altri video</target>
3590 <context context-type="linenumber">1</context> 3570 <context context-type="linenumber">1</context>
3591 </context-group> 3571 </context-group>
3592 </trans-unit> 3572 </trans-unit>
3593 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 3573 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
3594 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 3574 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
3595 <target>Vuoi veramente eliminare <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? Questo eliminerá anche tutti i video caricati su questo canale.</target> 3575 <target>Il canale video <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> è stato cancellato.</target>
3596 <context-group name="null">
3597 <context context-type="linenumber">1</context>
3598 </context-group>
3599 </trans-unit>
3600 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
3601 <source>Please type the name of the video channel to confirm</source>
3602 <target>Per favore digita il nome del canale video per confermare</target>
3603 <context-group name="null"> 3576 <context-group name="null">
3604 <context context-type="linenumber">1</context> 3577 <context context-type="linenumber">1</context>
3605 </context-group> 3578 </context-group>
3606 </trans-unit> 3579 </trans-unit>
3607 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 3580 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
3608 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 3581 <source>My videos</source>
3609 <target>Il canale video <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> è stato cancellato.</target> 3582 <target>I miei video</target>
3610 <context-group name="null"> 3583 <context-group name="null">
3611 <context context-type="linenumber">1</context> 3584 <context context-type="linenumber">1</context>
3612 </context-group> 3585 </context-group>
@@ -3677,16 +3650,44 @@ Altri video</target>
3677 <context context-type="linenumber">1</context> 3650 <context context-type="linenumber">1</context>
3678 </context-group> 3651 </context-group>
3679 </trans-unit> 3652 </trans-unit>
3680 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 3653 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
3681 <source>Channels</source> 3654 <source>My library</source>
3682 <target>Canali</target> 3655 <target>La mia libreria</target>
3656 <context-group name="null">
3657 <context context-type="linenumber">1</context>
3658 </context-group>
3659 </trans-unit>
3660 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
3661 <source>My channels</source>
3662 <target>I miei canali</target>
3663 <context-group name="null">
3664 <context context-type="linenumber">1</context>
3665 </context-group>
3666 </trans-unit>
3667 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
3668 <source>My subscriptions</source>
3669 <target>Le mie sottoscrizioni</target>
3670 <context-group name="null">
3671 <context context-type="linenumber">1</context>
3672 </context-group>
3673 </trans-unit>
3674 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
3675 <source>Misc</source>
3676 <target>Altro</target>
3677 <context-group name="null">
3678 <context context-type="linenumber">1</context>
3679 </context-group>
3680 </trans-unit>
3681 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
3682 <source>Ownership changes</source>
3683 <target>Cambi di proprietario</target>
3683 <context-group name="null"> 3684 <context-group name="null">
3684 <context context-type="linenumber">1</context> 3685 <context context-type="linenumber">1</context>
3685 </context-group> 3686 </context-group>
3686 </trans-unit> 3687 </trans-unit>
3687 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d"> 3688 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
3688 <source>Video imports</source> 3689 <source>My settings</source>
3689 <target>Caricamenti video</target> 3690 <target>Le mie impostazioni</target>
3690 <context-group name="null"> 3691 <context-group name="null">
3691 <context context-type="linenumber">1</context> 3692 <context context-type="linenumber">1</context>
3692 </context-group> 3693 </context-group>
@@ -3705,6 +3706,13 @@ Altri video</target>
3705 <context context-type="linenumber">1</context> 3706 <context context-type="linenumber">1</context>
3706 </context-group> 3707 </context-group>
3707 </trans-unit> 3708 </trans-unit>
3709 <trans-unit id="b54759e30f7c1983940cdacb8eb03f102a869084">
3710 <source>Go to the videos overview page</source>
3711 <target>Vai alla pagina di anteprima dei video</target>
3712 <context-group name="null">
3713 <context context-type="linenumber">1</context>
3714 </context-group>
3715 </trans-unit>
3708 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7"> 3716 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7">
3709 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>. 3717 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>.
3710</source> 3718</source>
@@ -3721,6 +3729,13 @@ Altri video</target>
3721 <context context-type="linenumber">1</context> 3729 <context context-type="linenumber">1</context>
3722 </context-group> 3730 </context-group>
3723 </trans-unit> 3731 </trans-unit>
3732 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
3733 <source>Error</source>
3734 <target>Errore</target>
3735 <context-group name="null">
3736 <context context-type="linenumber">1</context>
3737 </context-group>
3738 </trans-unit>
3724 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 3739 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
3725 <source>You need to reconnect.</source> 3740 <source>You need to reconnect.</source>
3726 <target>Devi riconnetterti.</target> 3741 <target>Devi riconnetterti.</target>
@@ -3742,6 +3757,18 @@ Altri video</target>
3742 <context context-type="linenumber">1</context> 3757 <context context-type="linenumber">1</context>
3743 </context-group> 3758 </context-group>
3744 </trans-unit> 3759 </trans-unit>
3760 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
3761 <source>Info</source>
3762 <target>Informazioni</target>
3763 <context-group name="null">
3764 <context context-type="linenumber">1</context>
3765 </context-group>
3766 </trans-unit>
3767 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
3768 <source>Success</source><target>Success</target><context-group name="null">
3769 <context context-type="linenumber">1</context>
3770 </context-group>
3771 </trans-unit>
3745 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 3772 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
3746 <source>Incorrect username or password.</source> 3773 <source>Incorrect username or password.</source>
3747 <target>Username or password non corretti</target> 3774 <target>Username or password non corretti</target>
@@ -3959,6 +3986,20 @@ Altri video</target>
3959 <context context-type="linenumber">1</context> 3986 <context context-type="linenumber">1</context>
3960 </context-group> 3987 </context-group>
3961 </trans-unit> 3988 </trans-unit>
3989 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
3990 <source>Email is required.</source>
3991 <target>L'email è richiesta.</target>
3992 <context-group name="null">
3993 <context context-type="linenumber">1</context>
3994 </context-group>
3995 </trans-unit>
3996 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
3997 <source>Email must be valid.</source>
3998 <target>L'email deve essere valida.</target>
3999 <context-group name="null">
4000 <context context-type="linenumber">1</context>
4001 </context-group>
4002 </trans-unit>
3962 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 4003 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
3963 <source>Username is required.</source> 4004 <source>Username is required.</source>
3964 <target>L'username è necessario.</target> 4005 <target>L'username è necessario.</target>
@@ -3980,41 +4021,6 @@ Altri video</target>
3980 <context context-type="linenumber">1</context> 4021 <context context-type="linenumber">1</context>
3981 </context-group> 4022 </context-group>
3982 </trans-unit> 4023 </trans-unit>
3983 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
3984 <source>Username must be at least 3 characters long.</source>
3985 <target>L'username deve essere almeno di 3 caratteri.</target>
3986 <context-group name="null">
3987 <context context-type="linenumber">1</context>
3988 </context-group>
3989 </trans-unit>
3990 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
3991 <source>Username cannot be more than 20 characters long.</source>
3992 <target>L'username non può essere più di 20 caratteri.</target>
3993 <context-group name="null">
3994 <context context-type="linenumber">1</context>
3995 </context-group>
3996 </trans-unit>
3997 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
3998 <source>Username should be only lowercase alphanumeric characters.</source>
3999 <target>L'username dovrebbe essere solo in minuscolo e contenere solo alfanumerici.</target>
4000 <context-group name="null">
4001 <context context-type="linenumber">1</context>
4002 </context-group>
4003 </trans-unit>
4004 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4005 <source>Email is required.</source>
4006 <target>L'email è richiesta.</target>
4007 <context-group name="null">
4008 <context context-type="linenumber">1</context>
4009 </context-group>
4010 </trans-unit>
4011 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4012 <source>Email must be valid.</source>
4013 <target>L'email deve essere valida.</target>
4014 <context-group name="null">
4015 <context context-type="linenumber">1</context>
4016 </context-group>
4017 </trans-unit>
4018 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 4024 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
4019 <source>Password must be at least 6 characters long.</source> 4025 <source>Password must be at least 6 characters long.</source>
4020 <target>La password deve essere lunga almeno 6 caratteri.</target> 4026 <target>La password deve essere lunga almeno 6 caratteri.</target>
@@ -4078,16 +4084,6 @@ Altri video</target>
4078 <context context-type="linenumber">1</context> 4084 <context context-type="linenumber">1</context>
4079 </context-group> 4085 </context-group>
4080 </trans-unit> 4086 </trans-unit>
4081 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
4082 <source>Display name must be at least 3 characters long.</source><target>Display name must be at least 3 characters long.</target><context-group name="null">
4083 <context context-type="linenumber">1</context>
4084 </context-group>
4085 </trans-unit>
4086 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
4087 <source>Display name cannot be more than 120 characters long.</source><target>Display name cannot be more than 120 characters long.</target><context-group name="null">
4088 <context context-type="linenumber">1</context>
4089 </context-group>
4090 </trans-unit>
4091 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 4087 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
4092 <source>Description must be at least 3 characters long.</source> 4088 <source>Description must be at least 3 characters long.</source>
4093 <target>La descrizione deve avere al minino 3 caratteri.</target> 4089 <target>La descrizione deve avere al minino 3 caratteri.</target>
@@ -4130,13 +4126,6 @@ Altri video</target>
4130 <context context-type="linenumber">1</context> 4126 <context context-type="linenumber">1</context>
4131 </context-group> 4127 </context-group>
4132 </trans-unit> 4128 </trans-unit>
4133 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
4134 <source>Report reason cannot be more than 300 characters long.</source>
4135 <target>Il motivo per la segnalazione non può essere più lungo di 300 caratteri.</target>
4136 <context-group name="null">
4137 <context context-type="linenumber">1</context>
4138 </context-group>
4139 </trans-unit>
4140 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118"> 4129 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
4141 <source>Moderation comment is required.</source> 4130 <source>Moderation comment is required.</source>
4142 <target>Il commento di moderazione è richiesto.</target> 4131 <target>Il commento di moderazione è richiesto.</target>
@@ -4151,13 +4140,6 @@ Altri video</target>
4151 <context context-type="linenumber">1</context> 4140 <context context-type="linenumber">1</context>
4152 </context-group> 4141 </context-group>
4153 </trans-unit> 4142 </trans-unit>
4154 <trans-unit id="89d0b662dde0871cf17244e79b2cb62cd517e44f">
4155 <source>Moderation comment cannot be more than 300 characters long.</source>
4156 <target>Il commento di moderazione non può essere più lungo di 300 caratteri.</target>
4157 <context-group name="null">
4158 <context context-type="linenumber">1</context>
4159 </context-group>
4160 </trans-unit>
4161 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6"> 4143 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
4162 <source>The channel is required.</source> 4144 <source>The channel is required.</source>
4163 <target>Il canale è richiesto.</target> 4145 <target>Il canale è richiesto.</target>
@@ -4179,27 +4161,6 @@ Altri video</target>
4179 <context context-type="linenumber">1</context> 4161 <context context-type="linenumber">1</context>
4180 </context-group> 4162 </context-group>
4181 </trans-unit> 4163 </trans-unit>
4182 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069">
4183 <source>Name must be at least 3 characters long.</source>
4184 <target>Il nome deve essere al minimo lunguo di tre caratteri.</target>
4185 <context-group name="null">
4186 <context context-type="linenumber">1</context>
4187 </context-group>
4188 </trans-unit>
4189 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482">
4190 <source>Name cannot be more than 20 characters long.</source>
4191 <target>Il nome non deve superare i 20 caratteri.</target>
4192 <context-group name="null">
4193 <context context-type="linenumber">1</context>
4194 </context-group>
4195 </trans-unit>
4196 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9">
4197 <source>Name should be only lowercase alphanumeric characters.</source>
4198 <target>Il nome deve contenire solo caratteri minuscoli ed alfanumerichi;</target>
4199 <context-group name="null">
4200 <context context-type="linenumber">1</context>
4201 </context-group>
4202 </trans-unit>
4203 <trans-unit id="6ca60e0f6dfbc0073b0514bce7d273150b0b9e79"> 4164 <trans-unit id="6ca60e0f6dfbc0073b0514bce7d273150b0b9e79">
4204 <source>Comment is required.</source> 4165 <source>Comment is required.</source>
4205 <target>Un commento è necessario.</target> 4166 <target>Un commento è necessario.</target>
@@ -4859,13 +4820,6 @@ Altri video</target>
4859 <context context-type="linenumber">1</context> 4820 <context context-type="linenumber">1</context>
4860 </context-group> 4821 </context-group>
4861 </trans-unit> 4822 </trans-unit>
4862 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
4863 <source>Subscribed</source>
4864 <target>Iscritto</target>
4865 <context-group name="null">
4866 <context context-type="linenumber">1</context>
4867 </context-group>
4868 </trans-unit>
4869 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded"> 4823 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
4870 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source> 4824 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
4871 <target>Iscritto a <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target> 4825 <target>Iscritto a <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
@@ -4873,9 +4827,9 @@ Altri video</target>
4873 <context context-type="linenumber">1</context> 4827 <context context-type="linenumber">1</context>
4874 </context-group> 4828 </context-group>
4875 </trans-unit> 4829 </trans-unit>
4876 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471"> 4830 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
4877 <source>Unsubscribed</source> 4831 <source>Subscribed</source>
4878 <target>Disiscritto</target> 4832 <target>Iscritto</target>
4879 <context-group name="null"> 4833 <context-group name="null">
4880 <context context-type="linenumber">1</context> 4834 <context context-type="linenumber">1</context>
4881 </context-group> 4835 </context-group>
@@ -4887,6 +4841,13 @@ Altri video</target>
4887 <context context-type="linenumber">1</context> 4841 <context context-type="linenumber">1</context>
4888 </context-group> 4842 </context-group>
4889 </trans-unit> 4843 </trans-unit>
4844 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
4845 <source>Unsubscribed</source>
4846 <target>Disiscritto</target>
4847 <context-group name="null">
4848 <context context-type="linenumber">1</context>
4849 </context-group>
4850 </trans-unit>
4890 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf"> 4851 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf">
4891 <source>Moderator</source> 4852 <source>Moderator</source>
4892 <target>Moderatore</target> 4853 <target>Moderatore</target>
@@ -4943,13 +4904,6 @@ Altri video</target>
4943 <context context-type="linenumber">1</context> 4904 <context context-type="linenumber">1</context>
4944 </context-group> 4905 </context-group>
4945 </trans-unit> 4906 </trans-unit>
4946 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4947 <source>Info</source>
4948 <target>Informazioni</target>
4949 <context-group name="null">
4950 <context context-type="linenumber">1</context>
4951 </context-group>
4952 </trans-unit>
4953 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 4907 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
4954 <source>Upload cancelled</source> 4908 <source>Upload cancelled</source>
4955 <target>Caricamento annullato.</target> 4909 <target>Caricamento annullato.</target>
@@ -4957,13 +4911,6 @@ Altri video</target>
4957 <context context-type="linenumber">1</context> 4911 <context context-type="linenumber">1</context>
4958 </context-group> 4912 </context-group>
4959 </trans-unit> 4913 </trans-unit>
4960 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa">
4961 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
4962 <target>Ci dispiace ma PeerTube non può gestire video di dimensioni &gt; 8GB</target>
4963 <context-group name="null">
4964 <context context-type="linenumber">1</context>
4965 </context-group>
4966 </trans-unit>
4967 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee"> 4914 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
4968 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source> 4915 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
4969 <target>La tua quota è stata superata con questo video (dimensione del video: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, stai utilizzando: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target> 4916 <target>La tua quota è stata superata con questo video (dimensione del video: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, stai utilizzando: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
diff --git a/client/src/locale/target/angular_ja_JP.xml b/client/src/locale/target/angular_ja_JP.xml
index d0b592098..04bd5089a 100644
--- a/client/src/locale/target/angular_ja_JP.xml
+++ b/client/src/locale/target/angular_ja_JP.xml
@@ -342,7 +342,7 @@
342 <source>Password</source> 342 <source>Password</source>
343 <target>パスワード</target> 343 <target>パスワード</target>
344 <context-group name="null"> 344 <context-group name="null">
345 <context context-type="linenumber">12</context> 345 <context context-type="linenumber">13</context>
346 </context-group> 346 </context-group>
347 </trans-unit> 347 </trans-unit>
348 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 348 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -356,7 +356,7 @@
356 <source>Login</source> 356 <source>Login</source>
357 <target>ログイン</target> 357 <target>ログイン</target>
358 <context-group name="null"> 358 <context-group name="null">
359 <context context-type="linenumber">38</context> 359 <context context-type="linenumber">36</context>
360 </context-group> 360 </context-group>
361 </trans-unit> 361 </trans-unit>
362 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 362 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -382,7 +382,7 @@
382 <source>Send me an email to reset my password</source> 382 <source>Send me an email to reset my password</source>
383 <target>æ–°ã—ã„パスワードをメールã§é€ã‚‹</target> 383 <target>æ–°ã—ã„パスワードをメールã§é€ã‚‹</target>
384 <context-group name="null"> 384 <context-group name="null">
385 <context context-type="linenumber">75</context> 385 <context context-type="linenumber">80</context>
386 </context-group> 386 </context-group>
387 </trans-unit> 387 </trans-unit>
388 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 388 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -444,7 +444,7 @@
444 <source>Signup</source> 444 <source>Signup</source>
445 <target>サインアップ</target> 445 <target>サインアップ</target>
446 <context-group name="null"> 446 <context-group name="null">
447 <context context-type="linenumber">88</context> 447 <context context-type="linenumber">78</context>
448 </context-group> 448 </context-group>
449 </trans-unit> 449 </trans-unit>
450 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a"> 450 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a">
@@ -456,7 +456,7 @@
456 </trans-unit> 456 </trans-unit>
457 <trans-unit id="aef5c45fb9c725573d20a6283492e6b80fd2ae96"> 457 <trans-unit id="aef5c45fb9c725573d20a6283492e6b80fd2ae96">
458 <source>Change the language</source><target>Change the language</target><context-group name="null"> 458 <source>Change the language</source><target>Change the language</target><context-group name="null">
459 <context context-type="linenumber">88</context> 459 <context context-type="linenumber">86</context>
460 </context-group> 460 </context-group>
461 </trans-unit> 461 </trans-unit>
462 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 462 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -465,7 +465,7 @@
465 </source> 465 </source>
466 <target>マイアカウント</target> 466 <target>マイアカウント</target>
467 <context-group name="null"> 467 <context-group name="null">
468 <context context-type="linenumber">22</context> 468 <context context-type="linenumber">20</context>
469 </context-group> 469 </context-group>
470 </trans-unit> 470 </trans-unit>
471 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 471 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -474,7 +474,7 @@
474 </source> 474 </source>
475 <target>マイビデオ</target> 475 <target>マイビデオ</target>
476 <context-group name="null"> 476 <context-group name="null">
477 <context context-type="linenumber">26</context> 477 <context context-type="linenumber">24</context>
478 </context-group> 478 </context-group>
479 </trans-unit> 479 </trans-unit>
480 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 480 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -483,14 +483,14 @@
483 </source> 483 </source>
484 <target>ログアウト</target> 484 <target>ログアウト</target>
485 <context-group name="null"> 485 <context-group name="null">
486 <context context-type="linenumber">30</context> 486 <context context-type="linenumber">28</context>
487 </context-group> 487 </context-group>
488 </trans-unit> 488 </trans-unit>
489 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 489 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
490 <source>Create an account</source> 490 <source>Create an account</source>
491 <target>アカウントを作æˆã™ã‚‹</target> 491 <target>アカウントを作æˆã™ã‚‹</target>
492 <context-group name="null"> 492 <context-group name="null">
493 <context context-type="linenumber">39</context> 493 <context context-type="linenumber">37</context>
494 </context-group> 494 </context-group>
495 </trans-unit> 495 </trans-unit>
496 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 496 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -504,47 +504,47 @@
504 <source>Subscriptions</source> 504 <source>Subscriptions</source>
505 <target>サブスクリプション</target> 505 <target>サブスクリプション</target>
506 <context-group name="null"> 506 <context-group name="null">
507 <context context-type="linenumber">47</context> 507 <context context-type="linenumber">45</context>
508 </context-group> 508 </context-group>
509 </trans-unit> 509 </trans-unit>
510 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 510 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
511 <source>Overview</source> 511 <source>Overview</source>
512 <target>調査</target> 512 <target>調査</target>
513 <context-group name="null"> 513 <context-group name="null">
514 <context context-type="linenumber">52</context> 514 <context context-type="linenumber">50</context>
515 </context-group> 515 </context-group>
516 </trans-unit> 516 </trans-unit>
517 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 517 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
518 <source>Trending</source><target>Trending</target><context-group name="null"> 518 <source>Trending</source><target>Trending</target><context-group name="null">
519 <context context-type="linenumber">57</context> 519 <context context-type="linenumber">55</context>
520 </context-group> 520 </context-group>
521 </trans-unit> 521 </trans-unit>
522 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 522 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
523 <source>Recently added</source> 523 <source>Recently added</source>
524 <target>最近追加ã•ã‚ŒãŸ</target> 524 <target>最近追加ã•ã‚ŒãŸ</target>
525 <context-group name="null"> 525 <context-group name="null">
526 <context context-type="linenumber">62</context> 526 <context context-type="linenumber">60</context>
527 </context-group> 527 </context-group>
528 </trans-unit> 528 </trans-unit>
529 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 529 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
530 <source>Local</source> 530 <source>Local</source>
531 <target>地元</target> 531 <target>地元</target>
532 <context-group name="null"> 532 <context-group name="null">
533 <context context-type="linenumber">67</context> 533 <context context-type="linenumber">65</context>
534 </context-group> 534 </context-group>
535 </trans-unit> 535 </trans-unit>
536 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 536 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
537 <source>More</source> 537 <source>More</source>
538 <target>多ãã®</target> 538 <target>多ãã®</target>
539 <context-group name="null"> 539 <context-group name="null">
540 <context context-type="linenumber">72</context> 540 <context context-type="linenumber">70</context>
541 </context-group> 541 </context-group>
542 </trans-unit> 542 </trans-unit>
543 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 543 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
544 <source>Administration</source> 544 <source>Administration</source>
545 <target>é‹å–¶</target> 545 <target>é‹å–¶</target>
546 <context-group name="null"> 546 <context-group name="null">
547 <context context-type="linenumber">76</context> 547 <context context-type="linenumber">74</context>
548 </context-group> 548 </context-group>
549 </trans-unit> 549 </trans-unit>
550 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 550 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -635,7 +635,7 @@
635 <source>No results.</source> 635 <source>No results.</source>
636 <target>çµæžœãŒã‚ã‚Šã¾ã›ã‚“。</target> 636 <target>çµæžœãŒã‚ã‚Šã¾ã›ã‚“。</target>
637 <context-group name="null"> 637 <context-group name="null">
638 <context context-type="linenumber">17</context> 638 <context context-type="linenumber">20</context>
639 </context-group> 639 </context-group>
640 </trans-unit> 640 </trans-unit>
641 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 641 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -682,6 +682,24 @@
682 <context context-type="linenumber">7</context> 682 <context context-type="linenumber">7</context>
683 </context-group> 683 </context-group>
684 </trans-unit> 684 </trans-unit>
685 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
686 <source>
687 Cancel
688 </source>
689 <target>
690 キャンセル
691 </target>
692 <context-group name="null">
693 <context context-type="linenumber">26</context>
694 </context-group>
695 </trans-unit>
696 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
697 <source>Submit</source>
698 <target>å·®ã—出ã™</target>
699 <context-group name="null">
700 <context context-type="linenumber">31</context>
701 </context-group>
702 </trans-unit>
685 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 703 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
686 <source>Description</source> 704 <source>Description</source>
687 <target>説明</target> 705 <target>説明</target>
@@ -693,23 +711,14 @@
693 <source>Terms</source> 711 <source>Terms</source>
694 <target>æ¡é …</target> 712 <target>æ¡é …</target>
695 <context-group name="null"> 713 <context-group name="null">
696 <context context-type="linenumber">44</context> 714 <context context-type="linenumber">39</context>
697 </context-group> 715 </context-group>
698 </trans-unit> 716 </trans-unit>
699 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 717 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
700 <source>User registration is allowed and</source> 718 <source>User registration is allowed and</source>
701 <target>ユーザー登録ãŒå¯èƒ½ã§ã™</target> 719 <target>ユーザー登録ãŒå¯èƒ½ã§ã™</target>
702 <context-group name="null"> 720 <context-group name="null">
703 <context context-type="linenumber">25</context> 721 <context context-type="linenumber">29</context>
704 </context-group>
705 </trans-unit>
706 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
707 <source>
708 User registration is currently not allowed.
709 </source>
710 <target>ユーザー登録ã¯ç¾åœ¨å—ã‘付ã‘ã¦ãŠã‚Šã¾ã›ã‚“</target>
711 <context-group name="null">
712 <context context-type="linenumber">36</context>
713 </context-group> 722 </context-group>
714 </trans-unit> 723 </trans-unit>
715 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 724 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -762,14 +771,14 @@
762 <source>Short description</source> 771 <source>Short description</source>
763 <target>ç°¡å˜ãªèª¬æ˜Ž</target> 772 <target>ç°¡å˜ãªèª¬æ˜Ž</target>
764 <context-group name="null"> 773 <context-group name="null">
765 <context context-type="linenumber">22</context> 774 <context context-type="linenumber">21</context>
766 </context-group> 775 </context-group>
767 </trans-unit> 776 </trans-unit>
768 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 777 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
769 <source>Videos Overview</source> 778 <source>Videos Overview</source>
770 <target>ビデオã®æ¦‚è¦</target> 779 <target>ビデオã®æ¦‚è¦</target>
771 <context-group name="null"> 780 <context-group name="null">
772 <context context-type="linenumber">58</context> 781 <context context-type="linenumber">51</context>
773 </context-group> 782 </context-group>
774 </trans-unit> 783 </trans-unit>
775 <trans-unit id="aaa900149c2ca1575ac1918d1ded33fb69830ab2"> 784 <trans-unit id="aaa900149c2ca1575ac1918d1ded33fb69830ab2">
@@ -790,20 +799,27 @@
790 <source>Signup enabled</source> 799 <source>Signup enabled</source>
791 <target>サインアップãŒæœ‰åŠ¹</target> 800 <target>サインアップãŒæœ‰åŠ¹</target>
792 <context-group name="null"> 801 <context-group name="null">
793 <context context-type="linenumber">93</context> 802 <context context-type="linenumber">84</context>
794 </context-group> 803 </context-group>
795 </trans-unit> 804 </trans-unit>
796 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 805 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
797 <source>Signup requires email verification</source> 806 <source>Signup requires email verification</source>
798 <target>サインアップã«ã¯é›»å­ãƒ¡ãƒ¼ãƒ«ã®ç¢ºèªãŒå¿…è¦ã§ã™</target> 807 <target>サインアップã«ã¯é›»å­ãƒ¡ãƒ¼ãƒ«ã®ç¢ºèªãŒå¿…è¦ã§ã™</target>
799 <context-group name="null"> 808 <context-group name="null">
800 <context context-type="linenumber">100</context> 809 <context context-type="linenumber">91</context>
801 </context-group> 810 </context-group>
802 </trans-unit> 811 </trans-unit>
803 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 812 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
804 <source>Signup limit</source> 813 <source>Signup limit</source>
805 <target>サインアップã®åˆ¶é™</target> 814 <target>サインアップã®åˆ¶é™</target>
806 <context-group name="null"> 815 <context-group name="null">
816 <context context-type="linenumber">96</context>
817 </context-group>
818 </trans-unit>
819 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
820 <source>Users</source>
821 <target>ユーザー</target>
822 <context-group name="null">
807 <context context-type="linenumber">105</context> 823 <context context-type="linenumber">105</context>
808 </context-group> 824 </context-group>
809 </trans-unit> 825 </trans-unit>
@@ -818,28 +834,21 @@
818 <source>Video import with a torrent file or a magnet URI enabled</source> 834 <source>Video import with a torrent file or a magnet URI enabled</source>
819 <target>Torrent ファイル ã¾ãŸã¯ magnet リンクを使用ã—ã¦å‹•ç”»ã‚’インãƒãƒ¼ãƒˆã™ã‚‹</target> 835 <target>Torrent ファイル ã¾ãŸã¯ magnet リンクを使用ã—ã¦å‹•ç”»ã‚’インãƒãƒ¼ãƒˆã™ã‚‹</target>
820 <context-group name="null"> 836 <context-group name="null">
821 <context context-type="linenumber">127</context> 837 <context context-type="linenumber">148</context>
822 </context-group> 838 </context-group>
823 </trans-unit> 839 </trans-unit>
824 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 840 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
825 <source>Administrator</source> 841 <source>Administrator</source>
826 <target>管ç†è€…</target> 842 <target>管ç†è€…</target>
827 <context-group name="null"> 843 <context-group name="null">
828 <context context-type="linenumber">131</context> 844 <context context-type="linenumber">155</context>
829 </context-group> 845 </context-group>
830 </trans-unit> 846 </trans-unit>
831 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 847 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
832 <source>Admin email</source> 848 <source>Admin email</source>
833 <target>管ç†è€…ã®é›»å­ãƒ¡ãƒ¼ãƒ«</target> 849 <target>管ç†è€…ã®é›»å­ãƒ¡ãƒ¼ãƒ«</target>
834 <context-group name="null"> 850 <context-group name="null">
835 <context context-type="linenumber">134</context> 851 <context context-type="linenumber">158</context>
836 </context-group>
837 </trans-unit>
838 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
839 <source>Users</source>
840 <target>ユーザー</target>
841 <context-group name="null">
842 <context context-type="linenumber">144</context>
843 </context-group> 852 </context-group>
844 </trans-unit> 853 </trans-unit>
845 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 854 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -860,7 +869,7 @@
860 <source>Your Twitter username</source> 869 <source>Your Twitter username</source>
861 <target>ã‚ãªãŸã®Twitterユーザーå</target> 870 <target>ã‚ãªãŸã®Twitterユーザーå</target>
862 <context-group name="null"> 871 <context-group name="null">
863 <context context-type="linenumber">181</context> 872 <context context-type="linenumber">184</context>
864 </context-group> 873 </context-group>
865 </trans-unit> 874 </trans-unit>
866 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 875 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -874,47 +883,47 @@
874 <source>Transcoding</source> 883 <source>Transcoding</source>
875 <target>トランスコード</target> 884 <target>トランスコード</target>
876 <context-group name="null"> 885 <context-group name="null">
877 <context context-type="linenumber">210</context> 886 <context context-type="linenumber">215</context>
878 </context-group> 887 </context-group>
879 </trans-unit> 888 </trans-unit>
880 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 889 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
881 <source>Transcoding enabled</source> 890 <source>Transcoding enabled</source>
882 <target>トランスコードãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã™</target> 891 <target>トランスコードãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã™</target>
883 <context-group name="null"> 892 <context-group name="null">
884 <context context-type="linenumber">215</context> 893 <context context-type="linenumber">221</context>
885 </context-group> 894 </context-group>
886 </trans-unit> 895 </trans-unit>
887 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 896 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
888 <source>Transcoding threads</source><target>Transcoding threads</target><context-group name="null"> 897 <source>Transcoding threads</source><target>Transcoding threads</target><context-group name="null">
889 <context context-type="linenumber">223</context> 898 <context context-type="linenumber">237</context>
890 </context-group> 899 </context-group>
891 </trans-unit> 900 </trans-unit>
892 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 901 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
893 <source>Customizations</source> 902 <source>Customizations</source>
894 <target>カスタマイズ</target> 903 <target>カスタマイズ</target>
895 <context-group name="null"> 904 <context-group name="null">
896 <context context-type="linenumber">275</context> 905 <context context-type="linenumber">289</context>
897 </context-group> 906 </context-group>
898 </trans-unit> 907 </trans-unit>
899 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 908 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
900 <source>JavaScript</source> 909 <source>JavaScript</source>
901 <target>JavaScript</target> 910 <target>JavaScript</target>
902 <context-group name="null"> 911 <context-group name="null">
903 <context context-type="linenumber">278</context> 912 <context context-type="linenumber">294</context>
904 </context-group> 913 </context-group>
905 </trans-unit> 914 </trans-unit>
906 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab"> 915 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab">
907 <source>Advanced configuration</source> 916 <source>Advanced configuration</source>
908 <target>高度ãªæ§‹æˆ</target> 917 <target>高度ãªæ§‹æˆ</target>
909 <context-group name="null"> 918 <context-group name="null">
910 <context context-type="linenumber">207</context> 919 <context context-type="linenumber">212</context>
911 </context-group> 920 </context-group>
912 </trans-unit> 921 </trans-unit>
913 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 922 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
914 <source>Update configuration</source> 923 <source>Update configuration</source>
915 <target>設定を更新ã™ã‚‹</target> 924 <target>設定を更新ã™ã‚‹</target>
916 <context-group name="null"> 925 <context-group name="null">
917 <context context-type="linenumber">325</context> 926 <context context-type="linenumber">340</context>
918 </context-group> 927 </context-group>
919 </trans-unit> 928 </trans-unit>
920 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 929 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1037,7 +1046,7 @@
1037 <source>Ban reason:</source> 1046 <source>Ban reason:</source>
1038 <target>ç¦æ­¢ç†ç”±ï¼š</target> 1047 <target>ç¦æ­¢ç†ç”±ï¼š</target>
1039 <context-group name="null"> 1048 <context-group name="null">
1040 <context context-type="linenumber">92</context> 1049 <context context-type="linenumber">95</context>
1041 </context-group> 1050 </context-group>
1042 </trans-unit> 1051 </trans-unit>
1043 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 1052 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -1086,7 +1095,7 @@
1086 <source>Actions</source> 1095 <source>Actions</source>
1087 <target>行動</target> 1096 <target>行動</target>
1088 <context-group name="null"> 1097 <context-group name="null">
1089 <context context-type="linenumber">33</context> 1098 <context context-type="linenumber">35</context>
1090 </context-group> 1099 </context-group>
1091 </trans-unit> 1100 </trans-unit>
1092 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 1101 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -1110,46 +1119,25 @@
1110 <context context-type="linenumber">2</context> 1119 <context context-type="linenumber">2</context>
1111 </context-group> 1120 </context-group>
1112 </trans-unit> 1121 </trans-unit>
1113 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
1114 <source>My subscriptions</source>
1115 <target>ç§ã®è¼¸å…¥å“</target>
1116 <context-group name="null">
1117 <context context-type="linenumber">16</context>
1118 </context-group>
1119 </trans-unit>
1120 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
1121 <source>My imports</source>
1122 <target>ç§ã®è³¼èª­</target>
1123 <context-group name="null">
1124 <context context-type="linenumber">18</context>
1125 </context-group>
1126 </trans-unit>
1127 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
1128 <source>Ownership changes</source>
1129 <target>所有権ã®å¤‰æ›´</target>
1130 <context-group name="null">
1131 <context context-type="linenumber">33</context>
1132 </context-group>
1133 </trans-unit>
1134 <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8"> 1122 <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8">
1135 <source>Profile</source> 1123 <source>Profile</source>
1136 <target>プロフィール</target> 1124 <target>プロフィール</target>
1137 <context-group name="null"> 1125 <context-group name="null">
1138 <context context-type="linenumber">8</context> 1126 <context context-type="linenumber">7</context>
1139 </context-group> 1127 </context-group>
1140 </trans-unit> 1128 </trans-unit>
1141 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 1129 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
1142 <source>Video settings</source> 1130 <source>Video settings</source>
1143 <target>ビデオ設定</target> 1131 <target>ビデオ設定</target>
1144 <context-group name="null"> 1132 <context-group name="null">
1145 <context context-type="linenumber">15</context> 1133 <context context-type="linenumber">16</context>
1146 </context-group> 1134 </context-group>
1147 </trans-unit> 1135 </trans-unit>
1148 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 1136 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
1149 <source>Danger zone</source> 1137 <source>Danger zone</source>
1150 <target>å±é™ºåŒºåŸŸ</target> 1138 <target>å±é™ºåŒºåŸŸ</target>
1151 <context-group name="null"> 1139 <context-group name="null">
1152 <context context-type="linenumber">18</context> 1140 <context context-type="linenumber">19</context>
1153 </context-group> 1141 </context-group>
1154 </trans-unit> 1142 </trans-unit>
1155 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 1143 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -1159,13 +1147,6 @@
1159 <context context-type="linenumber">46</context> 1147 <context context-type="linenumber">46</context>
1160 </context-group> 1148 </context-group>
1161 </trans-unit> 1149 </trans-unit>
1162 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
1163 <source>Submit</source>
1164 <target>å·®ã—出ã™</target>
1165 <context-group name="null">
1166 <context context-type="linenumber">24</context>
1167 </context-group>
1168 </trans-unit>
1169 <trans-unit id="17a9d3860d9ad593dd09a9f934e03999d9e76a7a"> 1150 <trans-unit id="17a9d3860d9ad593dd09a9f934e03999d9e76a7a">
1170 <source> 1151 <source>
1171 Cancel 1152 Cancel
@@ -1307,7 +1288,7 @@
1307 <source>Publish</source> 1288 <source>Publish</source>
1308 <target>出ã™</target> 1289 <target>出ã™</target>
1309 <context-group name="null"> 1290 <context-group name="null">
1310 <context context-type="linenumber">60</context> 1291 <context context-type="linenumber">65</context>
1311 </context-group> 1292 </context-group>
1312 </trans-unit> 1293 </trans-unit>
1313 <trans-unit id="0d6558176587662e9bb3b79cca57d42591cf82f9"> 1294 <trans-unit id="0d6558176587662e9bb3b79cca57d42591cf82f9">
@@ -1384,17 +1365,6 @@
1384 <context context-type="linenumber">3</context> 1365 <context context-type="linenumber">3</context>
1385 </context-group> 1366 </context-group>
1386 </trans-unit> 1367 </trans-unit>
1387 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
1388 <source>
1389 Cancel
1390 </source>
1391 <target>
1392 キャンセル
1393 </target>
1394 <context-group name="null">
1395 <context context-type="linenumber">19</context>
1396 </context-group>
1397 </trans-unit>
1398 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 1368 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
1399 <source>Share</source> 1369 <source>Share</source>
1400 <target>シェア</target> 1370 <target>シェア</target>
@@ -1573,13 +1543,6 @@
1573 <context context-type="linenumber">14</context> 1543 <context context-type="linenumber">14</context>
1574 </context-group> 1544 </context-group>
1575 </trans-unit> 1545 </trans-unit>
1576 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
1577 <source>Error getting about from server</source>
1578 <target>サーãƒãƒ¼ã‹ã‚‰ã®ã‚¨ãƒ©ãƒ¼</target>
1579 <context-group name="null">
1580 <context context-type="linenumber">1</context>
1581 </context-group>
1582 </trans-unit>
1583 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 1546 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
1584 <source>No description</source> 1547 <source>No description</source>
1585 <target>説明ã¯ã‚ã‚Šã¾ã›ã‚“</target> 1548 <target>説明ã¯ã‚ã‚Šã¾ã›ã‚“</target>
@@ -1594,20 +1557,6 @@
1594 <context context-type="linenumber">1</context> 1557 <context context-type="linenumber">1</context>
1595 </context-group> 1558 </context-group>
1596 </trans-unit> 1559 </trans-unit>
1597 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
1598 <source>Error</source>
1599 <target>エラー</target>
1600 <context-group name="null">
1601 <context context-type="linenumber">1</context>
1602 </context-group>
1603 </trans-unit>
1604 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
1605 <source>Success</source>
1606 <target>æˆåŠŸ</target>
1607 <context-group name="null">
1608 <context context-type="linenumber">1</context>
1609 </context-group>
1610 </trans-unit>
1611 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 1560 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
1612 <source>Configuration updated.</source> 1561 <source>Configuration updated.</source>
1613 <target>構æˆãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚</target> 1562 <target>構æˆãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚</target>
@@ -1690,9 +1639,16 @@
1690 <context context-type="linenumber">1</context> 1639 <context context-type="linenumber">1</context>
1691 </context-group> 1640 </context-group>
1692 </trans-unit> 1641 </trans-unit>
1693 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 1642 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
1694 <source>Channels</source> 1643 <source>My subscriptions</source>
1695 <target>ãƒãƒ£ãƒ³ãƒãƒ«</target> 1644 <target>ç§ã®è¼¸å…¥å“</target>
1645 <context-group name="null">
1646 <context context-type="linenumber">1</context>
1647 </context-group>
1648 </trans-unit>
1649 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
1650 <source>Ownership changes</source>
1651 <target>所有権ã®å¤‰æ›´</target>
1696 <context-group name="null"> 1652 <context-group name="null">
1697 <context context-type="linenumber">1</context> 1653 <context context-type="linenumber">1</context>
1698 </context-group> 1654 </context-group>
@@ -1712,6 +1668,13 @@
1712 <context context-type="linenumber">1</context> 1668 <context context-type="linenumber">1</context>
1713 </context-group> 1669 </context-group>
1714 </trans-unit> 1670 </trans-unit>
1671 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
1672 <source>Error</source>
1673 <target>エラー</target>
1674 <context-group name="null">
1675 <context context-type="linenumber">1</context>
1676 </context-group>
1677 </trans-unit>
1715 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 1678 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
1716 <source>You need to reconnect.</source> 1679 <source>You need to reconnect.</source>
1717 <target>å†æŽ¥ç¶šã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</target> 1680 <target>å†æŽ¥ç¶šã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</target>
@@ -1726,6 +1689,20 @@
1726 <context context-type="linenumber">1</context> 1689 <context context-type="linenumber">1</context>
1727 </context-group> 1690 </context-group>
1728 </trans-unit> 1691 </trans-unit>
1692 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
1693 <source>Info</source>
1694 <target>情報</target>
1695 <context-group name="null">
1696 <context context-type="linenumber">1</context>
1697 </context-group>
1698 </trans-unit>
1699 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
1700 <source>Success</source>
1701 <target>æˆåŠŸ</target>
1702 <context-group name="null">
1703 <context context-type="linenumber">1</context>
1704 </context-group>
1705 </trans-unit>
1729 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 1706 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
1730 <source>Incorrect username or password.</source> 1707 <source>Incorrect username or password.</source>
1731 <target>ユーザーãƒãƒ¼ãƒ ã¾ãŸã¯ãƒ‘スワードãŒé•ã„ã¾ã™ã€‚</target> 1708 <target>ユーザーãƒãƒ¼ãƒ ã¾ãŸã¯ãƒ‘スワードãŒé•ã„ã¾ã™ã€‚</target>
@@ -1796,6 +1773,20 @@
1796 <context context-type="linenumber">1</context> 1773 <context context-type="linenumber">1</context>
1797 </context-group> 1774 </context-group>
1798 </trans-unit> 1775 </trans-unit>
1776 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
1777 <source>Email is required.</source>
1778 <target>é›»å­ãƒ¡ãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚</target>
1779 <context-group name="null">
1780 <context context-type="linenumber">1</context>
1781 </context-group>
1782 </trans-unit>
1783 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
1784 <source>Email must be valid.</source>
1785 <target>é›»å­ãƒ¡ãƒ¼ãƒ«ã¯æœ‰åŠ¹ã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</target>
1786 <context-group name="null">
1787 <context context-type="linenumber">1</context>
1788 </context-group>
1789 </trans-unit>
1799 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 1790 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
1800 <source>Username is required.</source> 1791 <source>Username is required.</source>
1801 <target>ユーザーåã¯å¿…é ˆã§ã™ã€‚</target> 1792 <target>ユーザーåã¯å¿…é ˆã§ã™ã€‚</target>
@@ -1817,41 +1808,6 @@
1817 <context context-type="linenumber">1</context> 1808 <context context-type="linenumber">1</context>
1818 </context-group> 1809 </context-group>
1819 </trans-unit> 1810 </trans-unit>
1820 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
1821 <source>Username must be at least 3 characters long.</source>
1822 <target>ユーザーåã¯3文字以上ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。</target>
1823 <context-group name="null">
1824 <context context-type="linenumber">1</context>
1825 </context-group>
1826 </trans-unit>
1827 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
1828 <source>Username cannot be more than 20 characters long.</source>
1829 <target>ユーザーåã®é•·ã•ã¯20文字を超ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。</target>
1830 <context-group name="null">
1831 <context context-type="linenumber">1</context>
1832 </context-group>
1833 </trans-unit>
1834 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
1835 <source>Username should be only lowercase alphanumeric characters.</source>
1836 <target>ユーザーåã¯å°æ–‡å­—ã®è‹±æ•°å­—ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。</target>
1837 <context-group name="null">
1838 <context context-type="linenumber">1</context>
1839 </context-group>
1840 </trans-unit>
1841 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
1842 <source>Email is required.</source>
1843 <target>é›»å­ãƒ¡ãƒ¼ãƒ«ãŒå¿…è¦ã§ã™ã€‚</target>
1844 <context-group name="null">
1845 <context context-type="linenumber">1</context>
1846 </context-group>
1847 </trans-unit>
1848 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
1849 <source>Email must be valid.</source>
1850 <target>é›»å­ãƒ¡ãƒ¼ãƒ«ã¯æœ‰åŠ¹ã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</target>
1851 <context-group name="null">
1852 <context context-type="linenumber">1</context>
1853 </context-group>
1854 </trans-unit>
1855 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 1811 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
1856 <source>Password must be at least 6 characters long.</source> 1812 <source>Password must be at least 6 characters long.</source>
1857 <target>パスワードã¯6文字以上ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。</target> 1813 <target>パスワードã¯6文字以上ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。</target>
@@ -2419,16 +2375,16 @@
2419 <context context-type="linenumber">1</context> 2375 <context context-type="linenumber">1</context>
2420 </context-group> 2376 </context-group>
2421 </trans-unit> 2377 </trans-unit>
2422 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1"> 2378 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
2423 <source>Subscribed</source> 2379 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
2424 <target>購読ã™ã‚</target> 2380 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> ã®ç»éŒ²ãŒå®Œäº†ã—ã¾ã—ãŸã€‚</target>
2425 <context-group name="null"> 2381 <context-group name="null">
2426 <context context-type="linenumber">1</context> 2382 <context context-type="linenumber">1</context>
2427 </context-group> 2383 </context-group>
2428 </trans-unit> 2384 </trans-unit>
2429 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded"> 2385 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
2430 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source> 2386 <source>Subscribed</source>
2431 <target><x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> ã®ç»éŒ²ãŒå®Œäº†ã—ã¾ã—ãŸã€‚</target> 2387 <target>購読ã™ã‚</target>
2432 <context-group name="null"> 2388 <context-group name="null">
2433 <context context-type="linenumber">1</context> 2389 <context context-type="linenumber">1</context>
2434 </context-group> 2390 </context-group>
@@ -2461,13 +2417,6 @@
2461 <context context-type="linenumber">1</context> 2417 <context context-type="linenumber">1</context>
2462 </context-group> 2418 </context-group>
2463 </trans-unit> 2419 </trans-unit>
2464 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
2465 <source>Info</source>
2466 <target>情報</target>
2467 <context-group name="null">
2468 <context context-type="linenumber">1</context>
2469 </context-group>
2470 </trans-unit>
2471 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 2420 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
2472 <source>Upload cancelled</source> 2421 <source>Upload cancelled</source>
2473 <target>アップロードã®ã‚­ãƒ£ãƒ³ã‚»ãƒ«</target> 2422 <target>アップロードã®ã‚­ãƒ£ãƒ³ã‚»ãƒ«</target>
@@ -2475,13 +2424,6 @@
2475 <context context-type="linenumber">1</context> 2424 <context context-type="linenumber">1</context>
2476 </context-group> 2425 </context-group>
2477 </trans-unit> 2426 </trans-unit>
2478 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa">
2479 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
2480 <target>申ã—訳ã‚ã‚Šã¾ã›ã‚“ãŒã€PeerTube ã¯å‹•ç”»ã‚’処ç†å‡ºæ¥ã¾ã›ã‚“。 &gt; 8GB</target>
2481 <context-group name="null">
2482 <context context-type="linenumber">1</context>
2483 </context-group>
2484 </trans-unit>
2485 <trans-unit id="972fc644f847cf84e4732ec012915c4cdaf865ce"> 2427 <trans-unit id="972fc644f847cf84e4732ec012915c4cdaf865ce">
2486 <source>Video published.</source> 2428 <source>Video published.</source>
2487 <target>ビデオãŒå…¬é–‹ã•ã‚Œã¾ã—ãŸã€‚</target> 2429 <target>ビデオãŒå…¬é–‹ã•ã‚Œã¾ã—ãŸã€‚</target>
diff --git a/client/src/locale/target/angular_jbo.xml b/client/src/locale/target/angular_jbo.xml
index 83e61a714..6478b002c 100644
--- a/client/src/locale/target/angular_jbo.xml
+++ b/client/src/locale/target/angular_jbo.xml
@@ -33,7 +33,7 @@
33 </trans-unit> 33 </trans-unit>
34 <trans-unit id="ngb.datepicker.next-month"> 34 <trans-unit id="ngb.datepicker.next-month">
35 <source>Next month</source> 35 <source>Next month</source>
36 <target>la bavla'ima'i</target> 36 <target>lo bavla'ima'i</target>
37 <context-group name="null"> 37 <context-group name="null">
38 <context context-type="linenumber">27</context> 38 <context context-type="linenumber">27</context>
39 </context-group> 39 </context-group>
@@ -53,9 +53,7 @@
53 </context-group> 53 </context-group>
54 </trans-unit> 54 </trans-unit>
55 <trans-unit id="ngb.pagination.first"> 55 <trans-unit id="ngb.pagination.first">
56 <source>««</source> 56 <source>««</source><target>««</target><context-group name="null">
57 <target>««</target>
58 <context-group name="null">
59 <context context-type="linenumber">7</context> 57 <context context-type="linenumber">7</context>
60 </context-group> 58 </context-group>
61 </trans-unit> 59 </trans-unit>
@@ -67,9 +65,7 @@
67 </context-group> 65 </context-group>
68 </trans-unit> 66 </trans-unit>
69 <trans-unit id="ngb.pagination.previous"> 67 <trans-unit id="ngb.pagination.previous">
70 <source>«</source> 68 <source>«</source><target>«</target><context-group name="null">
71 <target>«</target>
72 <context-group name="null">
73 <context context-type="linenumber">15</context> 69 <context context-type="linenumber">15</context>
74 </context-group> 70 </context-group>
75 </trans-unit> 71 </trans-unit>
@@ -81,9 +77,7 @@
81 </context-group> 77 </context-group>
82 </trans-unit> 78 </trans-unit>
83 <trans-unit id="ngb.pagination.next"> 79 <trans-unit id="ngb.pagination.next">
84 <source>»</source> 80 <source>»</source><target>»</target><context-group name="null">
85 <target>»</target>
86 <context-group name="null">
87 <context context-type="linenumber">29</context> 81 <context context-type="linenumber">29</context>
88 </context-group> 82 </context-group>
89 </trans-unit> 83 </trans-unit>
@@ -95,9 +89,7 @@
95 </context-group> 89 </context-group>
96 </trans-unit> 90 </trans-unit>
97 <trans-unit id="ngb.pagination.last"> 91 <trans-unit id="ngb.pagination.last">
98 <source>»»</source> 92 <source>»»</source><target>»»</target><context-group name="null">
99 <target>»»</target>
100 <context-group name="null">
101 <context context-type="linenumber">36</context> 93 <context context-type="linenumber">36</context>
102 </context-group> 94 </context-group>
103 </trans-unit> 95 </trans-unit>
@@ -237,6 +229,48 @@ sisti lo nu jersi pe'a</target>
237 <context context-type="linenumber">13</context> 229 <context context-type="linenumber">13</context>
238 </context-group> 230 </context-group>
239 </trans-unit> 231 </trans-unit>
232 <trans-unit id="76e1f485e6ead4c84b606f46d413878881d66ad3">
233 <source>User registration is not allowed on this instance, but you can register on many others!</source>
234 <target>.i le samtcise'u cu curmi no nu cmiveigau .i ku'i do cmeveigau fo so'i drata ka'e</target>
235 <context-group name="null">
236 <context context-type="linenumber">28</context>
237 </context-group>
238 </trans-unit>
239 <trans-unit id="c32ef07f8803a223a83ed17024b38e8d82292407">
240 <source>Password</source>
241 <target>lo lerpoijaspu</target>
242 <context-group name="null">
243 <context context-type="linenumber">13</context>
244 </context-group>
245 </trans-unit>
246 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
247 <source>I forgot my password</source>
248 <target>.i mi nalmo'i le mi lerpoijaspu</target>
249 <context-group name="null">
250 <context context-type="linenumber">44</context>
251 </context-group>
252 </trans-unit>
253 <trans-unit id="6765b4c916060f6bc42d9bb69e80377dbcb5e4e9">
254 <source>Login</source>
255 <target>co'a cmisau</target>
256 <context-group name="null">
257 <context context-type="linenumber">36</context>
258 </context-group>
259 </trans-unit>
260 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
261 <source>Forgot your password</source>
262 <target>.i mi nalmo'i le mi lerpoijaspu</target>
263 <context-group name="null">
264 <context context-type="linenumber">57</context>
265 </context-group>
266 </trans-unit>
267 <trans-unit id="244aae9346da82b0922506c2d2581373a15641cc">
268 <source>Email</source>
269 <target>lo ve samymri</target>
270 <context-group name="null">
271 <context context-type="linenumber">8</context>
272 </context-group>
273 </trans-unit>
240 <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529"> 274 <trans-unit id="69b6ac577a19acc39fc0c22342092f327fff2529">
241 <source>Email address</source> 275 <source>Email address</source>
242 <target>lo ve samymri</target> 276 <target>lo ve samymri</target>
@@ -248,7 +282,7 @@ sisti lo nu jersi pe'a</target>
248 <source>Send me an email to reset my password</source> 282 <source>Send me an email to reset my password</source>
249 <target>samymri fi mi te zu'e lo nu galfi le mi japyvla</target> 283 <target>samymri fi mi te zu'e lo nu galfi le mi japyvla</target>
250 <context-group name="null"> 284 <context-group name="null">
251 <context context-type="linenumber">75</context> 285 <context context-type="linenumber">80</context>
252 </context-group> 286 </context-group>
253 </trans-unit> 287 </trans-unit>
254 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 288 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -299,6 +333,13 @@ zbasu lo pilno</target>
299 <context context-type="linenumber">55</context> 333 <context context-type="linenumber">55</context>
300 </context-group> 334 </context-group>
301 </trans-unit> 335 </trans-unit>
336 <trans-unit id="717a5e3574fec754fbeb348c2d5561c4d81facc4">
337 <source>Signup</source>
338 <target>cmiveigau</target>
339 <context-group name="null">
340 <context context-type="linenumber">78</context>
341 </context-group>
342 </trans-unit>
302 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a"> 343 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a">
303 <source><x id="INTERPOLATION" equiv-text="{{ pagination.totalItems | myNumberFormatter }}"/> results</source> 344 <source><x id="INTERPOLATION" equiv-text="{{ pagination.totalItems | myNumberFormatter }}"/> results</source>
304 <target><x id="INTERPOLATION" equiv-text="{{ pagination.totalItems | myNumberFormatter }}"/> lo te facki</target> 345 <target><x id="INTERPOLATION" equiv-text="{{ pagination.totalItems | myNumberFormatter }}"/> lo te facki</target>
@@ -327,7 +368,7 @@ zbasu lo pilno</target>
327 <source>Change the language</source> 368 <source>Change the language</source>
328 <target>galfi lo bangu</target> 369 <target>galfi lo bangu</target>
329 <context-group name="null"> 370 <context-group name="null">
330 <context context-type="linenumber">88</context> 371 <context context-type="linenumber">86</context>
331 </context-group> 372 </context-group>
332 </trans-unit> 373 </trans-unit>
333 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 374 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -337,7 +378,7 @@ zbasu lo pilno</target>
337 <target> 378 <target>
338lo predatni be mi be'o poi gubni</target> 379lo predatni be mi be'o poi gubni</target>
339 <context-group name="null"> 380 <context-group name="null">
340 <context context-type="linenumber">18</context> 381 <context context-type="linenumber">16</context>
341 </context-group> 382 </context-group>
342 </trans-unit> 383 </trans-unit>
343 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 384 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -347,7 +388,7 @@ lo predatni be mi be'o poi gubni</target>
347 <target> 388 <target>
348lo mi pilno</target> 389lo mi pilno</target>
349 <context-group name="null"> 390 <context-group name="null">
350 <context context-type="linenumber">22</context> 391 <context context-type="linenumber">20</context>
351 </context-group> 392 </context-group>
352 </trans-unit> 393 </trans-unit>
353 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 394 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -357,14 +398,14 @@ lo mi pilno</target>
357 <target> 398 <target>
358lo mi vidvi</target> 399lo mi vidvi</target>
359 <context-group name="null"> 400 <context-group name="null">
360 <context context-type="linenumber">26</context> 401 <context context-type="linenumber">24</context>
361 </context-group> 402 </context-group>
362 </trans-unit> 403 </trans-unit>
363 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 404 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
364 <source>Create an account</source> 405 <source>Create an account</source>
365 <target>zbasu lo pilno</target> 406 <target>zbasu lo pilno</target>
366 <context-group name="null"> 407 <context-group name="null">
367 <context context-type="linenumber">39</context> 408 <context context-type="linenumber">37</context>
368 </context-group> 409 </context-group>
369 </trans-unit> 410 </trans-unit>
370 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 411 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -378,28 +419,28 @@ lo mi vidvi</target>
378 <source>Subscriptions</source> 419 <source>Subscriptions</source>
379 <target>lo se jersi pe'a</target> 420 <target>lo se jersi pe'a</target>
380 <context-group name="null"> 421 <context-group name="null">
381 <context context-type="linenumber">47</context> 422 <context context-type="linenumber">45</context>
382 </context-group> 423 </context-group>
383 </trans-unit> 424 </trans-unit>
384 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 425 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
385 <source>Trending</source> 426 <source>Trending</source>
386 <target>lo cabna misno</target> 427 <target>lo cabna misno</target>
387 <context-group name="null"> 428 <context-group name="null">
388 <context context-type="linenumber">57</context> 429 <context context-type="linenumber">55</context>
389 </context-group> 430 </context-group>
390 </trans-unit> 431 </trans-unit>
391 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 432 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
392 <source>Local</source> 433 <source>Local</source>
393 <target>lo diklo</target> 434 <target>lo diklo</target>
394 <context-group name="null"> 435 <context-group name="null">
395 <context context-type="linenumber">67</context> 436 <context context-type="linenumber">65</context>
396 </context-group> 437 </context-group>
397 </trans-unit> 438 </trans-unit>
398 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 439 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
399 <source>More</source> 440 <source>More</source>
400 <target>lo drata</target> 441 <target>lo drata</target>
401 <context-group name="null"> 442 <context-group name="null">
402 <context context-type="linenumber">72</context> 443 <context context-type="linenumber">70</context>
403 </context-group> 444 </context-group>
404 </trans-unit> 445 </trans-unit>
405 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 446 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -476,7 +517,7 @@ lo mi vidvi</target>
476 <source>No results.</source> 517 <source>No results.</source>
477 <target>.i facki fi no da</target> 518 <target>.i facki fi no da</target>
478 <context-group name="null"> 519 <context-group name="null">
479 <context context-type="linenumber">17</context> 520 <context context-type="linenumber">20</context>
480 </context-group> 521 </context-group>
481 </trans-unit> 522 </trans-unit>
482 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b"> 523 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b">
@@ -498,26 +539,6 @@ lo mi vidvi</target>
498 <context context-type="linenumber">27</context> 539 <context context-type="linenumber">27</context>
499 </context-group> 540 </context-group>
500 </trans-unit> 541 </trans-unit>
501 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
502 <source>
503 this instance provides unlimited space for the videos of its users.
504 </source>
505 <target>
506 .i le vi samtcise'u cu sabji lo na'e se jimte ke vidvi datni canlu lo pilno be sy.</target>
507 <context-group name="null">
508 <context context-type="linenumber">31</context>
509 </context-group>
510 </trans-unit>
511 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
512 <source>
513 User registration is currently not allowed.
514 </source>
515 <target>
516 .i ca na'e curmi lo nu zbasu lo pilno</target>
517 <context-group name="null">
518 <context context-type="linenumber">36</context>
519 </context-group>
520 </trans-unit>
521 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 542 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
522 <source> 543 <source>
523 About PeerTube 544 About PeerTube
@@ -638,28 +659,28 @@ lo mi vidvi</target>
638 <source>Short description</source> 659 <source>Short description</source>
639 <target>lo cmalu ve skicu</target> 660 <target>lo cmalu ve skicu</target>
640 <context-group name="null"> 661 <context-group name="null">
641 <context context-type="linenumber">22</context> 662 <context context-type="linenumber">21</context>
642 </context-group> 663 </context-group>
643 </trans-unit> 664 </trans-unit>
644 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 665 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
645 <source>Local videos</source> 666 <source>Local videos</source>
646 <target>lo diklo vidvi</target> 667 <target>lo diklo vidvi</target>
647 <context-group name="null"> 668 <context-group name="null">
648 <context context-type="linenumber">61</context> 669 <context context-type="linenumber">54</context>
649 </context-group> 670 </context-group>
650 </trans-unit> 671 </trans-unit>
651 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 672 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
652 <source>Policy on videos containing sensitive content</source> 673 <source>Policy on videos containing sensitive content</source>
653 <target>loi javni be tu'a lo vidvi poi vasru lo ganvi poi te kajde</target> 674 <target>loi javni be tu'a lo vidvi poi vasru lo ganvi poi te kajde</target>
654 <context-group name="null"> 675 <context-group name="null">
655 <context context-type="linenumber">70</context> 676 <context context-type="linenumber">61</context>
656 </context-group> 677 </context-group>
657 </trans-unit> 678 </trans-unit>
658 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 679 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
659 <source>JavaScript</source> 680 <source>JavaScript</source>
660 <target>la .djavascript.</target> 681 <target>la .djavascript.</target>
661 <context-group name="null"> 682 <context-group name="null">
662 <context context-type="linenumber">278</context> 683 <context context-type="linenumber">294</context>
663 </context-group> 684 </context-group>
664 </trans-unit> 685 </trans-unit>
665 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 686 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -686,53 +707,18 @@ lo pilno</target>
686 <context context-type="linenumber">12</context> 707 <context context-type="linenumber">12</context>
687 </context-group> 708 </context-group>
688 </trans-unit> 709 </trans-unit>
689 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
690 <source>My settings</source>
691 <target>lo mi se cuxna</target>
692 <context-group name="null">
693 <context context-type="linenumber">3</context>
694 </context-group>
695 </trans-unit>
696 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
697 <source>My channels</source>
698 <target>lo mi te tivni</target>
699 <context-group name="null">
700 <context context-type="linenumber">12</context>
701 </context-group>
702 </trans-unit>
703 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
704 <source>My videos</source>
705 <target>lo mi vidvi</target>
706 <context-group name="null">
707 <context context-type="linenumber">14</context>
708 </context-group>
709 </trans-unit>
710 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
711 <source>My subscriptions</source>
712 <target>lo se jersi pe'a be mi</target>
713 <context-group name="null">
714 <context context-type="linenumber">16</context>
715 </context-group>
716 </trans-unit>
717 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
718 <source>My imports</source>
719 <target>lo se nerbei be mi</target>
720 <context-group name="null">
721 <context context-type="linenumber">18</context>
722 </context-group>
723 </trans-unit>
724 <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8"> 710 <trans-unit id="994363f08f9fbfa3b3994ff7b35c6904fdff18d8">
725 <source>Profile</source> 711 <source>Profile</source>
726 <target>lo predatni</target> 712 <target>lo predatni</target>
727 <context-group name="null"> 713 <context-group name="null">
728 <context context-type="linenumber">8</context> 714 <context context-type="linenumber">7</context>
729 </context-group> 715 </context-group>
730 </trans-unit> 716 </trans-unit>
731 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 717 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
732 <source>Video settings</source> 718 <source>Video settings</source>
733 <target>lo se cuxna pe lo vidvi</target> 719 <target>lo se cuxna pe lo vidvi</target>
734 <context-group name="null"> 720 <context-group name="null">
735 <context context-type="linenumber">15</context> 721 <context context-type="linenumber">16</context>
736 </context-group> 722 </context-group>
737 </trans-unit> 723 </trans-unit>
738 <trans-unit id="73c1cefc348a6f361497210dea1ed79499fd1260"> 724 <trans-unit id="73c1cefc348a6f361497210dea1ed79499fd1260">
@@ -942,14 +928,14 @@ lo pilno</target>
942 <source>Cancel create</source> 928 <source>Cancel create</source>
943 <target>co'u zbasu</target> 929 <target>co'u zbasu</target>
944 <context-group name="null"> 930 <context-group name="null">
945 <context context-type="linenumber">169</context> 931 <context context-type="linenumber">170</context>
946 </context-group> 932 </context-group>
947 </trans-unit> 933 </trans-unit>
948 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 934 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
949 <source>Cancel deletion</source> 935 <source>Cancel deletion</source>
950 <target>co'u vimcu</target> 936 <target>co'u vimcu</target>
951 <context-group name="null"> 937 <context-group name="null">
952 <context context-type="linenumber">177</context> 938 <context context-type="linenumber">178</context>
953 </context-group> 939 </context-group>
954 </trans-unit> 940 </trans-unit>
955 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 941 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -963,7 +949,7 @@ lo pilno</target>
963 <source>Advanced settings</source> 949 <source>Advanced settings</source>
964 <target>lo certu se cuxna</target> 950 <target>lo certu se cuxna</target>
965 <context-group name="null"> 951 <context-group name="null">
966 <context context-type="linenumber">190</context> 952 <context context-type="linenumber">191</context>
967 </context-group> 953 </context-group>
968 </trans-unit> 954 </trans-unit>
969 <trans-unit id="9aafb2a928664aa7a9375fd37c533f0375f8b611"> 955 <trans-unit id="9aafb2a928664aa7a9375fd37c533f0375f8b611">
@@ -1104,13 +1090,6 @@ lo pilno</target>
1104 <context context-type="linenumber">14</context> 1090 <context context-type="linenumber">14</context>
1105 </context-group> 1091 </context-group>
1106 </trans-unit> 1092 </trans-unit>
1107 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
1108 <source>Error</source>
1109 <target>.i srera</target>
1110 <context-group name="null">
1111 <context context-type="linenumber">1</context>
1112 </context-group>
1113 </trans-unit>
1114 <trans-unit id="54adc67482fdaa0d361a2992bc91e064dc61cc9a"> 1093 <trans-unit id="54adc67482fdaa0d361a2992bc91e064dc61cc9a">
1115 <source>100MB</source> 1094 <source>100MB</source>
1116 <target>pa no no lo megbivysamsle</target> 1095 <target>pa no no lo megbivysamsle</target>
@@ -1195,6 +1174,27 @@ lo pilno</target>
1195 <context context-type="linenumber">1</context> 1174 <context context-type="linenumber">1</context>
1196 </context-group> 1175 </context-group>
1197 </trans-unit> 1176 </trans-unit>
1177 <trans-unit id="586bee8c27a761611eb05661524cc7ca944b5978">
1178 <source>Delete this report</source>
1179 <target>vimcu le notci</target>
1180 <context-group name="null">
1181 <context context-type="linenumber">1</context>
1182 </context-group>
1183 </trans-unit>
1184 <trans-unit id="73b70e37cddaa6494d8a666b6cba90dc80595599">
1185 <source>Do you really want to delete this abuse report?</source>
1186 <target>.i .au ju'o pei vimcu le malpli notci</target>
1187 <context-group name="null">
1188 <context context-type="linenumber">1</context>
1189 </context-group>
1190 </trans-unit>
1191 <trans-unit id="6a7938b8780c27540ea70cc0f8f4d928c8916cf9">
1192 <source>Abuse deleted.</source>
1193 <target>.i mo'u vimcu le malpli notci</target>
1194 <context-group name="null">
1195 <context context-type="linenumber">1</context>
1196 </context-group>
1197 </trans-unit>
1198 <trans-unit id="19508af0dfbc685cbf10cf02061bb5a0f423b6fc"> 1198 <trans-unit id="19508af0dfbc685cbf10cf02061bb5a0f423b6fc">
1199 <source>Password updated.</source> 1199 <source>Password updated.</source>
1200 <target>.i mo'u galfi lo japyvla</target> 1200 <target>.i mo'u galfi lo japyvla</target>
@@ -1237,23 +1237,30 @@ lo pilno</target>
1237 <context context-type="linenumber">1</context> 1237 <context context-type="linenumber">1</context>
1238 </context-group> 1238 </context-group>
1239 </trans-unit> 1239 </trans-unit>
1240 <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795"> 1240 <trans-unit id="3ef8bf973a9a481a08c6f0aaa875f0259b3ea645">
1241 <source>Create</source> 1241 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> created.</source>
1242 <target>zbasu</target> 1242 <target>.i mo'u zbasu la'o ly. <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> .ly. noi vidvi te tivni</target>
1243 <context-group name="null">
1244 <context context-type="linenumber">1</context>
1245 </context-group>
1246 </trans-unit>
1247 <trans-unit id="f359f6adf6cccca7770019f947ed594169ee7d47">
1248 <source>This name already exists on this instance.</source>
1249 <target>.i le cmene xa'o zasti ci'e le mupli</target>
1243 <context-group name="null"> 1250 <context-group name="null">
1244 <context context-type="linenumber">1</context> 1251 <context context-type="linenumber">1</context>
1245 </context-group> 1252 </context-group>
1246 </trans-unit> 1253 </trans-unit>
1247 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 1254 <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795">
1248 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 1255 <source>Create</source>
1249 <target>.i .au ju'o pei do vimcu la'o ly. <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> .ly. .i la'e di'u vimcu ro lo vidvi ji'a poi se kibdu'a fi le vi te tivni</target> 1256 <target>zbasu</target>
1250 <context-group name="null"> 1257 <context-group name="null">
1251 <context context-type="linenumber">1</context> 1258 <context context-type="linenumber">1</context>
1252 </context-group> 1259 </context-group>
1253 </trans-unit> 1260 </trans-unit>
1254 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e"> 1261 <trans-unit id="98ab64f0af924a60a48b40835c1b655bd17c6559">
1255 <source>Please type the name of the video channel to confirm</source> 1262 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> updated.</source>
1256 <target>.i .e'o ko ciska le cmene be le vidvi te zu'e lo nu birti</target> 1263 <target>.i mo'u galfi la'o ly. <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> .ly. noi vidvi te tivni</target>
1257 <context-group name="null"> 1264 <context-group name="null">
1258 <context context-type="linenumber">1</context> 1265 <context context-type="linenumber">1</context>
1259 </context-group> 1266 </context-group>
@@ -1265,6 +1272,13 @@ lo pilno</target>
1265 <context context-type="linenumber">1</context> 1272 <context context-type="linenumber">1</context>
1266 </context-group> 1273 </context-group>
1267 </trans-unit> 1274 </trans-unit>
1275 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
1276 <source>My videos</source>
1277 <target>lo mi vidvi</target>
1278 <context-group name="null">
1279 <context context-type="linenumber">1</context>
1280 </context-group>
1281 </trans-unit>
1268 <trans-unit id="00e16d1f1c5cc936ec0881cd02cbf66aa1b4cddd"> 1282 <trans-unit id="00e16d1f1c5cc936ec0881cd02cbf66aa1b4cddd">
1269 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{deleteLength}}"/> videos?</source> 1283 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{deleteLength}}"/> videos?</source>
1270 <target>.i .au ju'o pei do vimcu <x id="INTERPOLATION" equiv-text="{{deleteLength}}"/> lo vidvi</target> 1284 <target>.i .au ju'o pei do vimcu <x id="INTERPOLATION" equiv-text="{{deleteLength}}"/> lo vidvi</target>
@@ -1279,16 +1293,23 @@ lo pilno</target>
1279 <context context-type="linenumber">1</context> 1293 <context context-type="linenumber">1</context>
1280 </context-group> 1294 </context-group>
1281 </trans-unit> 1295 </trans-unit>
1282 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 1296 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
1283 <source>Channels</source> 1297 <source>My channels</source>
1284 <target>lo te tivni</target> 1298 <target>lo mi te tivni</target>
1285 <context-group name="null"> 1299 <context-group name="null">
1286 <context context-type="linenumber">1</context> 1300 <context context-type="linenumber">1</context>
1287 </context-group> 1301 </context-group>
1288 </trans-unit> 1302 </trans-unit>
1289 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d"> 1303 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
1290 <source>Video imports</source> 1304 <source>My subscriptions</source>
1291 <target>lo vidvi poi se nerbei</target> 1305 <target>lo se jersi pe'a be mi</target>
1306 <context-group name="null">
1307 <context context-type="linenumber">1</context>
1308 </context-group>
1309 </trans-unit>
1310 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
1311 <source>My settings</source>
1312 <target>lo mi se cuxna</target>
1292 <context-group name="null"> 1313 <context-group name="null">
1293 <context context-type="linenumber">1</context> 1314 <context context-type="linenumber">1</context>
1294 </context-group> 1315 </context-group>
@@ -1335,6 +1356,13 @@ lo pilno</target>
1335 <context context-type="linenumber">1</context> 1356 <context context-type="linenumber">1</context>
1336 </context-group> 1357 </context-group>
1337 </trans-unit> 1358 </trans-unit>
1359 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
1360 <source>Error</source>
1361 <target>.i srera</target>
1362 <context-group name="null">
1363 <context context-type="linenumber">1</context>
1364 </context-group>
1365 </trans-unit>
1338 <trans-unit id="b0f24b7136e551a0deba831f1525711245b31a26"> 1366 <trans-unit id="b0f24b7136e551a0deba831f1525711245b31a26">
1339 <source>Your password has been successfully reset!</source> 1367 <source>Your password has been successfully reset!</source>
1340 <target>.i snada lo nu mo'u galfi le do japyvla</target> 1368 <target>.i snada lo nu mo'u galfi le do japyvla</target>
@@ -1342,5 +1370,19 @@ lo pilno</target>
1342 <context context-type="linenumber">1</context> 1370 <context context-type="linenumber">1</context>
1343 </context-group> 1371 </context-group>
1344 </trans-unit> 1372 </trans-unit>
1373 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
1374 <source>The channel is required.</source>
1375 <target>.i le vidvi te tivni cu sarcu</target>
1376 <context-group name="null">
1377 <context context-type="linenumber">1</context>
1378 </context-group>
1379 </trans-unit>
1380 <trans-unit id="97afb789c1ab09074495d49aaadb92a1c3e71a16">
1381 <source>Video channel is required.</source>
1382 <target>.i le vidvi te tivni cu sarcu</target>
1383 <context-group name="null">
1384 <context context-type="linenumber">1</context>
1385 </context-group>
1386 </trans-unit>
1345 </body> 1387 </body>
1346 </file></xliff> \ No newline at end of file 1388 </file></xliff> \ No newline at end of file
diff --git a/client/src/locale/target/angular_nl_NL.xml b/client/src/locale/target/angular_nl_NL.xml
index 3db9f0504..7e7a6abdd 100644
--- a/client/src/locale/target/angular_nl_NL.xml
+++ b/client/src/locale/target/angular_nl_NL.xml
@@ -3,6 +3,244 @@
3<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" xmlns:xyz="urn:appInfo:Items" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd" version="1.1"> 3<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" xmlns:xyz="urn:appInfo:Items" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd" version="1.1">
4 <file source-language="en-US" datatype="plaintext" original="" target-language="nl-NL"> 4 <file source-language="en-US" datatype="plaintext" original="" target-language="nl-NL">
5 <body> 5 <body>
6 <trans-unit id="ngb.alert.close">
7 <source>Close</source>
8 <target>Sluiten</target>
9 <context-group name="null">
10 <context context-type="linenumber">2</context>
11 </context-group>
12 </trans-unit>
13 <trans-unit id="ngb.carousel.previous">
14 <source>Previous</source>
15 <target>Vorige</target>
16 <context-group name="null">
17 <context context-type="linenumber">13</context>
18 </context-group>
19 </trans-unit>
20 <trans-unit id="ngb.carousel.next">
21 <source>Next</source>
22 <target>Volgende</target>
23 <context-group name="null">
24 <context context-type="linenumber">17</context>
25 </context-group>
26 </trans-unit>
27 <trans-unit id="ngb.datepicker.previous-month">
28 <source>Previous month</source>
29 <target>Vorige maand</target>
30 <context-group name="null">
31 <context context-type="linenumber">5</context>
32 </context-group>
33 </trans-unit>
34 <trans-unit id="ngb.datepicker.next-month">
35 <source>Next month</source>
36 <target>Volgende maand</target>
37 <context-group name="null">
38 <context context-type="linenumber">27</context>
39 </context-group>
40 </trans-unit>
41 <trans-unit id="ngb.datepicker.select-month">
42 <source>Select month</source>
43 <target>Selecteer maand</target>
44 <context-group name="null">
45 <context context-type="linenumber">7</context>
46 </context-group>
47 </trans-unit>
48 <trans-unit id="ngb.datepicker.select-year">
49 <source>Select year</source>
50 <target>Selecteer jaar</target>
51 <context-group name="null">
52 <context context-type="linenumber">16</context>
53 </context-group>
54 </trans-unit>
55 <trans-unit id="ngb.pagination.first">
56 <source>««</source>
57 <target>««</target>
58 <context-group name="null">
59 <context context-type="linenumber">7</context>
60 </context-group>
61 </trans-unit>
62 <trans-unit id="ngb.pagination.first-aria">
63 <source>First</source>
64 <target>Eerste</target>
65 <context-group name="null">
66 <context context-type="linenumber">5</context>
67 </context-group>
68 </trans-unit>
69 <trans-unit id="ngb.pagination.previous">
70 <source>«</source>
71 <target>«</target>
72 <context-group name="null">
73 <context context-type="linenumber">15</context>
74 </context-group>
75 </trans-unit>
76 <trans-unit id="ngb.pagination.previous-aria">
77 <source>Previous</source>
78 <target>Vorige</target>
79 <context-group name="null">
80 <context context-type="linenumber">13</context>
81 </context-group>
82 </trans-unit>
83 <trans-unit id="ngb.pagination.next">
84 <source>»</source>
85 <target>»</target>
86 <context-group name="null">
87 <context context-type="linenumber">29</context>
88 </context-group>
89 </trans-unit>
90 <trans-unit id="ngb.pagination.next-aria">
91 <source>Next</source>
92 <target>Volgende</target>
93 <context-group name="null">
94 <context context-type="linenumber">27</context>
95 </context-group>
96 </trans-unit>
97 <trans-unit id="ngb.pagination.last">
98 <source>»»</source>
99 <target>»»</target>
100 <context-group name="null">
101 <context context-type="linenumber">36</context>
102 </context-group>
103 </trans-unit>
104 <trans-unit id="ngb.pagination.last-aria">
105 <source>Last</source>
106 <target>Laatste</target>
107 <context-group name="null">
108 <context context-type="linenumber">34</context>
109 </context-group>
110 </trans-unit>
111 <trans-unit id="ngb.progressbar.value">
112 <source><x id="INTERPOLATION" equiv-text="{{getPercentValue()}}"/>%</source>
113 <target><x id="INTERPOLATION" equiv-text="{{getPercentValue()}}"/>%</target>
114 <context-group name="null">
115 <context context-type="linenumber">6</context>
116 </context-group>
117 </trans-unit>
118 <trans-unit id="ngb.timepicker.increment-hours">
119 <source>Increment hours</source>
120 <target>Verhoog uren</target>
121 <context-group name="null">
122 <context context-type="linenumber">9</context>
123 </context-group>
124 </trans-unit>
125 <trans-unit id="ngb.timepicker.HH">
126 <source>HH</source>
127 <target>HH</target>
128 <context-group name="null">
129 <context context-type="linenumber">12</context>
130 </context-group>
131 </trans-unit>
132 <trans-unit id="ngb.timepicker.hours">
133 <source>Hours</source>
134 <target>Uren</target>
135 <context-group name="null">
136 <context context-type="linenumber">14</context>
137 </context-group>
138 </trans-unit>
139 <trans-unit id="ngb.timepicker.decrement-hours">
140 <source>Decrement hours</source>
141 <target>Verlaag uren</target>
142 <context-group name="null">
143 <context context-type="linenumber">19</context>
144 </context-group>
145 </trans-unit>
146 <trans-unit id="ngb.timepicker.increment-minutes">
147 <source>Increment minutes</source>
148 <target>Verhoog minuten</target>
149 <context-group name="null">
150 <context context-type="linenumber">28</context>
151 </context-group>
152 </trans-unit>
153 <trans-unit id="ngb.timepicker.MM">
154 <source>MM</source>
155 <target>MM</target>
156 <context-group name="null">
157 <context context-type="linenumber">31</context>
158 </context-group>
159 </trans-unit>
160 <trans-unit id="ngb.timepicker.minutes">
161 <source>Minutes</source>
162 <target>Minuten</target>
163 <context-group name="null">
164 <context context-type="linenumber">33</context>
165 </context-group>
166 </trans-unit>
167 <trans-unit id="ngb.timepicker.decrement-minutes">
168 <source>Decrement minutes</source>
169 <target>Verlaag minuten</target>
170 <context-group name="null">
171 <context context-type="linenumber">38</context>
172 </context-group>
173 </trans-unit>
174 <trans-unit id="ngb.timepicker.increment-seconds">
175 <source>Increment seconds</source>
176 <target>Verhoog seconden</target>
177 <context-group name="null">
178 <context context-type="linenumber">47</context>
179 </context-group>
180 </trans-unit>
181 <trans-unit id="ngb.timepicker.SS">
182 <source>SS</source>
183 <target>SS</target>
184 <context-group name="null">
185 <context context-type="linenumber">50</context>
186 </context-group>
187 </trans-unit>
188 <trans-unit id="ngb.timepicker.seconds">
189 <source>Seconds</source>
190 <target>Seconden</target>
191 <context-group name="null">
192 <context context-type="linenumber">52</context>
193 </context-group>
194 </trans-unit>
195 <trans-unit id="ngb.timepicker.decrement-seconds">
196 <source>Decrement seconds</source>
197 <target>Verlaag seconden</target>
198 <context-group name="null">
199 <context context-type="linenumber">57</context>
200 </context-group>
201 </trans-unit>
202 <trans-unit id="ngb.timepicker.PM">
203 <source>PM</source>
204 <target>PM</target>
205 <context-group name="null">
206 <context context-type="linenumber">65</context>
207 </context-group>
208 </trans-unit>
209 <trans-unit id="ngb.timepicker.AM">
210 <source>AM</source>
211 <target>AM</target>
212 <context-group name="null">
213 <context context-type="linenumber">66</context>
214 </context-group>
215 </trans-unit>
216 <trans-unit id="d7b35c384aecd25a516200d6921836374613dfe7">
217 <source>Cancel</source>
218 <target>Annuleren</target>
219 <context-group name="null">
220 <context context-type="linenumber">10</context>
221 </context-group>
222 </trans-unit>
223 <trans-unit id="1d19634967b06f93fd7f20c0663742f8254e6d46">
224 <source>(extensions: <x id="INTERPOLATION" equiv-text="{{ allowedExtensionsMessage }}"/>, max size: <x id="INTERPOLATION_1" equiv-text="{{ maxFileSize | bytes }}"/>)</source>
225 <target>(extensies: <x id="INTERPOLATION" equiv-text="{{ allowedExtensionsMessage }}"/>, max grootte: <x id="INTERPOLATION_1" equiv-text="{{ maxFileSize | bytes }}"/>)</target>
226 <context-group name="null">
227 <context context-type="linenumber">11</context>
228 </context-group>
229 </trans-unit>
230 <trans-unit id="4b3963c6d0863118fe9e9e33447d12be3c2db081">
231 <source>Unlisted</source>
232 <target>Onvermeld</target>
233 <context-group name="null">
234 <context context-type="linenumber">10</context>
235 </context-group>
236 </trans-unit>
237 <trans-unit id="ddd8a4986d2d1717a274a5a0fbed04988a819e69">
238 <source>Private</source>
239 <target>Privé</target>
240 <context-group name="null">
241 <context context-type="linenumber">11</context>
242 </context-group>
243 </trans-unit>
6 <trans-unit id="9d5f16f0233b39fa2cd843321407a7358c323ad8"> 244 <trans-unit id="9d5f16f0233b39fa2cd843321407a7358c323ad8">
7 <source><x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 245 <source><x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
8 <target><x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> keer bekeken</target> 246 <target><x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> keer bekeken</target>
@@ -45,6 +283,105 @@
45 <context context-type="linenumber">19</context> 283 <context context-type="linenumber">19</context>
46 </context-group> 284 </context-group>
47 </trans-unit> 285 </trans-unit>
286 <trans-unit id="450025269732888db1f04cfe6033843110ab65ee">
287 <source>
288 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/>
289 Subscribe
290 <x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
291 <x id="START_TAG_SPAN_1" ctype="x-span" equiv-text="&lt;span&gt;"/>
292 <x id="INTERPOLATION" equiv-text="{{ videoChannel.followersCount | myNumberFormatter }}"/>
293 <x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
294 </source>
295 <target>
296 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/>
297 Abonneer
298 <x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
299 <x id="START_TAG_SPAN_1" ctype="x-span" equiv-text="&lt;span&gt;"/>
300 <x id="INTERPOLATION" equiv-text="{{ videoChannel.followersCount | myNumberFormatter }}"/>
301 <x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
302 <context-group name="null">
303 <context context-type="linenumber">5</context>
304 </context-group>
305 </trans-unit>
306 <trans-unit id="c374edf3b9228d3df6d761bdc8a289e7df0096e8">
307 <source>
308 Unsubscribe
309 </source>
310 <target>
311Abonnement opzeggen</target>
312 <context-group name="null">
313 <context context-type="linenumber">18</context>
314 </context-group>
315 </trans-unit>
316 <trans-unit id="9b3287f52c239cad05ec98391553e5052ba1aa66">
317 <source>Using an ActivityPub account</source>
318 <target>Een ActivityPub-account gebruiken</target>
319 <context-group name="null">
320 <context context-type="linenumber">36</context>
321 </context-group>
322 </trans-unit>
323 <trans-unit id="60251958d9e05c8cc00abf9645bb0026ebbe4dc3">
324 <source>Subscribe with an account on <x id="INTERPOLATION" equiv-text="{{ videoChannel.host }}"/></source>
325 <target>Abonneer met een account op <x id="INTERPOLATION" equiv-text="{{ videoChannel.host }}"/></target>
326 <context-group name="null">
327 <context context-type="linenumber">39</context>
328 </context-group>
329 </trans-unit>
330 <trans-unit id="e7adf422424a61b71465d183f9d44bf956482ef0">
331 <source>Subscribe with your local account</source>
332 <target>Abonneer met je lokale account</target>
333 <context-group name="null">
334 <context context-type="linenumber">40</context>
335 </context-group>
336 </trans-unit>
337 <trans-unit id="5047522cc670b1f4a288bce07f9b1c5061e913ed">
338 <source>Subscribe with a Mastodon account:</source>
339 <target>Abonneer met een Mastodon-account</target>
340 <context-group name="null">
341 <context context-type="linenumber">43</context>
342 </context-group>
343 </trans-unit>
344 <trans-unit id="d8758664cadd6452256ca25ca0c7259074f427c1">
345 <source>Using a syndication feed</source>
346 <target>Een syndicaatfeed gebruiken</target>
347 <context-group name="null">
348 <context context-type="linenumber">48</context>
349 </context-group>
350 </trans-unit>
351 <trans-unit id="d5e5bc7d213694fc0414a76f0ff3085bae44268a">
352 <source>Subscribe via RSS</source>
353 <target>Abonneren met RSS</target>
354 <context-group name="null">
355 <context context-type="linenumber">49</context>
356 </context-group>
357 </trans-unit>
358 <trans-unit id="4913054c95f5ba14c351ab1b787f7abac97bfdd3">
359 <source>
360 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/>Remote subscribe<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
361 <x id="START_TAG_SPAN_1" ctype="x-span" equiv-text="&lt;span&gt;"/>Remote interact<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
362 </source>
363 <target>
364<x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/>Extern abonneren<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
365 <x id="START_TAG_SPAN_1" ctype="x-span" equiv-text="&lt;span&gt;"/>Externe interactie<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
366 </target>
367 <context-group name="null">
368 <context context-type="linenumber">10</context>
369 </context-group>
370 </trans-unit>
371 <trans-unit id="319933e1af77ca2e35b75a5e9270a3c90e83dd4b">
372 <source>You can subscribe to the channel via any ActivityPub-capable fediverse instance. For instance with Mastodon or Pleroma you can type the channel URL in the search box and subscribe there.</source>
373 <target>Je kan op het kanaal abonneren via elke ActivityPub-mogelijke fediverse instantie. Bijvoorbeeld met Mastodon of Pleroma kan je de URL van het kanaal in de zoekbalk invullen en daar abonneren.</target>
374 <context-group name="null">
375 <context context-type="linenumber">17</context>
376 </context-group>
377 </trans-unit>
378 <trans-unit id="2767d5461b6c622ccdeb868df8becf26bc16b99a">
379 <source>You can interact with this via any ActivityPub-capable fediverse instance. For instance with Mastodon or Pleroma you can type the current URL in the search box and interact with it there.</source>
380 <target>Je kan hiermee interactie hebben via elke ActivityPub-mogelijke fediverse instantie. Bijvoorbeeld met Mastodon of Pleroma kan je de huidige URL in de zoekbalk typen en er daar interactie mee hebben.</target>
381 <context-group name="null">
382 <context context-type="linenumber">22</context>
383 </context-group>
384 </trans-unit>
48 <trans-unit id="15f046007e4fca2e8477966745e2ec4e3e81bc3b"> 385 <trans-unit id="15f046007e4fca2e8477966745e2ec4e3e81bc3b">
49 <source>Video quota</source> 386 <source>Video quota</source>
50 <target>Videoquotum</target> 387 <target>Videoquotum</target>
@@ -52,15 +389,65 @@
52 <context context-type="linenumber">42</context> 389 <context context-type="linenumber">42</context>
53 </context-group> 390 </context-group>
54 </trans-unit> 391 </trans-unit>
392 <trans-unit id="9270dfd4606fb45a991fe7716e640b6efa28ba85">
393 <source>
394 Unlimited <x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/>(<x id="INTERPOLATION" equiv-text="{{ dailyUserVideoQuota | bytes: 0 }}"/> per day)<x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
395 </source>
396 <target>
397Oneindig <x id="START_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;ng-container&gt;"/>(<x id="INTERPOLATION" equiv-text="{{ dailyUserVideoQuota | bytes: 0 }}"/> per dag)<x id="CLOSE_TAG_NG-CONTAINER" ctype="x-ng-container" equiv-text="&lt;/ng-container&gt;"/>
398 </target>
399 <context-group name="null">
400 <context context-type="linenumber">14</context>
401 </context-group>
402 </trans-unit>
403 <trans-unit id="6a323f80f9d90a32db8ce52cc82075938c3c36f0">
404 <source>Ban</source>
405 <target>Verbannen</target>
406 <context-group name="null">
407 <context context-type="linenumber">3</context>
408 </context-group>
409 </trans-unit>
410 <trans-unit id="bb44873ad8d4c5dbad0ac2a6a50e0ceee9119125">
411 <source>Reason...</source>
412 <target>Reden...</target>
413 <context-group name="null">
414 <context context-type="linenumber">11</context>
415 </context-group>
416 </trans-unit>
417 <trans-unit id="f21428bd564d1cacdbc737f87a8def2e2ad42251">
418 <source>
419 A banned user will no longer be able to login.
420 </source>
421 <target>
422Een verbannen gebruiker kan niet langer inloggen.</target>
423 <context-group name="null">
424 <context context-type="linenumber">17</context>
425 </context-group>
426 </trans-unit>
427 <trans-unit id="35fdca47605de8113a0db7f587f7c099abec8020">
428 <source>Ban this user</source>
429 <target>Verban deze gebruiker</target>
430 <context-group name="null">
431 <context context-type="linenumber">25</context>
432 </context-group>
433 </trans-unit>
55 <trans-unit id="12910217fdcdbca64bee06f511639b653d5428ea"> 434 <trans-unit id="12910217fdcdbca64bee06f511639b653d5428ea">
56 <source> 435 <source>
57 Login 436 Login
58 </source> 437 </source>
59 <target>Aanmelden</target> 438 <target>
439Aanmelden</target>
60 <context-group name="null"> 440 <context-group name="null">
61 <context context-type="linenumber">2</context> 441 <context context-type="linenumber">2</context>
62 </context-group> 442 </context-group>
63 </trans-unit> 443 </trans-unit>
444 <trans-unit id="ae3cb52bf2dee3101ee654812b5d16e8665a9453">
445 <source>Request new verification email.</source>
446 <target>Een nieuwe verificatie e-mail aanvragen.</target>
447 <context-group name="null">
448 <context context-type="linenumber">12</context>
449 </context-group>
450 </trans-unit>
64 <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194"> 451 <trans-unit id="e08a77594f3d89311cdf6da5090044270909c194">
65 <source>User</source> 452 <source>User</source>
66 <target>Gebruiker</target> 453 <target>Gebruiker</target>
@@ -79,7 +466,8 @@
79 <source> 466 <source>
80 or create an account 467 or create an account
81 </source> 468 </source>
82 <target>of maak een account</target> 469 <target>
470of maak een account</target>
83 <context-group name="null"> 471 <context-group name="null">
84 <context context-type="linenumber">18</context> 472 <context context-type="linenumber">18</context>
85 </context-group> 473 </context-group>
@@ -88,14 +476,15 @@
88 <source> 476 <source>
89 or create an account on another instance 477 or create an account on another instance
90 </source> 478 </source>
91 <target>of maak een account aan op een andere server</target> 479 <target>
480of maak een account aan op een andere instantie</target>
92 <context-group name="null"> 481 <context-group name="null">
93 <context context-type="linenumber">22</context> 482 <context context-type="linenumber">22</context>
94 </context-group> 483 </context-group>
95 </trans-unit> 484 </trans-unit>
96 <trans-unit id="76e1f485e6ead4c84b606f46d413878881d66ad3"> 485 <trans-unit id="76e1f485e6ead4c84b606f46d413878881d66ad3">
97 <source>User registration is not allowed on this instance, but you can register on many others!</source> 486 <source>User registration is not allowed on this instance, but you can register on many others!</source>
98 <target>Registratie is niet mogelijk op deze instantie, maar je kan een account maken op een van de vele anderen!</target> 487 <target>Registratie is niet mogelijk op deze instantie, maar je kan wel registreren op een van de vele anderen!</target>
99 <context-group name="null"> 488 <context-group name="null">
100 <context context-type="linenumber">28</context> 489 <context context-type="linenumber">28</context>
101 </context-group> 490 </context-group>
@@ -104,12 +493,12 @@
104 <source>Password</source> 493 <source>Password</source>
105 <target>Wachtwoord</target> 494 <target>Wachtwoord</target>
106 <context-group name="null"> 495 <context-group name="null">
107 <context context-type="linenumber">12</context> 496 <context context-type="linenumber">13</context>
108 </context-group> 497 </context-group>
109 </trans-unit> 498 </trans-unit>
110 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 499 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
111 <source>I forgot my password</source> 500 <source>I forgot my password</source>
112 <target>Wachtwoord vergeten</target> 501 <target>Ik ben mijn wachtwoord vergeten</target>
113 <context-group name="null"> 502 <context-group name="null">
114 <context context-type="linenumber">44</context> 503 <context context-type="linenumber">44</context>
115 </context-group> 504 </context-group>
@@ -118,12 +507,12 @@
118 <source>Login</source> 507 <source>Login</source>
119 <target>Aanmelden</target> 508 <target>Aanmelden</target>
120 <context-group name="null"> 509 <context-group name="null">
121 <context context-type="linenumber">38</context> 510 <context context-type="linenumber">36</context>
122 </context-group> 511 </context-group>
123 </trans-unit> 512 </trans-unit>
124 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 513 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
125 <source>Forgot your password</source> 514 <source>Forgot your password</source>
126 <target>Wachtwoord vergeten</target> 515 <target>Jouw wachtwoord vergeten</target>
127 <context-group name="null"> 516 <context-group name="null">
128 <context context-type="linenumber">57</context> 517 <context context-type="linenumber">57</context>
129 </context-group> 518 </context-group>
@@ -146,14 +535,15 @@
146 <source>Send me an email to reset my password</source> 535 <source>Send me an email to reset my password</source>
147 <target>Zend me een e-mail om een nieuw wachtwoord in te stellen</target> 536 <target>Zend me een e-mail om een nieuw wachtwoord in te stellen</target>
148 <context-group name="null"> 537 <context-group name="null">
149 <context context-type="linenumber">75</context> 538 <context context-type="linenumber">80</context>
150 </context-group> 539 </context-group>
151 </trans-unit> 540 </trans-unit>
152 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 541 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
153 <source> 542 <source>
154 Reset my password 543 Reset my password
155 </source> 544 </source>
156 <target>Wachtwoord opnieuw instellen</target> 545 <target>
546Wachtwoord opnieuw instellen</target>
157 <context-group name="null"> 547 <context-group name="null">
158 <context context-type="linenumber">2</context> 548 <context context-type="linenumber">2</context>
159 </context-group> 549 </context-group>
@@ -183,7 +573,8 @@
183 <source> 573 <source>
184 Create an account 574 Create an account
185 </source> 575 </source>
186 <target>Account maken</target> 576 <target>
577Account aanmaken</target>
187 <context-group name="null"> 578 <context-group name="null">
188 <context context-type="linenumber">3</context> 579 <context context-type="linenumber">3</context>
189 </context-group> 580 </context-group>
@@ -195,25 +586,139 @@
195 <context context-type="linenumber">8</context> 586 <context context-type="linenumber">8</context>
196 </context-group> 587 </context-group>
197 </trans-unit> 588 </trans-unit>
589 <trans-unit id="26025b8081241cf85eb6516431b596df11fa66b3">
590 <source>Example: jane_doe</source>
591 <target>Bijvoorbeeld: jane-doe</target>
592 <context-group name="null">
593 <context context-type="linenumber">17</context>
594 </context-group>
595 </trans-unit>
596 <trans-unit id="7fe213724c4c0a4112c40c673884acb98a0a3b92">
597 <source>I am at least 16 years old and agree to the &lt;a href='/about/instance#terms-section' target='_blank'rel='noopener noreferrer'&gt;Terms&lt;/a&gt; of this instance</source>
598 <target>Ik ben minstens 16 jaar oud en accepteer de &lt;a href='/about/instance#terms-section' target='_blank'rel='noopener noreferrer'&gt;Voorwaarden&lt;/a&gt; van deze instantie</target>
599 <context-group name="null">
600 <context context-type="linenumber">55</context>
601 </context-group>
602 </trans-unit>
198 <trans-unit id="717a5e3574fec754fbeb348c2d5561c4d81facc4"> 603 <trans-unit id="717a5e3574fec754fbeb348c2d5561c4d81facc4">
199 <source>Signup</source> 604 <source>Signup</source>
200 <target>Registratie</target> 605 <target>Registratie</target>
201 <context-group name="null"> 606 <context-group name="null">
202 <context context-type="linenumber">88</context> 607 <context context-type="linenumber">78</context>
608 </context-group>
609 </trans-unit>
610 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
611 <source>Features found on this instance</source>
612 <target>Kenmerken van deze instantie</target>
613 <context-group name="null">
614 <context context-type="linenumber">67</context>
615 </context-group>
616 </trans-unit>
617 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a">
618 <source><x id="INTERPOLATION" equiv-text="{{ pagination.totalItems | myNumberFormatter }}"/> results</source>
619 <target><x id="INTERPOLATION" equiv-text="{{ pagination.totalItems | myNumberFormatter }}"/> resultaten</target>
620 <context-group name="null">
621 <context context-type="linenumber">5</context>
622 </context-group>
623 </trans-unit>
624 <trans-unit id="4c3960fb1d9b07d1db3b5bda3ee40019211830dc">
625 <source>
626 for <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/><x id="INTERPOLATION" equiv-text="{{ currentSearch }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
627 </source>
628 <target>
629voor <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/><x id="INTERPOLATION" equiv-text="{{ currentSearch }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
630 <context-group name="null">
631 <context context-type="linenumber">6</context>
632 </context-group>
633 </trans-unit>
634 <trans-unit id="7c603b9ed878097782e2b8908f662e2344b46061">
635 <source>
636 Filters
637 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/><x id="INTERPOLATION" equiv-text="{{ numberOfFilters() }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/>
638 </source>
639 <target>
640 Filters
641 <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span&gt;"/><x id="INTERPOLATION" equiv-text="{{ numberOfFilters() }}"/><x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
642 <context-group name="null">
643 <context context-type="linenumber">16</context>
644 </context-group>
645 </trans-unit>
646 <trans-unit id="e2dbf0426cbb0b573faf49dffeb7d5bdf16eda5d">
647 <source>
648 No results found
649 </source>
650 <target>
651Geen resultaten gevonden</target>
652 <context-group name="null">
653 <context context-type="linenumber">28</context>
654 </context-group>
655 </trans-unit>
656 <trans-unit id="10341623e991a4185990a0c3c76ac2bc3543cc4a">
657 <source><x id="INTERPOLATION" equiv-text="{{ result.followersCount }}"/> subscribers</source>
658 <target><x id="INTERPOLATION" equiv-text="{{ result.followersCount }}"/> abonnees</target>
659 <context-group name="null">
660 <context context-type="linenumber">44</context>
661 </context-group>
662 </trans-unit>
663 <trans-unit id="602281e45fe8b79748e3fbf21c432379fcb58883">
664 <source><x id="INTERPOLATION" equiv-text="{{ result.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ result.views | myNumberFormatter }}"/> views</source>
665 <target><x id="INTERPOLATION" equiv-text="{{ result.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ result.views | myNumberFormatter }}"/> weergaven</target>
666 <context-group name="null">
667 <context context-type="linenumber">55</context>
203 </context-group> 668 </context-group>
204 </trans-unit> 669 </trans-unit>
205 <trans-unit id="aef5c45fb9c725573d20a6283492e6b80fd2ae96"> 670 <trans-unit id="aef5c45fb9c725573d20a6283492e6b80fd2ae96">
206 <source>Change the language</source> 671 <source>Change the language</source>
207 <target>Taal veranderen</target> 672 <target>Taal veranderen</target>
208 <context-group name="null"> 673 <context-group name="null">
209 <context context-type="linenumber">88</context> 674 <context context-type="linenumber">86</context>
675 </context-group>
676 </trans-unit>
677 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
678 <source>
679 My public profile
680 </source>
681 <target>
682Mijn openbare profiel</target>
683 <context-group name="null">
684 <context context-type="linenumber">16</context>
685 </context-group>
686 </trans-unit>
687 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
688 <source>
689 My account
690 </source>
691 <target>
692Mijn account</target>
693 <context-group name="null">
694 <context context-type="linenumber">20</context>
695 </context-group>
696 </trans-unit>
697 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
698 <source>
699 My videos
700 </source>
701 <target>
702Mijn video's</target>
703 <context-group name="null">
704 <context context-type="linenumber">24</context>
705 </context-group>
706 </trans-unit>
707 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
708 <source>
709 Log out
710 </source>
711 <target>
712Uitloggen</target>
713 <context-group name="null">
714 <context context-type="linenumber">28</context>
210 </context-group> 715 </context-group>
211 </trans-unit> 716 </trans-unit>
212 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 717 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
213 <source>Create an account</source> 718 <source>Create an account</source>
214 <target>Account maken</target> 719 <target>Account maken</target>
215 <context-group name="null"> 720 <context-group name="null">
216 <context context-type="linenumber">39</context> 721 <context context-type="linenumber">37</context>
217 </context-group> 722 </context-group>
218 </trans-unit> 723 </trans-unit>
219 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 724 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -223,32 +728,53 @@
223 <context context-type="linenumber">24</context> 728 <context context-type="linenumber">24</context>
224 </context-group> 729 </context-group>
225 </trans-unit> 730 </trans-unit>
731 <trans-unit id="357064ca9d9ac859eb618e28e8126fa32be049e2">
732 <source>Subscriptions</source>
733 <target>Abonnementen</target>
734 <context-group name="null">
735 <context context-type="linenumber">45</context>
736 </context-group>
737 </trans-unit>
738 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
739 <source>Overview</source>
740 <target>Overzicht</target>
741 <context-group name="null">
742 <context context-type="linenumber">50</context>
743 </context-group>
744 </trans-unit>
226 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 745 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
227 <source>Trending</source> 746 <source>Trending</source>
228 <target>Populair</target> 747 <target>Populair</target>
229 <context-group name="null"> 748 <context-group name="null">
230 <context context-type="linenumber">57</context> 749 <context context-type="linenumber">55</context>
231 </context-group> 750 </context-group>
232 </trans-unit> 751 </trans-unit>
233 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 752 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
234 <source>Recently added</source> 753 <source>Recently added</source>
235 <target>Recent toegevoegd</target> 754 <target>Recent toegevoegd</target>
236 <context-group name="null"> 755 <context-group name="null">
237 <context context-type="linenumber">62</context> 756 <context context-type="linenumber">60</context>
238 </context-group> 757 </context-group>
239 </trans-unit> 758 </trans-unit>
240 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 759 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
241 <source>Local</source> 760 <source>Local</source>
242 <target>Lokaal</target> 761 <target>Lokaal</target>
243 <context-group name="null"> 762 <context-group name="null">
244 <context context-type="linenumber">67</context> 763 <context context-type="linenumber">65</context>
764 </context-group>
765 </trans-unit>
766 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
767 <source>More</source>
768 <target>Meer</target>
769 <context-group name="null">
770 <context context-type="linenumber">70</context>
245 </context-group> 771 </context-group>
246 </trans-unit> 772 </trans-unit>
247 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 773 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
248 <source>Administration</source> 774 <source>Administration</source>
249 <target>Administratie</target> 775 <target>Administratie</target>
250 <context-group name="null"> 776 <context-group name="null">
251 <context context-type="linenumber">76</context> 777 <context context-type="linenumber">74</context>
252 </context-group> 778 </context-group>
253 </trans-unit> 779 </trans-unit>
254 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 780 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -258,6 +784,20 @@
258 <context context-type="linenumber">25</context> 784 <context context-type="linenumber">25</context>
259 </context-group> 785 </context-group>
260 </trans-unit> 786 </trans-unit>
787 <trans-unit id="4752e5e33da1c3396d3248eb8fef59bca5d00cb3">
788 <source>Show keyboard shortcuts</source>
789 <target>Laat keyboard shortcuts zien</target>
790 <context-group name="null">
791 <context context-type="linenumber">89</context>
792 </context-group>
793 </trans-unit>
794 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
795 <source>Toggle dark interface</source>
796 <target>Schakel donkere interface aan of uit</target>
797 <context-group name="null">
798 <context context-type="linenumber">92</context>
799 </context-group>
800 </trans-unit>
261 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 801 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
262 <source>Search...</source> 802 <source>Search...</source>
263 <target>Zoeken …</target> 803 <target>Zoeken …</target>
@@ -272,6 +812,48 @@
272 <context context-type="linenumber">9</context> 812 <context context-type="linenumber">9</context>
273 </context-group> 813 </context-group>
274 </trans-unit> 814 </trans-unit>
815 <trans-unit id="5d43539fc358c3a548b9d487be821db73e2702ff">
816 <source>Sort</source>
817 <target>Sorteren</target>
818 <context-group name="null">
819 <context context-type="linenumber">6</context>
820 </context-group>
821 </trans-unit>
822 <trans-unit id="98acac685fc4b2d35e5d0cf3cd224d247a756c3e">
823 <source>Published date</source>
824 <target>Datum van publicatie</target>
825 <context-group name="null">
826 <context context-type="linenumber">15</context>
827 </context-group>
828 </trans-unit>
829 <trans-unit id="a02ea1d4e7424ca989929da5e598f379940fdbf2">
830 <source>Duration</source>
831 <target>Duratie</target>
832 <context-group name="null">
833 <context context-type="linenumber">24</context>
834 </context-group>
835 </trans-unit>
836 <trans-unit id="dc67060f94f0f2b58549f54a5c07925dffd20238">
837 <source>Display sensitive content</source>
838 <target>Laat gevoelige inhoud zien</target>
839 <context-group name="null">
840 <context context-type="linenumber">33</context>
841 </context-group>
842 </trans-unit>
843 <trans-unit id="4f20f2d5a6882190892e58b85f6ccbedfa737952">
844 <source>Yes</source>
845 <target>Ja</target>
846 <context-group name="null">
847 <context context-type="linenumber">37</context>
848 </context-group>
849 </trans-unit>
850 <trans-unit id="3d3ae7deebc5949b0c1c78b9847886a94321d9fd">
851 <source>No</source>
852 <target>Nee</target>
853 <context-group name="null">
854 <context context-type="linenumber">42</context>
855 </context-group>
856 </trans-unit>
275 <trans-unit id="607de17c2a755f65775881c19e276e7c933bcf94"> 857 <trans-unit id="607de17c2a755f65775881c19e276e7c933bcf94">
276 <source>Category</source> 858 <source>Category</source>
277 <target>Categorie</target> 859 <target>Categorie</target>
@@ -293,11 +875,77 @@
293 <context context-type="linenumber">182</context> 875 <context context-type="linenumber">182</context>
294 </context-group> 876 </context-group>
295 </trans-unit> 877 </trans-unit>
878 <trans-unit id="c8d58c4fbe23e51af3dc8f58cb4a81eac20739e8">
879 <source>All of these tags</source>
880 <target>Al deze tags</target>
881 <context-group name="null">
882 <context context-type="linenumber">82</context>
883 </context-group>
884 </trans-unit>
885 <trans-unit id="492d2bd18db0cba03f6d9e3b0c42b8639fbe51ab">
886 <source>One of these tags</source>
887 <target>Een van deze tags</target>
888 <context-group name="null">
889 <context context-type="linenumber">87</context>
890 </context-group>
891 </trans-unit>
892 <trans-unit id="5ca707824ab93066c7d9b44e1b8bf216725c2c22">
893 <source>Filter</source>
894 <target>Filter</target>
895 <context-group name="null">
896 <context context-type="linenumber">94</context>
897 </context-group>
898 </trans-unit>
899 <trans-unit id="41ed53a3f1d4dfc57011d0aba13b8b074e8b41b6">
900 <source>Display unlisted and private videos</source>
901 <target>Laat onvermelde en privé-video's zien</target>
902 <context-group name="null">
903 <context context-type="linenumber">14</context>
904 </context-group>
905 </trans-unit>
296 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 906 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
297 <source>No results.</source> 907 <source>No results.</source>
298 <target>Geen resultaten.</target> 908 <target>Geen resultaten.</target>
299 <context-group name="null"> 909 <context-group name="null">
300 <context context-type="linenumber">17</context> 910 <context context-type="linenumber">20</context>
911 </context-group>
912 </trans-unit>
913 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
914 <source>
915 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ object.category.label }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
916 </source>
917 <target>
918<x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ object.category.label }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></target>
919 <context-group name="null">
920 <context context-type="linenumber">6</context>
921 </context-group>
922 </trans-unit>
923 <trans-unit id="48a5d0af93b94c4575b7f76a47fb3cdee58e6919">
924 <source>
925 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>#<x id="INTERPOLATION" equiv-text="{{ object.tag }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
926 </source>
927 <target>
928<x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>#<x id="INTERPOLATION" equiv-text="{{ object.tag }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></target>
929 <context-group name="null">
930 <context context-type="linenumber">14</context>
931 </context-group>
932 </trans-unit>
933 <trans-unit id="e093a5a83045ff283f992a93699abb7cb9dd3c1b">
934 <source>
935 <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>
936 <x id="TAG_IMG" ctype="image" equiv-text="&lt;img/&gt;"/>
937
938 <x id="START_TAG_DIV" ctype="x-div" equiv-text="&lt;div&gt;"/><x id="INTERPOLATION" equiv-text="{{ object.channel.displayName }}"/><x id="CLOSE_TAG_DIV" ctype="x-div" equiv-text="&lt;/div&gt;"/>
939 <x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
940 </source>
941 <target>
942<x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>
943 <x id="TAG_IMG" ctype="image" equiv-text="&lt;img/&gt;"/>
944
945 <x id="START_TAG_DIV" ctype="x-div" equiv-text="&lt;div&gt;"/><x id="INTERPOLATION" equiv-text="{{ object.channel.displayName }}"/><x id="CLOSE_TAG_DIV" ctype="x-div" equiv-text="&lt;/div&gt;"/>
946 <x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></target>
947 <context-group name="null">
948 <context context-type="linenumber">22</context>
301 </context-group> 949 </context-group>
302 </trans-unit> 950 </trans-unit>
303 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b"> 951 <trans-unit id="ff78f059449d44322f627d0f66df07abe476962b">
@@ -314,13 +962,21 @@
314 <context context-type="linenumber">7</context> 962 <context context-type="linenumber">7</context>
315 </context-group> 963 </context-group>
316 </trans-unit> 964 </trans-unit>
317 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 965 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
318 <source> 966 <source>
319 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 967 Cancel
320</source> 968 </source>
321 <target>Over de instantie <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/></target> 969 <target>
970Annuleer</target>
322 <context-group name="null"> 971 <context-group name="null">
323 <context context-type="linenumber">1</context> 972 <context context-type="linenumber">26</context>
973 </context-group>
974 </trans-unit>
975 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
976 <source>Submit</source>
977 <target>Voorleggen</target>
978 <context-group name="null">
979 <context context-type="linenumber">31</context>
324 </context-group> 980 </context-group>
325 </trans-unit> 981 </trans-unit>
326 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 982 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -334,48 +990,24 @@
334 <source>Terms</source> 990 <source>Terms</source>
335 <target>Voorwaarden</target> 991 <target>Voorwaarden</target>
336 <context-group name="null"> 992 <context-group name="null">
337 <context context-type="linenumber">44</context> 993 <context context-type="linenumber">39</context>
338 </context-group> 994 </context-group>
339 </trans-unit> 995 </trans-unit>
340 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 996 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
341 <source>User registration is allowed and</source> 997 <source>User registration is allowed and</source>
342 <target>Een account aanmaken is mogelijk en</target> 998 <target>Een account aanmaken is mogelijk en</target>
343 <context-group name="null"> 999 <context-group name="null">
344 <context context-type="linenumber">25</context> 1000 <context context-type="linenumber">29</context>
345 </context-group>
346 </trans-unit>
347 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
348 <source>
349 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
350 </source>
351 <target>deze instantie voorziet een basis-opslagquotum van <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> voor de video's van haar gebruikers.</target>
352 <context-group name="null">
353 <context context-type="linenumber">27</context>
354 </context-group>
355 </trans-unit>
356 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
357 <source>
358 this instance provides unlimited space for the videos of its users.
359 </source>
360 <target>deze instantie voorziet onbeperkte opslagruimte voor de video's van haar gebruikers.</target>
361 <context-group name="null">
362 <context context-type="linenumber">31</context>
363 </context-group>
364 </trans-unit>
365 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
366 <source>
367 User registration is currently not allowed.
368 </source>
369 <target>Een account maken is momenteel niet toegelaten op deze instantie.</target>
370 <context-group name="null">
371 <context context-type="linenumber">36</context>
372 </context-group> 1001 </context-group>
373 </trans-unit> 1002 </trans-unit>
374 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 1003 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
375 <source> 1004 <source>
376 About PeerTube 1005 About PeerTube
377</source> 1006</source>
378 <target>Over PeerTube</target> 1007 <target>
1008Over PeerTube
1009
1010</target>
379 <context-group name="null"> 1011 <context-group name="null">
380 <context context-type="linenumber">1</context> 1012 <context context-type="linenumber">1</context>
381 </context-group> 1013 </context-group>
@@ -391,7 +1023,8 @@
391 <source> 1023 <source>
392 It is a free and open-source software, under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>AGPLv3 licence<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>. 1024 It is a free and open-source software, under the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>AGPLv3 licence<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.
393 </source> 1025 </source>
394 <target>Het is vrije en open-source software, beschikbaar onder de <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>AGPLv3<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target> 1026 <target>
1027Het is vrije en open-source software, beschikbaar onder de <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>AGPLv3 licentie<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
395 <context-group name="null"> 1028 <context-group name="null">
396 <context context-type="linenumber">8</context> 1029 <context context-type="linenumber">8</context>
397 </context-group> 1030 </context-group>
@@ -400,7 +1033,8 @@
400 <source> 1033 <source>
401 For more information, please visit <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>joinpeertube.org<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>. 1034 For more information, please visit <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>joinpeertube.org<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.
402 </source> 1035 </source>
403 <target>Kijk voor meer informatie op <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>joinpeertube.org<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target> 1036 <target>
1037Kijk voor meer informatie op <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>joinpeertube.org<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
404 <context-group name="null"> 1038 <context-group name="null">
405 <context context-type="linenumber">12</context> 1039 <context context-type="linenumber">12</context>
406 </context-group> 1040 </context-group>
@@ -417,7 +1051,8 @@
417 PeerTube uses the BitTorrent protocol to share bandwidth between users. 1051 PeerTube uses the BitTorrent protocol to share bandwidth between users.
418 This implies that your IP address is stored in the instance's BitTorrent tracker as long as you download or watch the video. 1052 This implies that your IP address is stored in the instance's BitTorrent tracker as long as you download or watch the video.
419 </source> 1053 </source>
420 <target>PeerTube gebruikt het BitTorrent-protocol om bandbreedte tussen gebruikers te delen. Dat betekent ook dat jouw IP-adres bijgehouden wordt in de BitTorrent-tracker van de PeerTube-instantie zolang je de video aan het bekijken bent.</target> 1054 <target>
1055PeerTube gebruikt het BitTorrent-protocol om bandbreedte tussen gebruikers te delen. Dat betekent ook dat jouw IP-adres bijgehouden wordt in de BitTorrent-tracker van de PeerTube-instantie zolang je de video aan het bekijken bent.</target>
421 <context-group name="null"> 1056 <context-group name="null">
422 <context context-type="linenumber">20</context> 1057 <context context-type="linenumber">20</context>
423 </context-group> 1058 </context-group>
@@ -434,7 +1069,8 @@
434 In theory, someone with enough technical skills could create a script that tracks which IP is downloading which video. 1069 In theory, someone with enough technical skills could create a script that tracks which IP is downloading which video.
435 In practice, this is much more difficult because: 1070 In practice, this is much more difficult because:
436 </source> 1071 </source>
437 <target>In theorie kan iemand met technische kennis een script maken dat bijhoudt welk IP-adres welke video aan het downloaden is. In de praktijk is dat wat moeilijker:</target> 1072 <target>
1073In theorie kan iemand met technische kennis een script maken dat bijhoudt welk IP-adres welke video aan het downloaden is. In de praktijk is dat wat moeilijker omdat:</target>
438 <context-group name="null"> 1074 <context-group name="null">
439 <context context-type="linenumber">27</context> 1075 <context context-type="linenumber">27</context>
440 </context-group> 1076 </context-group>
@@ -444,7 +1080,8 @@
444 An HTTP request has to be sent on each tracker for each video to spy. 1080 An HTTP request has to be sent on each tracker for each video to spy.
445 If we want to spy all PeerTube's videos, we have to send as many requests as there are videos (so potentially a lot) 1081 If we want to spy all PeerTube's videos, we have to send as many requests as there are videos (so potentially a lot)
446 </source> 1082 </source>
447 <target>Voor elke video waarvan hij de kijkers wil bespioneren, moet hij een apart HTTP-request sturen. Om dat voor alle PeerTube-videos te doen, moeten er dus evenveel HTTP-requests als video's gebruikt worden (dat kan hoog oplopen).</target> 1083 <target>
1084Voor elke video waarvan hij de kijkers wil bespioneren, moet hij een apart HTTP-request sturen. Om dat voor alle PeerTube-videos te doen, moeten er dus evenveel HTTP-requests als video's gebruikt worden (dat kan hoog oplopen).</target>
448 <context-group name="null"> 1085 <context-group name="null">
449 <context context-type="linenumber">33</context> 1086 <context context-type="linenumber">33</context>
450 </context-group> 1087 </context-group>
@@ -454,7 +1091,8 @@
454 For each request sent, the tracker returns random peers at a limited number. 1091 For each request sent, the tracker returns random peers at a limited number.
455 For instance, if there are 1000 peers in the swarm and the tracker sends only 20 peers for each request, there must be at least 50 requests sent to know every peers in the swarm 1092 For instance, if there are 1000 peers in the swarm and the tracker sends only 20 peers for each request, there must be at least 50 requests sent to know every peers in the swarm
456 </source> 1093 </source>
457 <target>Voor elk request geeft de tracker een beperkt aantal willekeurige peers terug. Als er bijvoorbeeld 1000 peers beschikbaar zijn en de tracker steeds 20 peers teruggeeft, moeten er op zijn minst 50 requests gestuurd worden om alle peers te weten te komen.</target> 1094 <target>
1095Voor elk request geeft de tracker een beperkt aantal willekeurige peers terug. Als er bijvoorbeeld 1000 peers beschikbaar zijn en de tracker steeds 20 peers teruggeeft, moeten er op zijn minst 50 requests gestuurd worden om alle peers te weten te komen.</target>
458 <context-group name="null"> 1096 <context-group name="null">
459 <context context-type="linenumber">38</context> 1097 <context context-type="linenumber">38</context>
460 </context-group> 1098 </context-group>
@@ -463,7 +1101,8 @@
463 <source> 1101 <source>
464 Those requests have to be sent regularly to know who starts/stops watching a video. It is easy to detect that kind of behaviour 1102 Those requests have to be sent regularly to know who starts/stops watching a video. It is easy to detect that kind of behaviour
465 </source> 1103 </source>
466 <target>Die requests moeten regelmatig herhaald worden om te kunnen achterhalen wie begint of stopt met een video te bekijken. Het is gemakkelijk om zulk gedrag te detecteren.</target> 1104 <target>
1105Die requests moeten regelmatig herhaald worden om te kunnen achterhalen wie begint of stopt met een video te kijken. Het is gemakkelijk om zulk gedrag te detecteren.</target>
467 <context-group name="null"> 1106 <context-group name="null">
468 <context context-type="linenumber">43</context> 1107 <context context-type="linenumber">43</context>
469 </context-group> 1108 </context-group>
@@ -472,7 +1111,8 @@
472 <source> 1111 <source>
473 If an IP address is stored in the tracker, it doesn't mean that the person behind the IP (if this person exists) has watched the video 1112 If an IP address is stored in the tracker, it doesn't mean that the person behind the IP (if this person exists) has watched the video
474 </source> 1113 </source>
475 <target>Als een IP-adres opgeslagen is in de tracker, betekent dat niet dat de persoon achter dat adres (als die persoon bestaat) de video bekeken heeft</target> 1114 <target>
1115Als een IP-adres opgeslagen is in de tracker, betekent dat niet dat de persoon achter dat adres (als die persoon bestaat) de video bekeken heeft</target>
476 <context-group name="null"> 1116 <context-group name="null">
477 <context context-type="linenumber">47</context> 1117 <context context-type="linenumber">47</context>
478 </context-group> 1118 </context-group>
@@ -481,24 +1121,169 @@
481 <source> 1121 <source>
482 The IP address is a vague information : usually, it regularly changes and can represent many persons or entities 1122 The IP address is a vague information : usually, it regularly changes and can represent many persons or entities
483 </source> 1123 </source>
484 <target>Een IP-adres is vage </target> 1124 <target>
1125Een IP-adres is vage informatie: Meestal veranderd het regelmatig en kan het meerdere personen en identiteiten representeren</target>
485 <context-group name="null"> 1126 <context-group name="null">
486 <context context-type="linenumber">51</context> 1127 <context context-type="linenumber">51</context>
487 </context-group> 1128 </context-group>
488 </trans-unit> 1129 </trans-unit>
1130 <trans-unit id="b4c2ef0143270626106b26196d40baf3439aa7b0">
1131 <source>
1132 Web peers are not publicly accessible: because we use WebRTC inside the web browser (<x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>with the WebTorrent library<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>), the protocol is different from classic BitTorrent.
1133 When you are in a web browser, you send a signal containing your IP address to the tracker that will randomly choose other peers to forward the information to.
1134 See <x id="START_LINK_1" ctype="x-a" equiv-text="&lt;a&gt;"/>this document<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> for more information
1135 </source>
1136 <target>
1137Web peers zijn niet openbaar bereikbaar: omdat we WebRTC in de webbrowser gebruiken (<x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>met de WebTorrent-bibliotheek<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>), is het protocol anders dan in klassieke BitTorrent.
1138 Wanneer je in een webbrowser zit, verstuur je een signaal die je IP adres bevat naar de tracker die willekeurig andere peers kiest om de informatie heen te sturen.
1139 See <x id="START_LINK_1" ctype="x-a" equiv-text="&lt;a&gt;"/>dit document<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> voor meer informatie</target>
1140 <context-group name="null">
1141 <context context-type="linenumber">55</context>
1142 </context-group>
1143 </trans-unit>
1144 <trans-unit id="50d8e8388f5ceab292850ed828f306c9f2cab389">
1145 <source>
1146 The worst-case scenario of an average person spying on their friends is quite unlikely.
1147 There are much more effective ways to get that kind of information.
1148 </source>
1149 <target>
1150Het worst-case scenario dat kan gebeuren van een gemiddeld persoon die hun vrienden bespioneert is erg onwaarschijnlijk.
1151Er zijn veel effectievere manieren om dat soort informatie te verkrijgen.</target>
1152 <context-group name="null">
1153 <context context-type="linenumber">62</context>
1154 </context-group>
1155 </trans-unit>
1156 <trans-unit id="4bf47a1ae952bf42a4682a5ecddb0bfb8c9adfaf">
1157 <source>How does PeerTube compare with YouTube?</source>
1158 <target>Hoe is PeerTube vergeleken met YouTube?</target>
1159 <context-group name="null">
1160 <context context-type="linenumber">67</context>
1161 </context-group>
1162 </trans-unit>
1163 <trans-unit id="2432705cbabcb92a8677338901dd5d655383ef4c">
1164 <source>
1165 The threats to privacy in YouTube are different from PeerTube's.
1166 In YouTube's case, the platform gathers a huge amount of your personal information (not only your IP) to analyze them and track you.
1167 Moreover, YouTube is owned by Google/Alphabet, a company that tracks you across many websites (via AdSense or Google Analytics).
1168 </source>
1169 <target>
1170De bedreigingen tegen privacy in YouTube zijn verschillend dan in PeerTube's geval.
1171In YouTube's geval, verzamelt het platform een gigantisch aantal persoonlijke informatie (niet alleen je IP) om te analyseren en om je te tracken.
1172Verder nog, YouTube is eigendom van Google/Alphabet, een bedrijf die je trackt over meerdere websites (via AdSense of Google Analytics).</target>
1173 <context-group name="null">
1174 <context context-type="linenumber">69</context>
1175 </context-group>
1176 </trans-unit>
1177 <trans-unit id="3c2990d5e452bdf2317ff23745db70705d848d99">
1178 <source>What can I do to limit the exposure of my IP address?</source>
1179 <target>Wat kan ik doen om de blootstelling van mijn IP adress te verminderen?</target>
1180 <context-group name="null">
1181 <context context-type="linenumber">75</context>
1182 </context-group>
1183 </trans-unit>
489 <trans-unit id="a545356de272b955258c2a2432b08ec637b65f7e"> 1184 <trans-unit id="a545356de272b955258c2a2432b08ec637b65f7e">
490 <source> 1185 <source>
491 Your IP address is public so every time you consult a website, there is a number of actors (in addition to the final website) seeing your IP in their connection logs: ISP/routers/trackers/CDN and more. 1186 Your IP address is public so every time you consult a website, there is a number of actors (in addition to the final website) seeing your IP in their connection logs: ISP/routers/trackers/CDN and more.
492 PeerTube is transparent about it: we warn you that if you want to keep your IP private, you must use a VPN or Tor Browser. 1187 PeerTube is transparent about it: we warn you that if you want to keep your IP private, you must use a VPN or Tor Browser.
493 Thinking that removing P2P from PeerTube will give you back anonymity doesn't make sense. 1188 Thinking that removing P2P from PeerTube will give you back anonymity doesn't make sense.
494 </source> 1189 </source>
495 <target>Je IP-adres is geen privé-gegeven. Elke keer je een website bezoekt, is er een aantal entiteiten (bovenop de website die je effectief bezoekt) die je IP zien in hun logs: ISP's, routers, trackers, CDN's en meer. 1190 <target>
496PeerTube is transparant: we waarschuwen je dat je, als je je IP-adres privé wil afschermen, je een VPN of de Tor-Browser moet gebruiken. 1191Je IP-adres is openbaar dus elke keer dat je een website bezoekt, zijn er een aantal actoren (bovenop de website die je effectief bezoekt) die je IP zien in hun logs: ISP/routers/trackers/CDN en meer.
497Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit geven.</target> 1192PeerTube is daarover transparant: we waarschuwen je dat je, als je je IP-adres wil afschermen, je een VPN of de Tor-Browser moet gebruiken.
1193Denken dat het P2P-mechanisme uit PeerTube halen je anonimiteit terug zou geven is onlogisch.</target>
498 <context-group name="null"> 1194 <context-group name="null">
499 <context context-type="linenumber">77</context> 1195 <context context-type="linenumber">77</context>
500 </context-group> 1196 </context-group>
501 </trans-unit> 1197 </trans-unit>
1198 <trans-unit id="8ce78dd287b9a9dde5079916425ea66466530e41">
1199 <source>What will be done to mitigate this problem?</source>
1200 <target>Wat zal worden gedaan om dit probleem te verminderen?</target>
1201 <context-group name="null">
1202 <context context-type="linenumber">83</context>
1203 </context-group>
1204 </trans-unit>
1205 <trans-unit id="b1372cb61ca791a0f7f95bf31c86c97df142adc4">
1206 <source>
1207 PeerTube is in its early stages, and want to deliver the best countermeasures possible by the time the stable is released.
1208 In the meantime, we want to test different ideas related to this issue:
1209 </source>
1210 <target>
1211PeerTube is in haar ontwikkelingsfasen, en wilt de beste tegenmaatregelen mogelijk geven tegen de tijd dat de stabiele versie is gereleased.
1212Ondertussen willen we verschillende ideeën testen die gerelateerd zijn aan dit probleem:</target>
1213 <context-group name="null">
1214 <context context-type="linenumber">85</context>
1215 </context-group>
1216 </trans-unit>
1217 <trans-unit id="d32608aba08c6bb3cc4e4e8ec6223e5f4e78ca19">
1218 <source>Set a limit to the number of peers sent by the tracker</source>
1219 <target>Zet een limiet op het aantal peers verzonden door de tracker</target>
1220 <context-group name="null">
1221 <context context-type="linenumber">91</context>
1222 </context-group>
1223 </trans-unit>
1224 <trans-unit id="a6d732b614143f862e69798046dc0868716547e5">
1225 <source>Set a limit on the request frequency received by the tracker (being tested)</source>
1226 <target>Zet een limiet op de verzoekfrequentie verkregen door de tracker (wordt getest)</target>
1227 <context-group name="null">
1228 <context context-type="linenumber">92</context>
1229 </context-group>
1230 </trans-unit>
1231 <trans-unit id="ba77e356eaa5c06caaf5c8734c361d1a5415fe1c">
1232 <source>Ring a bell if there are unusual requests (being tested)</source>
1233 <target>Laat iets horen als er ongebruikelijke requests zijn (wordt getest)</target>
1234 <context-group name="null">
1235 <context context-type="linenumber">93</context>
1236 </context-group>
1237 </trans-unit>
1238 <trans-unit id="81861ff8a71c8a5881cdf66417f3bddb753f0e18">
1239 <source>Disable P2P from the administration interface</source>
1240 <target>Schakel P2P uit vanuit het administratieinterface</target>
1241 <context-group name="null">
1242 <context context-type="linenumber">94</context>
1243 </context-group>
1244 </trans-unit>
1245 <trans-unit id="efde279863678ed95a8949a3712c99748bdabfe6">
1246 <source>An automatic video redundancy program: we wouldn't know if the IP downloaded the video on purpose or if it was the automatized program</source>
1247 <target>Een automatisch video-overbodigheidsprogramma: we zouden niet weten of het IP de video met opzet heeft gedownload, of als het een geautomatiseerd programma was.</target>
1248 <context-group name="null">
1249 <context context-type="linenumber">95</context>
1250 </context-group>
1251 </trans-unit>
1252 <trans-unit id="bd2edf99dd6562385ccec19a7ab2d1898e626605">
1253 <source>Banned</source>
1254 <target>Verbannen</target>
1255 <context-group name="null">
1256 <context context-type="linenumber">12</context>
1257 </context-group>
1258 </trans-unit>
1259 <trans-unit id="62a557fcfdbd25a31d1a0332294f94a466fee809">
1260 <source>Muted</source>
1261 <target>Gedempt</target>
1262 <context-group name="null">
1263 <context context-type="linenumber">13</context>
1264 </context-group>
1265 </trans-unit>
1266 <trans-unit id="48bbf6dbdb22e0ef4bd257eae2ab356f2ea66c89">
1267 <source>Muted by your instance</source>
1268 <target>Gedempt door jouw instantie</target>
1269 <context-group name="null">
1270 <context context-type="linenumber">14</context>
1271 </context-group>
1272 </trans-unit>
1273 <trans-unit id="44bd08a7ec1e407356620967d65d8fe2d8639d0a">
1274 <source>Instance muted</source>
1275 <target>Instantie gedempt</target>
1276 <context-group name="null">
1277 <context context-type="linenumber">15</context>
1278 </context-group>
1279 </trans-unit>
1280 <trans-unit id="1a6443bb7ed01046dd83cf78806f795f1204ffa1">
1281 <source>Instance muted by your instance</source>
1282 <target>Instantie gedempt door jouw instantie</target>
1283 <context-group name="null">
1284 <context context-type="linenumber">16</context>
1285 </context-group>
1286 </trans-unit>
502 <trans-unit id="a835d8a12e14eb96919245a0bbafd8069c146578"> 1287 <trans-unit id="a835d8a12e14eb96919245a0bbafd8069c146578">
503 <source><x id="INTERPOLATION" equiv-text="{{ account.followersCount }}"/> subscribers</source> 1288 <source><x id="INTERPOLATION" equiv-text="{{ account.followersCount }}"/> subscribers</source>
504 <target><x id="INTERPOLATION" equiv-text="{{ account.followersCount }}"/> abonnees</target> 1289 <target><x id="INTERPOLATION" equiv-text="{{ account.followersCount }}"/> abonnees</target>
@@ -552,42 +1337,49 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
552 <source>Short description</source> 1337 <source>Short description</source>
553 <target>Korte omschrijving</target> 1338 <target>Korte omschrijving</target>
554 <context-group name="null"> 1339 <context-group name="null">
555 <context context-type="linenumber">22</context> 1340 <context context-type="linenumber">21</context>
556 </context-group> 1341 </context-group>
557 </trans-unit> 1342 </trans-unit>
558 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1343 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
559 <source>Default client route</source> 1344 <source>Default client route</source>
560 <target>Startpagina</target> 1345 <target>Startpagina</target>
561 <context-group name="null"> 1346 <context-group name="null">
562 <context context-type="linenumber">55</context> 1347 <context context-type="linenumber">48</context>
1348 </context-group>
1349 </trans-unit>
1350 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1351 <source>Videos Overview</source>
1352 <target>Video-overzicht</target>
1353 <context-group name="null">
1354 <context context-type="linenumber">51</context>
563 </context-group> 1355 </context-group>
564 </trans-unit> 1356 </trans-unit>
565 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1357 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
566 <source>Videos Trending</source> 1358 <source>Videos Trending</source>
567 <target>Populaire video's</target> 1359 <target>Populaire video's</target>
568 <context-group name="null"> 1360 <context-group name="null">
569 <context context-type="linenumber">59</context> 1361 <context context-type="linenumber">52</context>
570 </context-group> 1362 </context-group>
571 </trans-unit> 1363 </trans-unit>
572 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1364 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
573 <source>Videos Recently Added</source> 1365 <source>Videos Recently Added</source>
574 <target>Recent toegevoegde video's</target> 1366 <target>Recent toegevoegde video's</target>
575 <context-group name="null"> 1367 <context-group name="null">
576 <context context-type="linenumber">60</context> 1368 <context context-type="linenumber">53</context>
577 </context-group> 1369 </context-group>
578 </trans-unit> 1370 </trans-unit>
579 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1371 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
580 <source>Local videos</source> 1372 <source>Local videos</source>
581 <target>Video's op deze instantie</target> 1373 <target>Video's op deze instantie</target>
582 <context-group name="null"> 1374 <context-group name="null">
583 <context context-type="linenumber">61</context> 1375 <context context-type="linenumber">54</context>
584 </context-group> 1376 </context-group>
585 </trans-unit> 1377 </trans-unit>
586 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1378 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
587 <source>Policy on videos containing sensitive content</source> 1379 <source>Policy on videos containing sensitive content</source>
588 <target>Beleid rond video's met gevoelige inhoud</target> 1380 <target>Beleid rond video's met gevoelige inhoud</target>
589 <context-group name="null"> 1381 <context-group name="null">
590 <context context-type="linenumber">70</context> 1382 <context context-type="linenumber">61</context>
591 </context-group> 1383 </context-group>
592 </trans-unit> 1384 </trans-unit>
593 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1385 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -622,42 +1414,77 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
622 <source>Signup enabled</source> 1414 <source>Signup enabled</source>
623 <target>Registratie mogelijk</target> 1415 <target>Registratie mogelijk</target>
624 <context-group name="null"> 1416 <context-group name="null">
625 <context context-type="linenumber">93</context> 1417 <context context-type="linenumber">84</context>
1418 </context-group>
1419 </trans-unit>
1420 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1421 <source>Signup requires email verification</source>
1422 <target>E-mailverificatie nodig bij registratie</target>
1423 <context-group name="null">
1424 <context context-type="linenumber">91</context>
626 </context-group> 1425 </context-group>
627 </trans-unit> 1426 </trans-unit>
628 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1427 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
629 <source>Signup limit</source> 1428 <source>Signup limit</source>
630 <target>Registratielimiet</target> 1429 <target>Registratielimiet</target>
631 <context-group name="null"> 1430 <context-group name="null">
1431 <context context-type="linenumber">96</context>
1432 </context-group>
1433 </trans-unit>
1434 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1435 <source>Users</source>
1436 <target>Gebruikers</target>
1437 <context-group name="null">
632 <context context-type="linenumber">105</context> 1438 <context context-type="linenumber">105</context>
633 </context-group> 1439 </context-group>
634 </trans-unit> 1440 </trans-unit>
635 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1441 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
636 <source>Administrator</source> 1442 <source>User default video quota</source>
637 <target>Beheerder</target> 1443 <target>Standaard video-quotum voor gebruikers</target>
638 <context-group name="null"> 1444 <context-group name="null">
639 <context context-type="linenumber">131</context> 1445 <context context-type="linenumber">109</context>
640 </context-group> 1446 </context-group>
641 </trans-unit> 1447 </trans-unit>
642 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1448 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
643 <source>Admin email</source> 1449 <source>User default daily upload limit</source>
644 <target>E-mail van beheerder</target> 1450 <target>Standaard dagelijks video-quotum voor gebruikers</target>
645 <context-group name="null"> 1451 <context-group name="null">
646 <context context-type="linenumber">134</context> 1452 <context context-type="linenumber">121</context>
647 </context-group> 1453 </context-group>
648 </trans-unit> 1454 </trans-unit>
649 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be"> 1455 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
650 <source>Users</source> 1456 <source>Import</source>
651 <target>Gebruikers</target> 1457 <target>Importeren</target>
652 <context-group name="null"> 1458 <context-group name="null">
653 <context context-type="linenumber">144</context> 1459 <context context-type="linenumber">42</context>
654 </context-group> 1460 </context-group>
655 </trans-unit> 1461 </trans-unit>
656 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09"> 1462 <trans-unit id="29aa67f13fd34a2421ff9d7de7d5142790676b9e">
657 <source>User default video quota</source> 1463 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
658 <target>Standaard video-quotum voor gebruikers</target> 1464 <target>Video-import met HTTP URL (d.w.z. YouTube) ingeschakeld</target>
659 <context-group name="null"> 1465 <context-group name="null">
660 <context context-type="linenumber">147</context> 1466 <context context-type="linenumber">141</context>
1467 </context-group>
1468 </trans-unit>
1469 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e">
1470 <source>Video import with a torrent file or a magnet URI enabled</source>
1471 <target>Video-import met een torrentbestand of een magnet URL ingeschakeld</target>
1472 <context-group name="null">
1473 <context context-type="linenumber">148</context>
1474 </context-group>
1475 </trans-unit>
1476 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1477 <source>Administrator</source>
1478 <target>Administrator</target>
1479 <context-group name="null">
1480 <context context-type="linenumber">155</context>
1481 </context-group>
1482 </trans-unit>
1483 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1484 <source>Admin email</source>
1485 <target>E-mail van administrator</target>
1486 <context-group name="null">
1487 <context context-type="linenumber">158</context>
661 </context-group> 1488 </context-group>
662 </trans-unit> 1489 </trans-unit>
663 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1490 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -678,21 +1505,21 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
678 <source>Your Twitter username</source> 1505 <source>Your Twitter username</source>
679 <target>Je Twitter-gebruikersnaam</target> 1506 <target>Je Twitter-gebruikersnaam</target>
680 <context-group name="null"> 1507 <context-group name="null">
681 <context context-type="linenumber">181</context> 1508 <context context-type="linenumber">184</context>
682 </context-group> 1509 </context-group>
683 </trans-unit> 1510 </trans-unit>
684 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1511 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
685 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1512 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
686 <target>Geeft het Twitter-account aan voor de website of het platform waarop de inhoud gepubliceerd werd.</target> 1513 <target>Geeft het Twitter-account aan voor de website of het platform waarop de inhoud gepubliceerd werd.</target>
687 <context-group name="null"> 1514 <context-group name="null">
688 <context context-type="linenumber">184</context> 1515 <context context-type="linenumber">187</context>
689 </context-group> 1516 </context-group>
690 </trans-unit> 1517 </trans-unit>
691 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1518 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
692 <source>Instance whitelisted by Twitter</source> 1519 <source>Instance whitelisted by Twitter</source>
693 <target>Instantie ge-whitelist door Twitter</target> 1520 <target>Instantie gewhitelist door Twitter</target>
694 <context-group name="null"> 1521 <context-group name="null">
695 <context context-type="linenumber">198</context> 1522 <context context-type="linenumber">199</context>
696 </context-group> 1523 </context-group>
697 </trans-unit> 1524 </trans-unit>
698 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1525 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -706,77 +1533,120 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
706 <source>Transcoding</source> 1533 <source>Transcoding</source>
707 <target>Transcoding</target> 1534 <target>Transcoding</target>
708 <context-group name="null"> 1535 <context-group name="null">
709 <context context-type="linenumber">210</context> 1536 <context context-type="linenumber">215</context>
710 </context-group> 1537 </context-group>
711 </trans-unit> 1538 </trans-unit>
712 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1539 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
713 <source>Transcoding enabled</source> 1540 <source>Transcoding enabled</source>
714 <target>Transcoding ingeschakeld</target> 1541 <target>Transcoding ingeschakeld</target>
715 <context-group name="null"> 1542 <context-group name="null">
716 <context context-type="linenumber">215</context> 1543 <context context-type="linenumber">221</context>
717 </context-group> 1544 </context-group>
718 </trans-unit> 1545 </trans-unit>
719 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1546 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
720 <source>If you disable transcoding, many videos from your users will not work!</source> 1547 <source>If you disable transcoding, many videos from your users will not work!</source>
721 <target>Als je transcoding niet inschakelt, zullen veel video's die je gebruikers uploaden niet overal werken!</target> 1548 <target>Als je transcoding niet inschakelt, zullen veel video's die je gebruikers uploaden niet werken!</target>
722 <context-group name="null"> 1549 <context-group name="null">
723 <context context-type="linenumber">216</context> 1550 <context context-type="linenumber">222</context>
724 </context-group> 1551 </context-group>
725 </trans-unit> 1552 </trans-unit>
726 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1553 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
727 <source>Transcoding threads</source> 1554 <source>Transcoding threads</source>
728 <target>Threads gebruikt voor transcoding</target> 1555 <target>Threads gebruikt voor transcoding</target>
729 <context-group name="null"> 1556 <context-group name="null">
730 <context context-type="linenumber">223</context> 1557 <context context-type="linenumber">237</context>
1558 </context-group>
1559 </trans-unit>
1560 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1561 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1562 <target>Resolutie <x id="INTERPOLATION" equiv-text="{{resolution}}"/> ingeschakeld</target>
1563 <context-group name="null">
1564 <context context-type="linenumber">252</context>
1565 </context-group>
1566 </trans-unit>
1567 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
1568 <source>
1569 Cache
1570
1571 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1572 </source>
1573 <target>
1574Cache
1575
1576 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/></target>
1577 <context-group name="null">
1578 <context context-type="linenumber">260</context>
1579 </context-group>
1580 </trans-unit>
1581 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1582 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1583 <target>Sommige bestanden zijn niet federaal (voorbeelden, ondertitelingen). We verkrijgen ze direct van hun afkomstige instantie en cachen ze.</target>
1584 <context-group name="null">
1585 <context context-type="linenumber">265</context>
731 </context-group> 1586 </context-group>
732 </trans-unit> 1587 </trans-unit>
733 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1588 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
734 <source>Previews cache size</source> 1589 <source>Previews cache size</source>
735 <target>Cachegrootte voor previews</target> 1590 <target>Cachegrootte voor previews</target>
736 <context-group name="null"> 1591 <context-group name="null">
737 <context context-type="linenumber">254</context> 1592 <context context-type="linenumber">271</context>
1593 </context-group>
1594 </trans-unit>
1595 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1596 <source>Video captions cache size</source>
1597 <target>Cachegrootte van video-ondertiteling</target>
1598 <context-group name="null">
1599 <context context-type="linenumber">280</context>
738 </context-group> 1600 </context-group>
739 </trans-unit> 1601 </trans-unit>
740 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1602 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
741 <source>Customizations</source> 1603 <source>Customizations</source>
742 <target>Aanpassingen</target> 1604 <target>Aanpassingen</target>
743 <context-group name="null"> 1605 <context-group name="null">
744 <context context-type="linenumber">275</context> 1606 <context context-type="linenumber">289</context>
745 </context-group> 1607 </context-group>
746 </trans-unit> 1608 </trans-unit>
747 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1609 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
748 <source>JavaScript</source> 1610 <source>JavaScript</source>
749 <target>JavaScript</target> 1611 <target>JavaScript</target>
750 <context-group name="null"> 1612 <context-group name="null">
751 <context context-type="linenumber">278</context> 1613 <context context-type="linenumber">294</context>
752 </context-group> 1614 </context-group>
753 </trans-unit> 1615 </trans-unit>
754 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1616 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
755 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1617 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
756 <target>Schrijf JavaScriptcode.&lt;br /&gt;Voorbeeld: &lt;pre&gt;console.log('mijn instantie is fantastisch');&lt;/pre&gt;</target> 1618 <target>Schrijf direct JavaScriptcode.&lt;br /&gt;Bijvoorbeeld: &lt;pre&gt;console.log('mijn instantie is fantastisch');&lt;/pre&gt;</target>
757 <context-group name="null"> 1619 <context-group name="null">
758 <context context-type="linenumber">281</context> 1620 <context context-type="linenumber">297</context>
759 </context-group> 1621 </context-group>
760 </trans-unit> 1622 </trans-unit>
761 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab"> 1623 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab">
762 <source>Advanced configuration</source> 1624 <source>Advanced configuration</source>
763 <target>Geavanceerde configuratie</target> 1625 <target>Geavanceerde configuratie</target>
764 <context-group name="null"> 1626 <context-group name="null">
765 <context context-type="linenumber">207</context> 1627 <context context-type="linenumber">212</context>
766 </context-group> 1628 </context-group>
767 </trans-unit> 1629 </trans-unit>
768 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1630 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
769 <source>Update configuration</source> 1631 <source>Update configuration</source>
770 <target>Updateconfiguratie</target> 1632 <target>Bijwerkingsconfiguratie</target>
771 <context-group name="null"> 1633 <context-group name="null">
772 <context context-type="linenumber">325</context> 1634 <context context-type="linenumber">340</context>
1635 </context-group>
1636 </trans-unit>
1637 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1638 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1639 <target>Het lijkt erop dat de configuratie invalide is. Zoek alstublieft potentiële foutmeldingen op in andere tabbladen.</target>
1640 <context-group name="null">
1641 <context context-type="linenumber">341</context>
773 </context-group> 1642 </context-group>
774 </trans-unit> 1643 </trans-unit>
775 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1644 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
776 <source> 1645 <source>
777 Users 1646 Users
778 </source> 1647 </source>
779 <target>Gebruikers</target> 1648 <target>
1649Gebruikers</target>
780 <context-group name="null"> 1650 <context-group name="null">
781 <context context-type="linenumber">3</context> 1651 <context context-type="linenumber">3</context>
782 </context-group> 1652 </context-group>
@@ -785,16 +1655,28 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
785 <source> 1655 <source>
786 Manage follows 1656 Manage follows
787 </source> 1657 </source>
788 <target>Volgers beheren</target> 1658 <target>
1659Volgers beheren</target>
789 <context-group name="null"> 1660 <context-group name="null">
790 <context context-type="linenumber">7</context> 1661 <context context-type="linenumber">7</context>
791 </context-group> 1662 </context-group>
792 </trans-unit> 1663 </trans-unit>
1664 <trans-unit id="1a5c7f9b1bec1463728f44933f0e256de9c45154">
1665 <source>
1666 Moderation
1667 </source>
1668 <target>
1669Moderatie</target>
1670 <context-group name="null">
1671 <context context-type="linenumber">11</context>
1672 </context-group>
1673 </trans-unit>
793 <trans-unit id="7bea88c54fdccfdc9f687b0ffe9bf6a653d19368"> 1674 <trans-unit id="7bea88c54fdccfdc9f687b0ffe9bf6a653d19368">
794 <source> 1675 <source>
795 Jobs 1676 Jobs
796 </source> 1677 </source>
797 <target>Jobs</target> 1678 <target>
1679Banen</target>
798 <context-group name="null"> 1680 <context-group name="null">
799 <context context-type="linenumber">15</context> 1681 <context context-type="linenumber">15</context>
800 </context-group> 1682 </context-group>
@@ -803,7 +1685,8 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
803 <source> 1685 <source>
804 Configuration 1686 Configuration
805 </source> 1687 </source>
806 <target>Configuratie</target> 1688 <target>
1689Configuratie</target>
807 <context-group name="null"> 1690 <context-group name="null">
808 <context context-type="linenumber">19</context> 1691 <context context-type="linenumber">19</context>
809 </context-group> 1692 </context-group>
@@ -819,18 +1702,26 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
819 <source> 1702 <source>
820 It seems that you are not on a HTTPS server. Your webserver needs to have TLS activated in order to follow servers. 1703 It seems that you are not on a HTTPS server. Your webserver needs to have TLS activated in order to follow servers.
821 </source> 1704 </source>
822 <target>Het ziet ernaar uit dat je op een server bent zonder HTTPS. Op je webserver moet TLS geactiveerd zijn om servers te kunnen volgen.</target> 1705 <target>
1706Het ziet ernaar uit dat je op een server bent zonder HTTPS. Op je webserver moet TLS geactiveerd zijn om servers te kunnen volgen.</target>
823 <context-group name="null"> 1707 <context-group name="null">
824 <context context-type="linenumber">17</context> 1708 <context context-type="linenumber">17</context>
825 </context-group> 1709 </context-group>
826 </trans-unit> 1710 </trans-unit>
827 <trans-unit id="456c6383d8e7cd15aadbcdc196d4ae7a70092437"> 1711 <trans-unit id="456c6383d8e7cd15aadbcdc196d4ae7a70092437">
828 <source>Add following</source> 1712 <source>Add following</source>
829 <target>Abonneren</target> 1713 <target>Voeg volgend toe</target>
830 <context-group name="null"> 1714 <context-group name="null">
831 <context context-type="linenumber">21</context> 1715 <context context-type="linenumber">21</context>
832 </context-group> 1716 </context-group>
833 </trans-unit> 1717 </trans-unit>
1718 <trans-unit id="25925fc5826bc5b3eeae7c45b08b0ed74b9e2954">
1719 <source>Filter...</source>
1720 <target>Filtreren...</target>
1721 <context-group name="null">
1722 <context context-type="linenumber">27</context>
1723 </context-group>
1724 </trans-unit>
834 <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c"> 1725 <trans-unit id="45cc8ca94b5a50842a9a8ef804a5ab089a38ae5c">
835 <source>ID</source> 1726 <source>ID</source>
836 <target>ID</target> 1727 <target>ID</target>
@@ -866,6 +1757,27 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
866 <context context-type="linenumber">11</context> 1757 <context context-type="linenumber">11</context>
867 </context-group> 1758 </context-group>
868 </trans-unit> 1759 </trans-unit>
1760 <trans-unit id="7823909fb1d8d313382f6f4bd842f1a7ef6f08d1">
1761 <source>Accepted</source>
1762 <target>Geaccepteerd</target>
1763 <context-group name="null">
1764 <context context-type="linenumber">32</context>
1765 </context-group>
1766 </trans-unit>
1767 <trans-unit id="e6a27066251ca1e04c5be86ad758380856df2506">
1768 <source>Pending</source>
1769 <target>In behandeling</target>
1770 <context-group name="null">
1771 <context context-type="linenumber">33</context>
1772 </context-group>
1773 </trans-unit>
1774 <trans-unit id="1d729bcbe3529d2fe2295b7a3a41282ee09de2c8">
1775 <source>Redundancy allowed</source>
1776 <target>Overtolligheid toegelaten</target>
1777 <context-group name="null">
1778 <context context-type="linenumber">22</context>
1779 </context-group>
1780 </trans-unit>
869 <trans-unit id="5fccee488a9ea908c16d2ab9dbdaf264f1aac479"> 1781 <trans-unit id="5fccee488a9ea908c16d2ab9dbdaf264f1aac479">
870 <source>Manage follows</source> 1782 <source>Manage follows</source>
871 <target>Abonnementen beheren</target> 1783 <target>Abonnementen beheren</target>
@@ -873,9 +1785,30 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
873 <context context-type="linenumber">2</context> 1785 <context context-type="linenumber">2</context>
874 </context-group> 1786 </context-group>
875 </trans-unit> 1787 </trans-unit>
1788 <trans-unit id="f995df052a1dfc675c2a21926420a707d9601936">
1789 <source>Following</source>
1790 <target>Volgend</target>
1791 <context-group name="null">
1792 <context context-type="linenumber">5</context>
1793 </context-group>
1794 </trans-unit>
1795 <trans-unit id="d29764bcbaad3ef69b6be92be35bdf25972ce246">
1796 <source>Follow</source>
1797 <target>Volg</target>
1798 <context-group name="null">
1799 <context context-type="linenumber">7</context>
1800 </context-group>
1801 </trans-unit>
1802 <trans-unit id="9bee670725966ed477b4c33a545c8b5436b0065e">
1803 <source>Followers</source>
1804 <target>Volgers</target>
1805 <context-group name="null">
1806 <context context-type="linenumber">9</context>
1807 </context-group>
1808 </trans-unit>
876 <trans-unit id="a9f2501fcb2ff71f1376c2d2fbbbd49f200e6c8f"> 1809 <trans-unit id="a9f2501fcb2ff71f1376c2d2fbbbd49f200e6c8f">
877 <source>Jobs list</source> 1810 <source>Jobs list</source>
878 <target>Lijst van jobs</target> 1811 <target>Banenlijst</target>
879 <context-group name="null"> 1812 <context-group name="null">
880 <context context-type="linenumber">2</context> 1813 <context context-type="linenumber">2</context>
881 </context-group> 1814 </context-group>
@@ -887,6 +1820,20 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
887 <context context-type="linenumber">19</context> 1820 <context context-type="linenumber">19</context>
888 </context-group> 1821 </context-group>
889 </trans-unit> 1822 </trans-unit>
1823 <trans-unit id="74c8f69ec23f41a429e241126ab4d25b9d12348e">
1824 <source>Processed on</source>
1825 <target>Behandeld op</target>
1826 <context-group name="null">
1827 <context context-type="linenumber">22</context>
1828 </context-group>
1829 </trans-unit>
1830 <trans-unit id="4fa08915c99629d38c9da8a08b1985a7f4e38e40">
1831 <source>Finished on</source>
1832 <target>Voltooid op</target>
1833 <context-group name="null">
1834 <context context-type="linenumber">23</context>
1835 </context-group>
1836 </trans-unit>
890 <trans-unit id="31cf824034489eb42f6a388d5980b98b8e1de015"> 1837 <trans-unit id="31cf824034489eb42f6a388d5980b98b8e1de015">
891 <source>Create user</source> 1838 <source>Create user</source>
892 <target>Gebruiker aanmaken</target> 1839 <target>Gebruiker aanmaken</target>
@@ -910,7 +1857,7 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
910 </trans-unit> 1857 </trans-unit>
911 <trans-unit id="bb3542ff8e5defa6d0c773799e5c8fe399605d05"> 1858 <trans-unit id="bb3542ff8e5defa6d0c773799e5c8fe399605d05">
912 <source>mail@example.com</source> 1859 <source>mail@example.com</source>
913 <target>mail@example.org</target> 1860 <target>mail@voorbeeld.org</target>
914 <context-group name="null"> 1861 <context-group name="null">
915 <context context-type="linenumber">21</context> 1862 <context context-type="linenumber">21</context>
916 </context-group> 1863 </context-group>
@@ -935,6 +1882,13 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
935 <context context-type="linenumber">65</context> 1882 <context context-type="linenumber">65</context>
936 </context-group> 1883 </context-group>
937 </trans-unit> 1884 </trans-unit>
1885 <trans-unit id="6ded52553dd8720fd3698b8fbc3a6d037c07b496">
1886 <source>Daily video quota</source>
1887 <target>Dagelijks videoquotum</target>
1888 <context-group name="null">
1889 <context context-type="linenumber">72</context>
1890 </context-group>
1891 </trans-unit>
938 <trans-unit id="5e8b4663c17c337a1f11160c0a683350936faa1f"> 1892 <trans-unit id="5e8b4663c17c337a1f11160c0a683350936faa1f">
939 <source>Users list</source> 1893 <source>Users list</source>
940 <target>Gebruikerslijst</target> 1894 <target>Gebruikerslijst</target>
@@ -942,6 +1896,13 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
942 <context context-type="linenumber">2</context> 1896 <context context-type="linenumber">2</context>
943 </context-group> 1897 </context-group>
944 </trans-unit> 1898 </trans-unit>
1899 <trans-unit id="ea762ca1d74c96d8568ac68482778f52ca531cc4">
1900 <source>Batch actions</source>
1901 <target>Batchacties</target>
1902 <context-group name="null">
1903 <context context-type="linenumber">19</context>
1904 </context-group>
1905 </trans-unit>
945 <trans-unit id="08ea8692dc2a7050026df26fc39b22960bde9de5"> 1906 <trans-unit id="08ea8692dc2a7050026df26fc39b22960bde9de5">
946 <source>Username <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 1907 <source>Username <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
947 <target>Gebruikersnaam <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 1908 <target>Gebruikersnaam <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
@@ -949,6 +1910,65 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
949 <context context-type="linenumber">40</context> 1910 <context context-type="linenumber">40</context>
950 </context-group> 1911 </context-group>
951 </trans-unit> 1912 </trans-unit>
1913 <trans-unit id="adba7c8b43e42581460fbe5d08b5cb5ab60eba4b">
1914 <source>(banned)</source>
1915 <target>(verbannen)</target>
1916 <context-group name="null">
1917 <context context-type="linenumber">65</context>
1918 </context-group>
1919 </trans-unit>
1920 <trans-unit id="be73b652c2707f42b5d780d0c7b8fc5ea0b1706c">
1921 <source>Go to the account page</source>
1922 <target>Ga naar accountpagina</target>
1923 <context-group name="null">
1924 <context context-type="linenumber">133</context>
1925 </context-group>
1926 </trans-unit>
1927 <trans-unit id="02ba1a65db92d1d0ab4ba380086e9be61891aaa5">
1928 <source>User's email must be verified to login</source>
1929 <target>Gebruiker's e-mail moet geverifieerd zijn om in te loggen</target>
1930 <context-group name="null">
1931 <context context-type="linenumber">72</context>
1932 </context-group>
1933 </trans-unit>
1934 <trans-unit id="79cee9973620b2592ff2824c525aa8ed0b5e2b8b">
1935 <source>User's email is verified / User can login without email verification</source>
1936 <target>Gebruiker's e-mail is geverifieerd / Gebruiker kan inloggen zonder e-mailverificatie</target>
1937 <context-group name="null">
1938 <context context-type="linenumber">76</context>
1939 </context-group>
1940 </trans-unit>
1941 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee">
1942 <source>Ban reason:</source>
1943 <target>Reden van verbanning:</target>
1944 <context-group name="null">
1945 <context context-type="linenumber">95</context>
1946 </context-group>
1947 </trans-unit>
1948 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
1949 <source>Moderation comment</source>
1950 <target>Beheerdersopmerking</target>
1951 <context-group name="null">
1952 <context context-type="linenumber">3</context>
1953 </context-group>
1954 </trans-unit>
1955 <trans-unit id="5731e5d5ac989bf08848b5a57a5586cf84d80964">
1956 <source>
1957 This comment can only be seen by you or the other moderators.
1958 </source>
1959 <target>
1960Deze opmerking kan alleen door jou en andere beheerders gezien worden.</target>
1961 <context-group name="null">
1962 <context context-type="linenumber">17</context>
1963 </context-group>
1964 </trans-unit>
1965 <trans-unit id="0562e455c88234829f3c27a38f3039f027bfd5d2">
1966 <source>Update this comment</source>
1967 <target>Werk deze comment bij</target>
1968 <context-group name="null">
1969 <context context-type="linenumber">25</context>
1970 </context-group>
1971 </trans-unit>
952 <trans-unit id="2bf5a31043ff476ca081a4080f3f3f17518dc6f2"> 1972 <trans-unit id="2bf5a31043ff476ca081a4080f3f3f17518dc6f2">
953 <source>Reporter</source> 1973 <source>Reporter</source>
954 <target>Melder</target> 1974 <target>Melder</target>
@@ -963,6 +1983,13 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
963 <context context-type="linenumber">14</context> 1983 <context context-type="linenumber">14</context>
964 </context-group> 1984 </context-group>
965 </trans-unit> 1985 </trans-unit>
1986 <trans-unit id="7e7ad19f1bcc2c33cdba4c1ad25e2b398ad453d9">
1987 <source>State <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
1988 <target>Status <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
1989 <context-group name="null">
1990 <context context-type="linenumber">11</context>
1991 </context-group>
1992 </trans-unit>
966 <trans-unit id="c6ab75e099e131d7a4f94e1732e7436d8fc386c7"> 1993 <trans-unit id="c6ab75e099e131d7a4f94e1732e7436d8fc386c7">
967 <source>Go to the account</source> 1994 <source>Go to the account</source>
968 <target>Naar account gaan</target> 1995 <target>Naar account gaan</target>
@@ -977,6 +2004,69 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
977 <context context-type="linenumber">33</context> 2004 <context context-type="linenumber">33</context>
978 </context-group> 2005 </context-group>
979 </trans-unit> 2006 </trans-unit>
2007 <trans-unit id="030b4423b92167200e39519599f9b863b4f7c62c">
2008 <source>Actions</source>
2009 <target>Acties</target>
2010 <context-group name="null">
2011 <context context-type="linenumber">35</context>
2012 </context-group>
2013 </trans-unit>
2014 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
2015 <source>Reason:</source>
2016 <target>Reden:</target>
2017 <context-group name="null">
2018 <context context-type="linenumber">53</context>
2019 </context-group>
2020 </trans-unit>
2021 <trans-unit id="018cbb63c7eda4b82d17dd9058cfaa0fd055c638">
2022 <source>Moderation comment:</source>
2023 <target>Beheerderopmerking:</target>
2024 <context-group name="null">
2025 <context context-type="linenumber">57</context>
2026 </context-group>
2027 </trans-unit>
2028 <trans-unit id="b14fd2fc28c5eecd05554d2bcbc3a938c599e2bf">
2029 <source>Video name <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2030 <target>Videonaam <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2031 <context-group name="null">
2032 <context context-type="linenumber">8</context>
2033 </context-group>
2034 </trans-unit>
2035 <trans-unit id="96dfa3efa02bfafc0bc6d4ab186ebef2813a9e8a">
2036 <source>Sensitive</source>
2037 <target>Gevoelig</target>
2038 <context-group name="null">
2039 <context context-type="linenumber">9</context>
2040 </context-group>
2041 </trans-unit>
2042 <trans-unit id="a7f42da3bb4eea0b71b0a20a2aff6612a82cab99">
2043 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2044 <target>Datum <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2045 <context-group name="null">
2046 <context context-type="linenumber">11</context>
2047 </context-group>
2048 </trans-unit>
2049 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
2050 <source>Blacklist reason:</source>
2051 <target>Reden voor de zwarte lijst:</target>
2052 <context-group name="null">
2053 <context context-type="linenumber">43</context>
2054 </context-group>
2055 </trans-unit>
2056 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
2057 <source>Moderation</source>
2058 <target>Beheer</target>
2059 <context-group name="null">
2060 <context context-type="linenumber">2</context>
2061 </context-group>
2062 </trans-unit>
2063 <trans-unit id="23a793ed0df2e10823dd469c5cea9b5c36be8f7e">
2064 <source>Video abuses</source>
2065 <target>Videomisbruik</target>
2066 <context-group name="null">
2067 <context context-type="linenumber">5</context>
2068 </context-group>
2069 </trans-unit>
980 <trans-unit id="00ecde6001106fe7406a34cc3459cc5b88e4aec1"> 2070 <trans-unit id="00ecde6001106fe7406a34cc3459cc5b88e4aec1">
981 <source>Blacklisted videos</source> 2071 <source>Blacklisted videos</source>
982 <target>Video's op zwarte lijst</target> 2072 <target>Video's op zwarte lijst</target>
@@ -984,18 +2074,39 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
984 <context context-type="linenumber">7</context> 2074 <context context-type="linenumber">7</context>
985 </context-group> 2075 </context-group>
986 </trans-unit> 2076 </trans-unit>
987 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6"> 2077 <trans-unit id="b1ff109b26ae8f08650415454b9098c43eba2e2c">
988 <source>My settings</source> 2078 <source>Muted accounts</source>
989 <target>Mijn instellingen</target> 2079 <target>Gedempte accounts</target>
990 <context-group name="null"> 2080 <context-group name="null">
991 <context context-type="linenumber">3</context> 2081 <context context-type="linenumber">2</context>
992 </context-group> 2082 </context-group>
993 </trans-unit> 2083 </trans-unit>
994 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894"> 2084 <trans-unit id="bd0611346af048015e0a1275091ef68ce98832d2">
995 <source>My videos</source> 2085 <source>Muted servers</source>
996 <target>Mijn video's</target> 2086 <target>Gedempte servers</target>
997 <context-group name="null"> 2087 <context-group name="null">
998 <context context-type="linenumber">14</context> 2088 <context context-type="linenumber">11</context>
2089 </context-group>
2090 </trans-unit>
2091 <trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92">
2092 <source>Account</source>
2093 <target>Account</target>
2094 <context-group name="null">
2095 <context context-type="linenumber">12</context>
2096 </context-group>
2097 </trans-unit>
2098 <trans-unit id="079e99cce11c87b142e80fdd14dae98a61012fc4">
2099 <source>Muted at <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2100 <target>Gedempt bij <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2101 <context-group name="null">
2102 <context context-type="linenumber">13</context>
2103 </context-group>
2104 </trans-unit>
2105 <trans-unit id="1f689fada9748a830117f5b429a88ef8629082a8">
2106 <source>Unmute</source>
2107 <target>Demping opheffen</target>
2108 <context-group name="null">
2109 <context context-type="linenumber">23</context>
999 </context-group> 2110 </context-group>
1000 </trans-unit> 2111 </trans-unit>
1001 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 2112 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
@@ -1009,28 +2120,67 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
1009 <source>Profile</source> 2120 <source>Profile</source>
1010 <target>Profiel</target> 2121 <target>Profiel</target>
1011 <context-group name="null"> 2122 <context-group name="null">
1012 <context context-type="linenumber">8</context> 2123 <context context-type="linenumber">7</context>
1013 </context-group> 2124 </context-group>
1014 </trans-unit> 2125 </trans-unit>
1015 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 2126 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
1016 <source>Video settings</source> 2127 <source>Video settings</source>
1017 <target>Video-instellingen</target> 2128 <target>Video-instellingen</target>
1018 <context-group name="null"> 2129 <context-group name="null">
1019 <context context-type="linenumber">15</context> 2130 <context context-type="linenumber">16</context>
2131 </context-group>
2132 </trans-unit>
2133 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
2134 <source>Danger zone</source>
2135 <target>Gevarenzone</target>
2136 <context-group name="null">
2137 <context context-type="linenumber">19</context>
2138 </context-group>
2139 </trans-unit>
2140 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
2141 <source>Change ownership</source>
2142 <target>Verander eigenaar</target>
2143 <context-group name="null">
2144 <context context-type="linenumber">46</context>
2145 </context-group>
2146 </trans-unit>
2147 <trans-unit id="046c4fa30411e6b1aa46dc51bf82d07b1adf14d4">
2148 <source>Select the next owner</source>
2149 <target>Selecteer de volgende eigenaar</target>
2150 <context-group name="null">
2151 <context context-type="linenumber">9</context>
2152 </context-group>
2153 </trans-unit>
2154 <trans-unit id="a5433ae2324496bea9537caa5e8a2719d8e958d8">
2155 <source>
2156 Cancel
2157 </source>
2158 <target>
2159Annuleren</target>
2160 <context-group name="null">
2161 <context context-type="linenumber">35</context>
1020 </context-group> 2162 </context-group>
1021 </trans-unit> 2163 </trans-unit>
1022 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 2164 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
1023 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 2165 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
1024 <target>Video’s <x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> aantal keer bekeken</target> 2166 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> weergaven</target>
1025 <context-group name="null"> 2167 <context-group name="null">
1026 <context context-type="linenumber">19</context> 2168 <context context-type="linenumber">19</context>
1027 </context-group> 2169 </context-group>
1028 </trans-unit> 2170 </trans-unit>
2171 <trans-unit id="4a806761798181e907e28ed1af053d466526800d">
2172 <source>Blacklisted</source>
2173 <target>Op de zwarte lijst</target>
2174 <context-group name="null">
2175 <context context-type="linenumber">22</context>
2176 </context-group>
2177 </trans-unit>
1029 <trans-unit id="17a9d3860d9ad593dd09a9f934e03999d9e76a7a"> 2178 <trans-unit id="17a9d3860d9ad593dd09a9f934e03999d9e76a7a">
1030 <source> 2179 <source>
1031 Cancel 2180 Cancel
1032 </source> 2181 </source>
1033 <target>Annuleren</target> 2182 <target>
2183Annuleren</target>
1034 <context-group name="null"> 2184 <context-group name="null">
1035 <context context-type="linenumber">30</context> 2185 <context context-type="linenumber">30</context>
1036 </context-group> 2186 </context-group>
@@ -1056,6 +2206,13 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
1056 <context context-type="linenumber">6</context> 2206 <context context-type="linenumber">6</context>
1057 </context-group> 2207 </context-group>
1058 </trans-unit> 2208 </trans-unit>
2209 <trans-unit id="915d4704e1649016512cbf5eeac55b4dbf933558">
2210 <source>Example: my_channel</source>
2211 <target>Bijvoorbeeld: mijn_kanaal</target>
2212 <context-group name="null">
2213 <context context-type="linenumber">15</context>
2214 </context-group>
2215 </trans-unit>
1059 <trans-unit id="bc155f9fc3be3f32083f19b2c77d4ad3b696d9b9"> 2216 <trans-unit id="bc155f9fc3be3f32083f19b2c77d4ad3b696d9b9">
1060 <source>Display name</source> 2217 <source>Display name</source>
1061 <target>Weergavenaam</target> 2218 <target>Weergavenaam</target>
@@ -1066,12 +2223,26 @@ Het Peer-to-Peer-mechanisme uit PeerTube halen zou je niet méér anonimiteit ge
1066 <trans-unit id="74728de5289ea2ff3f553bc2b48f1811680b931a"> 2223 <trans-unit id="74728de5289ea2ff3f553bc2b48f1811680b931a">
1067 <source>Short text to tell people how they can support your channel (membership platform...).&lt;br /&gt;&lt;br /&gt; 2224 <source>Short text to tell people how they can support your channel (membership platform...).&lt;br /&gt;&lt;br /&gt;
1068When you will upload a video in this channel, the video support field will be automatically filled by this text.</source> 2225When you will upload a video in this channel, the video support field will be automatically filled by this text.</source>
1069 <target>Korte tekst om mensen te vertellen hoe ze je kanaal kunnen ondersteunen (lidmaatschap…).&lt;br/&gt;&lt;br/&gt; 2226 <target>Korte tekst om mensen te vertellen hoe ze je kanaal kunnen ondersteunen (lidmaatschapsplatform…).&lt;br /&gt;&lt;br /&gt;
1070Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "ondersteun"-veld.</target> 2227Als je een video uploadt op dit kanaal, wordt deze tekst ingevuld in het "ondersteun"-veld.</target>
1071 <context-group name="null"> 2228 <context-group name="null">
1072 <context context-type="linenumber">52</context> 2229 <context context-type="linenumber">52</context>
1073 </context-group> 2230 </context-group>
1074 </trans-unit> 2231 </trans-unit>
2232 <trans-unit id="38baeb215c17af9d9e295e371a57f4a48ab4c191">
2233 <source>Target</source>
2234 <target>Doelwit</target>
2235 <context-group name="null">
2236 <context context-type="linenumber">8</context>
2237 </context-group>
2238 </trans-unit>
2239 <trans-unit id="3a5d57052d13d2da1cbcffdbb8effb9874b1595a">
2240 <source>You don't have any subscriptions yet.</source>
2241 <target>Je hebt nog geen abonnementen.</target>
2242 <context-group name="null">
2243 <context context-type="linenumber">1</context>
2244 </context-group>
2245 </trans-unit>
1075 <trans-unit id="c65641c36859c328928e6b0f14c3f913886f8add"> 2246 <trans-unit id="c65641c36859c328928e6b0f14c3f913886f8add">
1076 <source>Created by <x id="INTERPOLATION" equiv-text="{{ videoChannel.ownerBy }}"/></source> 2247 <source>Created by <x id="INTERPOLATION" equiv-text="{{ videoChannel.ownerBy }}"/></source>
1077 <target>Gemaakt door <x id="INTERPOLATION" equiv-text="{{ videoChannel.ownerBy }}"/></target> 2248 <target>Gemaakt door <x id="INTERPOLATION" equiv-text="{{ videoChannel.ownerBy }}"/></target>
@@ -1086,6 +2257,75 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1086 <context context-type="linenumber">16</context> 2257 <context context-type="linenumber">16</context>
1087 </context-group> 2258 </context-group>
1088 </trans-unit> 2259 </trans-unit>
2260 <trans-unit id="fbc450919a486e8ed311a7e91a41987d47d83804">
2261 <source>Accept ownership</source>
2262 <target>Accepteer eigenaar</target>
2263 <context-group name="null">
2264 <context context-type="linenumber">3</context>
2265 </context-group>
2266 </trans-unit>
2267 <trans-unit id="4570c754149df06f31096510abfc925968c35562">
2268 <source>Select the target channel</source>
2269 <target>Selecteer het doelwitkanaal</target>
2270 <context-group name="null">
2271 <context context-type="linenumber">9</context>
2272 </context-group>
2273 </trans-unit>
2274 <trans-unit id="e98239d8a6be1100119ff4b5630c822b82786740">
2275 <source>Initiator</source>
2276 <target>Initiatiefnemer</target>
2277 <context-group name="null">
2278 <context context-type="linenumber">13</context>
2279 </context-group>
2280 </trans-unit>
2281 <trans-unit id="b08d67fe4e192ea8352bebdc6aabbd1bb7abed02">
2282 <source>
2283 Created
2284 <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/>
2285 </source>
2286 <target>
2287 Gecreëerd op
2288 <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/>
2289 </target>
2290 <context-group name="null">
2291 <context context-type="linenumber">15</context>
2292 </context-group>
2293 </trans-unit>
2294 <trans-unit id="81b97b8ea996ad1e4f9fca8415021850214884b1">
2295 <source>Status</source>
2296 <target>Status</target>
2297 <context-group name="null">
2298 <context context-type="linenumber">19</context>
2299 </context-group>
2300 </trans-unit>
2301 <trans-unit id="1bd5e17c9582661e20763a7634ef07881e33bbd7">
2302 <source>Action</source>
2303 <target>Actie</target>
2304 <context-group name="null">
2305 <context context-type="linenumber">20</context>
2306 </context-group>
2307 </trans-unit>
2308 <trans-unit id="f4212e793d36e1aaa6ee1b09881677f783b5feff">
2309 <source><x id="INTERPOLATION" equiv-text="{{ videoChangeOwnership.status }}"/></source>
2310 <target><x id="INTERPOLATION" equiv-text="{{ videoChangeOwnership.status }}"/></target>
2311 <context-group name="null">
2312 <context context-type="linenumber">39</context>
2313 </context-group>
2314 </trans-unit>
2315 <trans-unit id="4a5613f6b472c1ed863dff1be932913a251f27a2">
2316 <source>Refuse</source>
2317 <target>Weigeren</target>
2318 <context-group name="null">
2319 <context context-type="linenumber">47</context>
2320 </context-group>
2321 </trans-unit>
2322 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2323 <source>Muted instances</source>
2324 <target>Gedempte instanties</target>
2325 <context-group name="null">
2326 <context context-type="linenumber">2</context>
2327 </context-group>
2328 </trans-unit>
1089 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 2329 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
1090 <source>Change password</source> 2330 <source>Change password</source>
1091 <target>Wachtwoord veranderen</target> 2331 <target>Wachtwoord veranderen</target>
@@ -1093,6 +2333,13 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1093 <context context-type="linenumber">30</context> 2333 <context context-type="linenumber">30</context>
1094 </context-group> 2334 </context-group>
1095 </trans-unit> 2335 </trans-unit>
2336 <trans-unit id="0dd390d056411e1709ec97ec51c46d78600e3f7b">
2337 <source>Current password</source>
2338 <target>Huidige wachtwoord</target>
2339 <context-group name="null">
2340 <context context-type="linenumber">7</context>
2341 </context-group>
2342 </trans-unit>
1096 <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229"> 2343 <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229">
1097 <source>New password</source> 2344 <source>New password</source>
1098 <target>Nieuw wachtwoord</target> 2345 <target>Nieuw wachtwoord</target>
@@ -1114,8 +2361,17 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1114 <context context-type="linenumber">3</context> 2361 <context context-type="linenumber">3</context>
1115 </context-group> 2362 </context-group>
1116 </trans-unit> 2363 </trans-unit>
2364 <trans-unit id="d044c51156e295824813a866dba9545bdb59466b">
2365 <source>Use WebTorrent to exchange parts of the video with others</source>
2366 <target>Gebruik WebTorrent om delen van de video over te maken naar anderen</target>
2367 <context-group name="null">
2368 <context context-type="linenumber">21</context>
2369 </context-group>
2370 </trans-unit>
1117 <trans-unit id="fb17c44abac2d1ed2a54cdd28bae289dc0b9a1c2"> 2371 <trans-unit id="fb17c44abac2d1ed2a54cdd28bae289dc0b9a1c2">
1118 <source>Automatically plays video</source><target>Automatically plays video</target><context-group name="null"> 2372 <source>Automatically plays video</source>
2373 <target>Video automatisch afspelen</target>
2374 <context-group name="null">
1119 <context context-type="linenumber">28</context> 2375 <context context-type="linenumber">28</context>
1120 </context-group> 2376 </context-group>
1121 </trans-unit> 2377 </trans-unit>
@@ -1128,11 +2384,25 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1128 </trans-unit> 2384 </trans-unit>
1129 <trans-unit id="d2fa66a905b6b7f691c83be681d18188cbe4a8ba"> 2385 <trans-unit id="d2fa66a905b6b7f691c83be681d18188cbe4a8ba">
1130 <source>Update my profile</source> 2386 <source>Update my profile</source>
1131 <target>Update mijn profiel</target> 2387 <target>Werk mijn profiel bij</target>
1132 <context-group name="null"> 2388 <context-group name="null">
1133 <context context-type="linenumber">27</context> 2389 <context context-type="linenumber">27</context>
1134 </context-group> 2390 </context-group>
1135 </trans-unit> 2391 </trans-unit>
2392 <trans-unit id="4b50f2ef2e8b9a24e674d12012ee310f378a5503">
2393 <source><x id="INTERPOLATION" equiv-text="{{ actor.followersCount }}"/> subscribers</source>
2394 <target><x id="INTERPOLATION" equiv-text="{{ actor.followersCount }}"/> abonnees</target>
2395 <context-group name="null">
2396 <context context-type="linenumber">10</context>
2397 </context-group>
2398 </trans-unit>
2399 <trans-unit id="c4a959fc6349bd0793e1ad571d492052a07bdab5">
2400 <source>Change the avatar</source>
2401 <target>Verander de avatar</target>
2402 <context-group name="null">
2403 <context context-type="linenumber">15</context>
2404 </context-group>
2405 </trans-unit>
1136 <trans-unit id="c860c88df9ad58b1187084251340b232cdf0a7f9"> 2406 <trans-unit id="c860c88df9ad58b1187084251340b232cdf0a7f9">
1137 <source>(extensions: <x id="INTERPOLATION" equiv-text="{{ avatarExtensions }}"/>, max size: <x id="INTERPOLATION_1" equiv-text="{{ maxAvatarSize | bytes }}"/>)</source> 2407 <source>(extensions: <x id="INTERPOLATION" equiv-text="{{ avatarExtensions }}"/>, max size: <x id="INTERPOLATION_1" equiv-text="{{ maxAvatarSize | bytes }}"/>)</source>
1138 <target>(extensies: <x id="INTERPOLATION" equiv-text="{{ avatarExtensions }}"/>, maximale grootte: <x id="INTERPOLATION_1" equiv-text="{{ maxAvatarSize | bytes }}"/>)</target> 2408 <target>(extensies: <x id="INTERPOLATION" equiv-text="{{ avatarExtensions }}"/>, maximale grootte: <x id="INTERPOLATION_1" equiv-text="{{ maxAvatarSize | bytes }}"/>)</target>
@@ -1140,15 +2410,84 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1140 <context context-type="linenumber">18</context> 2410 <context context-type="linenumber">18</context>
1141 </context-group> 2411 </context-group>
1142 </trans-unit> 2412 </trans-unit>
2413 <trans-unit id="d1a04ba05116499d4cf59a48a282a8bcbf5b622d">
2414 <source>Once you delete your account, there is no going back. Please be certain.</source>
2415 <target>Als je je account verwijdert, kan je niet meer terug.
2416Wees alstublieft zeker.</target>
2417 <context-group name="null">
2418 <context context-type="linenumber">2</context>
2419 </context-group>
2420 </trans-unit>
2421 <trans-unit id="9a2f889dde4574a6883c853d1034e75891b28c45">
2422 <source>Delete your account</source>
2423 <target>Verwijder jouw account</target>
2424 <context-group name="null">
2425 <context context-type="linenumber">4</context>
2426 </context-group>
2427 </trans-unit>
1143 <trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd"> 2428 <trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd">
1144 <source> 2429 <source>
1145 Sorry, but we couldn't find the page you were looking for. 2430 Sorry, but we couldn't find the page you were looking for.
1146</source> 2431</source>
1147 <target>Sorry, maar die pagina kon niet gevonden worden.</target> 2432 <target>
2433Sorry, maar die pagina kon niet gevonden worden.
2434</target>
1148 <context-group name="null"> 2435 <context-group name="null">
1149 <context context-type="linenumber">1</context> 2436 <context context-type="linenumber">1</context>
1150 </context-group> 2437 </context-group>
1151 </trans-unit> 2438 </trans-unit>
2439 <trans-unit id="09a69cde5889927629e2ac9dc63a71b88252b530">
2440 <source>
2441 Verify account email confirmation
2442 </source>
2443 <target>
2444Verifieer e-mailbevestiging van account</target>
2445 <context-group name="null">
2446 <context context-type="linenumber">2</context>
2447 </context-group>
2448 </trans-unit>
2449 <trans-unit id="066569dd934e07e4a5f70c415692be17d5715b57">
2450 <source>
2451 Your email has been verified and you may now login. Redirecting...
2452 </source>
2453 <target>
2454Jouw e-mail is geverifieerd en je mag nu inloggen.
2455Je wordt doorverwezen...</target>
2456 <context-group name="null">
2457 <context context-type="linenumber">6</context>
2458 </context-group>
2459 </trans-unit>
2460 <trans-unit id="7ee8fad77b2664dabfb90ea03470f75a6f6d1d48">
2461 <source>An error occurred. </source>
2462 <target>Er is een probleem opgetreden.</target>
2463 <context-group name="null">
2464 <context context-type="linenumber">11</context>
2465 </context-group>
2466 </trans-unit>
2467 <trans-unit id="2d02841904de7f5f60e2618670ac1059f3abec97">
2468 <source>
2469 Request email for account verification
2470 </source>
2471 <target>
2472Vraag e-mail voor accountverificatie aan</target>
2473 <context-group name="null">
2474 <context context-type="linenumber">2</context>
2475 </context-group>
2476 </trans-unit>
2477 <trans-unit id="eb539ec6941044e284f237f5b40d6a0159afe7af">
2478 <source>Send verification email</source>
2479 <target>Verzend e-mail voor verificatie</target>
2480 <context-group name="null">
2481 <context context-type="linenumber">17</context>
2482 </context-group>
2483 </trans-unit>
2484 <trans-unit id="a08080316e052053fd20647731a6de826dc8072f">
2485 <source>This instance does not require email verification.</source>
2486 <target>Deze instantie heeft geen verificatie door e-mail nodig.</target>
2487 <context-group name="null">
2488 <context context-type="linenumber">20</context>
2489 </context-group>
2490 </trans-unit>
1152 <trans-unit id="1380539d91f77f565de6e21ce210da891e6644b8"> 2491 <trans-unit id="1380539d91f77f565de6e21ce210da891e6644b8">
1153 <source>Support this channel</source> 2492 <source>Support this channel</source>
1154 <target>Ondersteun dit kanaal</target> 2493 <target>Ondersteun dit kanaal</target>
@@ -1163,6 +2502,20 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1163 <context context-type="linenumber">17</context> 2502 <context context-type="linenumber">17</context>
1164 </context-group> 2503 </context-group>
1165 </trans-unit> 2504 </trans-unit>
2505 <trans-unit id="801b98c6f02fe3b32f6afa3ee854c99ed83474e6">
2506 <source>URL</source>
2507 <target>URL</target>
2508 <context-group name="null">
2509 <context context-type="linenumber">17</context>
2510 </context-group>
2511 </trans-unit>
2512 <trans-unit id="bfe7f34fbd4c3afa5f84a5580e0fae942cad2333">
2513 <source>You can import any URL &lt;a href='https://rg3.github.io/youtube-dl/supportedsites.html' target='_blank' rel='noopener noreferrer'&gt;supported by youtube-dl&lt;/a&gt; or URL that points to a raw MP4 file. You should make sure you have diffusion rights over the content it points to, otherwise it could cause legal trouble to yourself and your instance.</source>
2514 <target>Je kan elke URL importeren &lt;a href='https://rg3.github.io/youtube-dl/supportedsites.html' target='_blank' rel='noopener noreferrer'&gt;ondersteunt door youtube-dl&lt;/a&gt; of elke URL die naar een rauw MP4 bestand wijst. Je moet zeker weten dat je de diffusierechten hebt over de inhoud waar het naar wijst, anders kan het wettelijke problemen aan jou of je instantie geven.</target>
2515 <context-group name="null">
2516 <context context-type="linenumber">9</context>
2517 </context-group>
2518 </trans-unit>
1166 <trans-unit id="0cc554f4d7bb6a87515d2d95438e183b50702071"> 2519 <trans-unit id="0cc554f4d7bb6a87515d2d95438e183b50702071">
1167 <source>Channel</source> 2520 <source>Channel</source>
1168 <target>Kanaal</target> 2521 <target>Kanaal</target>
@@ -1172,11 +2525,37 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1172 </trans-unit> 2525 </trans-unit>
1173 <trans-unit id="3c78b53bca33467190c0b7a01320bc093a2b1427"> 2526 <trans-unit id="3c78b53bca33467190c0b7a01320bc093a2b1427">
1174 <source>Privacy</source> 2527 <source>Privacy</source>
1175 <target>Zichtbaarheid</target> 2528 <target>Privacy</target>
1176 <context-group name="null"> 2529 <context-group name="null">
1177 <context context-type="linenumber">159</context> 2530 <context context-type="linenumber">159</context>
1178 </context-group> 2531 </context-group>
1179 </trans-unit> 2532 </trans-unit>
2533 <trans-unit id="385811ab5a5c3e96e0db46c9ce1fc3147d8cd4c7">
2534 <source>Sorry, but something went wrong</source>
2535 <target>Sorry, er is iets fout gegaan</target>
2536 <context-group name="null">
2537 <context context-type="linenumber">49</context>
2538 </context-group>
2539 </trans-unit>
2540 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2">
2541 <source>
2542 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video.
2543</source>
2544 <target>
2545Gefeliciteerd, de video achter<x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> zal worden geimporteerd! Je kan nu al informatie over deze video toevoegen.
2546
2547</target>
2548 <context-group name="null">
2549 <context context-type="linenumber">46</context>
2550 </context-group>
2551 </trans-unit>
2552 <trans-unit id="047f50bc5b5d17b5bec0196355953e1a5c590ddb">
2553 <source>Update</source>
2554 <target>Bijwerken</target>
2555 <context-group name="null">
2556 <context context-type="linenumber">92</context>
2557 </context-group>
2558 </trans-unit>
1180 <trans-unit id="21add64f0f3ebbedf1150ca822c6e149494ab7a9"> 2559 <trans-unit id="21add64f0f3ebbedf1150ca822c6e149494ab7a9">
1181 <source>Select the file to upload</source> 2560 <source>Select the file to upload</source>
1182 <target>Selecteer het bestand om te uploaden</target> 2561 <target>Selecteer het bestand om te uploaden</target>
@@ -1184,18 +2563,132 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1184 <context context-type="linenumber">6</context> 2563 <context context-type="linenumber">6</context>
1185 </context-group> 2564 </context-group>
1186 </trans-unit> 2565 </trans-unit>
2566 <trans-unit id="5e420747842373fa99a75a7a18df068cc81e46fb">
2567 <source>Scheduled</source>
2568 <target>Ingeroosterd</target>
2569 <context-group name="null">
2570 <context context-type="linenumber">25</context>
2571 </context-group>
2572 </trans-unit>
1187 <trans-unit id="f7ac2376749c7985f94f0fc89ba75ea624de1215"> 2573 <trans-unit id="f7ac2376749c7985f94f0fc89ba75ea624de1215">
1188 <source>Publish will be available when upload is finished</source> 2574 <source>Publish will be available when upload is finished</source>
1189 <target>Publiceren is mogelijk wanneer de upload voltooid is</target> 2575 <target>Publiceren is mogelijk wanneer de upload voltooid is</target>
1190 <context-group name="null"> 2576 <context-group name="null">
1191 <context context-type="linenumber">53</context> 2577 <context context-type="linenumber">58</context>
1192 </context-group> 2578 </context-group>
1193 </trans-unit> 2579 </trans-unit>
1194 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 2580 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
1195 <source>Publish</source> 2581 <source>Publish</source>
1196 <target>Publiceren</target> 2582 <target>Publiceren</target>
1197 <context-group name="null"> 2583 <context-group name="null">
1198 <context context-type="linenumber">60</context> 2584 <context context-type="linenumber">65</context>
2585 </context-group>
2586 </trans-unit>
2587 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
2588 <source>Select the torrent to import</source>
2589 <target>Selecteer de torrent om te importeren</target>
2590 <context-group name="null">
2591 <context context-type="linenumber">6</context>
2592 </context-group>
2593 </trans-unit>
2594 <trans-unit id="1b518e7f8c067fa55ea797bb1b35b4a2d31dccbc">
2595 <source>Or</source>
2596 <target>Of</target>
2597 <context-group name="null">
2598 <context context-type="linenumber">11</context>
2599 </context-group>
2600 </trans-unit>
2601 <trans-unit id="0d6558176587662e9bb3b79cca57d42591cf82f9">
2602 <source>Paste magnet URI</source>
2603 <target>Plak magnet URL</target>
2604 <context-group name="null">
2605 <context context-type="linenumber">14</context>
2606 </context-group>
2607 </trans-unit>
2608 <trans-unit id="1ce18c12c809a738f05f2290f46df0677f27ed70">
2609 <source>You can import any torrent file that points to a mp4 file. You should make sure you have diffusion rights over the content it points to, otherwise it could cause legal trouble to yourself and your instance.</source>
2610 <target>Je kan elk torrentbestand importeren die wijst naar een mp4 bestand. Je moet zeker weten dat je de diffusierechten over de inhoud waar het naar wijst hebt, anders kan het wettelijke problemen aan jezelf en je instantie geven.</target>
2611 <context-group name="null">
2612 <context context-type="linenumber">17</context>
2613 </context-group>
2614 </trans-unit>
2615 <trans-unit id="7cb3731472edd9edf6a6d036498c2c8388157266">
2616 <source>
2617 Congratulations, the video will be imported with BitTorrent! You can already add information about this video.
2618</source>
2619 <target>
2620Gefeliciteerd, de video zal geimporteerd worden met BitTorrent!
2621Je kan nu al informatie toevoegen over deze video.
2622
2623</target>
2624 <context-group name="null">
2625 <context context-type="linenumber">53</context>
2626 </context-group>
2627 </trans-unit>
2628 <trans-unit id="0b60d939cf0f1af9fe513f31164d198abf671860">
2629 <source>Import <x id="INTERPOLATION" equiv-text="{{ videoName }}"/></source>
2630 <target>Importeer <x id="INTERPOLATION" equiv-text="{{ videoName }}"/></target>
2631 <context-group name="null">
2632 <context context-type="linenumber">3</context>
2633 </context-group>
2634 </trans-unit>
2635 <trans-unit id="e9cfe8bd050660077212af5c02f5be24821f28d5">
2636 <source>Upload <x id="INTERPOLATION" equiv-text="{{ videoName }}"/></source>
2637 <target><x id="INTERPOLATION" equiv-text="{{ videoName }}"/> Uploaden</target>
2638 <context-group name="null">
2639 <context context-type="linenumber">4</context>
2640 </context-group>
2641 </trans-unit>
2642 <trans-unit id="4faf57baebf0fb754a91af0c39521a30cbb1def3">
2643 <source>Upload a file</source>
2644 <target>Upload een bestand</target>
2645 <context-group name="null">
2646 <context context-type="linenumber">10</context>
2647 </context-group>
2648 </trans-unit>
2649 <trans-unit id="fc865859d33eab6fa0a8015233e4686cd544d470">
2650 <source>Import with URL</source>
2651 <target>Importeer met URL</target>
2652 <context-group name="null">
2653 <context context-type="linenumber">17</context>
2654 </context-group>
2655 </trans-unit>
2656 <trans-unit id="752c401d7dcd708944eef60e411187f71d882340">
2657 <source>Import with torrent</source>
2658 <target>Importeer met torrent</target>
2659 <context-group name="null">
2660 <context context-type="linenumber">24</context>
2661 </context-group>
2662 </trans-unit>
2663 <trans-unit id="40fa23fe45af4ee2e72cdd3cc6bf6013f180aab0">
2664 <source>Add caption</source>
2665 <target>Voeg ondertiteling toe</target>
2666 <context-group name="null">
2667 <context context-type="linenumber">5</context>
2668 </context-group>
2669 </trans-unit>
2670 <trans-unit id="6bad752cfcac8f3572bdf2c619daec683d56d1a8">
2671 <source>Select the caption file</source>
2672 <target>Selecteer het ondertitelingsbestand</target>
2673 <context-group name="null">
2674 <context context-type="linenumber">24</context>
2675 </context-group>
2676 </trans-unit>
2677 <trans-unit id="c34c61401151c29fb3679638a7d0b95258145ec3">
2678 <source>
2679 This will replace an existing caption!
2680 </source>
2681 <target>
2682Dit zal een bestaande ondertiteling vervangen!</target>
2683 <context-group name="null">
2684 <context context-type="linenumber">29</context>
2685 </context-group>
2686 </trans-unit>
2687 <trans-unit id="39702b643cfe3d5b96a4587c1b44a29fa665406c">
2688 <source>Add this caption</source>
2689 <target>Voeg deze ondertiteling toe</target>
2690 <context-group name="null">
2691 <context context-type="linenumber">40</context>
1199 </context-group> 2692 </context-group>
1200 </trans-unit> 2693 </trans-unit>
1201 <trans-unit id="fdf7cbdc140d0aab0f0b6c06065a0fd448ed6a2e"> 2694 <trans-unit id="fdf7cbdc140d0aab0f0b6c06065a0fd448ed6a2e">
@@ -1212,16 +2705,37 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1212 <context context-type="linenumber">191</context> 2705 <context context-type="linenumber">191</context>
1213 </context-group> 2706 </context-group>
1214 </trans-unit> 2707 </trans-unit>
2708 <trans-unit id="457b1cff4d8d7fad0c8742f69c413ecf5e443851">
2709 <source>Tags could be used to suggest relevant recommendations.&lt;/br&gt;Press Enter to add a new tag.</source>
2710 <target>Tags kunnen gebruikt worden om relevante aanraders te suggesteren. &lt;/br&gt;Druk op Enter om een nieuwe tag toe te voegen.</target>
2711 <context-group name="null">
2712 <context context-type="linenumber">18</context>
2713 </context-group>
2714 </trans-unit>
2715 <trans-unit id="9bdd535a2817bf0b843a124bf65e4992625e7ecf">
2716 <source>+ Tag</source>
2717 <target>Tag</target>
2718 <context-group name="null">
2719 <context context-type="linenumber">21</context>
2720 </context-group>
2721 </trans-unit>
2722 <trans-unit id="8389e9cde2928cc27aaecbdee818a255bf7984b0">
2723 <source>Enter a new tag</source>
2724 <target>Vul een nieuwe tag in</target>
2725 <context-group name="null">
2726 <context context-type="linenumber">21</context>
2727 </context-group>
2728 </trans-unit>
1215 <trans-unit id="50f53834157770b8205ada0e7a6e235211e4765e"> 2729 <trans-unit id="50f53834157770b8205ada0e7a6e235211e4765e">
1216 <source>Video descriptions are truncated by default and require manual action to expand them.</source> 2730 <source>Video descriptions are truncated by default and require manual action to expand them.</source>
1217 <target>Videobeschrijvingen worden standaard gedeeltelijk weergegeven, de kijker kan ze handmatig openvouwen.</target> 2731 <target>Videobeschrijvingen worden standaard gedeeltelijk weergegeven en moeten handmatig opengevouwen worden.</target>
1218 <context-group name="null"> 2732 <context-group name="null">
1219 <context context-type="linenumber">28</context> 2733 <context context-type="linenumber">28</context>
1220 </context-group> 2734 </context-group>
1221 </trans-unit> 2735 </trans-unit>
1222 <trans-unit id="d69f4fafc780cc7dbafb063ca5f11e6f7c91b0c5"> 2736 <trans-unit id="d69f4fafc780cc7dbafb063ca5f11e6f7c91b0c5">
1223 <source>Schedule publication (<x id="INTERPOLATION" equiv-text="{{ calendarTimezone }}"/>)</source> 2737 <source>Schedule publication (<x id="INTERPOLATION" equiv-text="{{ calendarTimezone }}"/>)</source>
1224 <target>Publicatie uitstellen (<x id="INTERPOLATION" equiv-text="{{ calendarTimezone }}"/>)</target> 2738 <target>Publicatie inroosteren op (<x id="INTERPOLATION" equiv-text="{{ calendarTimezone }}"/>)</target>
1225 <context-group name="null"> 2739 <context-group name="null">
1226 <context context-type="linenumber">105</context> 2740 <context context-type="linenumber">105</context>
1227 </context-group> 2741 </context-group>
@@ -1242,7 +2756,7 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1242 </trans-unit> 2756 </trans-unit>
1243 <trans-unit id="3549ee96125a43181f80712ed744ee223a0e645a"> 2757 <trans-unit id="3549ee96125a43181f80712ed744ee223a0e645a">
1244 <source>Enable video comments</source> 2758 <source>Enable video comments</source>
1245 <target>Videoreacties toelaten</target> 2759 <target>Videoreacties inschakelen</target>
1246 <context-group name="null"> 2760 <context-group name="null">
1247 <context context-type="linenumber">125</context> 2761 <context context-type="linenumber">125</context>
1248 </context-group> 2762 </context-group>
@@ -1251,7 +2765,14 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1251 <source>Wait transcoding before publishing the video</source> 2765 <source>Wait transcoding before publishing the video</source>
1252 <target>Wacht tot het transcoderen voltooid is om de video te publiceren</target> 2766 <target>Wacht tot het transcoderen voltooid is om de video te publiceren</target>
1253 <context-group name="null"> 2767 <context-group name="null">
1254 <context context-type="linenumber">130</context> 2768 <context context-type="linenumber">131</context>
2769 </context-group>
2770 </trans-unit>
2771 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2772 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
2773 <target>Als je beslist om niet te wachten totdat de transcoding compleet is voordat je de video publiceert, kan de video onspeelbaar zijn totdat de transcoding eindigt.</target>
2774 <context-group name="null">
2775 <context context-type="linenumber">132</context>
1255 </context-group> 2776 </context-group>
1256 </trans-unit> 2777 </trans-unit>
1257 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2778 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -1261,18 +2782,84 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1261 <context context-type="linenumber">4</context> 2782 <context context-type="linenumber">4</context>
1262 </context-group> 2783 </context-group>
1263 </trans-unit> 2784 </trans-unit>
2785 <trans-unit id="92bcfd1d237a2bfe48dc9f46d074ed26abc8df22">
2786 <source>Add another caption</source>
2787 <target>Voeg nog een ondertiteling toe</target>
2788 <context-group name="null">
2789 <context context-type="linenumber">147</context>
2790 </context-group>
2791 </trans-unit>
2792 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2793 <source>See the subtitle file</source>
2794 <target>Zie het ondertitelingsbestand</target>
2795 <context-group name="null">
2796 <context context-type="linenumber">156</context>
2797 </context-group>
2798 </trans-unit>
2799 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee">
2800 <source>Already uploaded ✔</source>
2801 <target>Al geupload ✔</target>
2802 <context-group name="null">
2803 <context context-type="linenumber">160</context>
2804 </context-group>
2805 </trans-unit>
2806 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad">
2807 <source>Will be created on update</source>
2808 <target>Wordt gecreëerd bij bijwerking</target>
2809 <context-group name="null">
2810 <context context-type="linenumber">168</context>
2811 </context-group>
2812 </trans-unit>
2813 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2814 <source>Cancel create</source>
2815 <target>Annuleer creatie</target>
2816 <context-group name="null">
2817 <context context-type="linenumber">170</context>
2818 </context-group>
2819 </trans-unit>
2820 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393">
2821 <source>Will be deleted on update</source>
2822 <target>Wordt verwijdert bij bijwerking</target>
2823 <context-group name="null">
2824 <context context-type="linenumber">176</context>
2825 </context-group>
2826 </trans-unit>
2827 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2828 <source>Cancel deletion</source>
2829 <target>Annuleer verwijdering</target>
2830 <context-group name="null">
2831 <context context-type="linenumber">178</context>
2832 </context-group>
2833 </trans-unit>
2834 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0">
2835 <source>
2836 No captions for now.
2837 </source>
2838 <target>
2839Geen ondertiteling voor nu.</target>
2840 <context-group name="null">
2841 <context context-type="linenumber">183</context>
2842 </context-group>
2843 </trans-unit>
2844 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2845 <source>Captions</source>
2846 <target>Ondertiteling</target>
2847 <context-group name="null">
2848 <context context-type="linenumber">140</context>
2849 </context-group>
2850 </trans-unit>
1264 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 2851 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
1265 <source>Upload thumbnail</source> 2852 <source>Upload thumbnail</source>
1266 <target>Thumbnail uploaden</target> 2853 <target>Thumbnail uploaden</target>
1267 <context-group name="null"> 2854 <context-group name="null">
1268 <context context-type="linenumber">195</context> 2855 <context context-type="linenumber">196</context>
1269 </context-group> 2856 </context-group>
1270 </trans-unit> 2857 </trans-unit>
1271 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 2858 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
1272 <source>Upload preview</source> 2859 <source>Upload preview</source>
1273 <target>Voorvertoning uploaden</target> 2860 <target>Voorvertoning uploaden</target>
1274 <context-group name="null"> 2861 <context-group name="null">
1275 <context context-type="linenumber">202</context> 2862 <context context-type="linenumber">203</context>
1276 </context-group> 2863 </context-group>
1277 </trans-unit> 2864 </trans-unit>
1278 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 2865 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -1284,26 +2871,238 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1284 </trans-unit> 2871 </trans-unit>
1285 <trans-unit id="f61f989de6fc12f99369a90800e4b5462d3f10a0"> 2872 <trans-unit id="f61f989de6fc12f99369a90800e4b5462d3f10a0">
1286 <source>Short text to tell people how they can support you (membership platform...).</source> 2873 <source>Short text to tell people how they can support you (membership platform...).</source>
1287 <target>Korte tekst om mensen te vertellen hoe ze je kanaal kunnen ondersteunen (bv. door gelddonaties).</target> 2874 <target>Korte tekst om mensen te vertellen hoe ze je kanaal kunnen ondersteunen (lidmaatschapsplatforms...).</target>
1288 <context-group name="null"> 2875 <context-group name="null">
1289 <context context-type="linenumber">209</context> 2876 <context context-type="linenumber">210</context>
1290 </context-group> 2877 </context-group>
1291 </trans-unit> 2878 </trans-unit>
1292 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 2879 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
1293 <source>Advanced settings</source> 2880 <source>Advanced settings</source>
1294 <target>Geavanceerde instellingen</target> 2881 <target>Geavanceerde instellingen</target>
1295 <context-group name="null"> 2882 <context-group name="null">
1296 <context context-type="linenumber">190</context> 2883 <context context-type="linenumber">191</context>
1297 </context-group> 2884 </context-group>
1298 </trans-unit> 2885 </trans-unit>
1299 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 2886 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
1300 <source> 2887 <source>
1301 Update <x id="INTERPOLATION" equiv-text="{{ video?.name }}"/> 2888 Update <x id="INTERPOLATION" equiv-text="{{ video?.name }}"/>
1302 </source> 2889 </source>
2890 <target>
2891<x id="INTERPOLATION" equiv-text="{{ video?.name }}"/> updaten</target>
1303 <context-group name="null"> 2892 <context-group name="null">
1304 <context context-type="linenumber">2</context> 2893 <context context-type="linenumber">2</context>
1305 </context-group> 2894 </context-group>
1306 </trans-unit> 2895 </trans-unit>
2896 <trans-unit id="9aafb2a928664aa7a9375fd37c533f0375f8b611">
2897 <source>Download video</source>
2898 <target>Download video</target>
2899 <context-group name="null">
2900 <context context-type="linenumber">3</context>
2901 </context-group>
2902 </trans-unit>
2903 <trans-unit id="8d6a41c2703bed3edfc76e1df0b1ca203404c17c">
2904 <source>Direct download</source>
2905 <target>Directe download</target>
2906 <context-group name="null">
2907 <context context-type="linenumber">27</context>
2908 </context-group>
2909 </trans-unit>
2910 <trans-unit id="ac3a02ecd20f41278f1ef7c03f45c1117b4b796d">
2911 <source>Torrent (.torrent file)</source>
2912 <target>Torrent (.torrent bestand)</target>
2913 <context-group name="null">
2914 <context context-type="linenumber">32</context>
2915 </context-group>
2916 </trans-unit>
2917 <trans-unit id="2db8d7cf6a3071f4c1519ef2b5e2713d9ff4e87f">
2918 <source>Torrent (magnet link)</source>
2919 <target>Torrent (magnet link)</target>
2920 <context-group name="null">
2921 <context context-type="linenumber">37</context>
2922 </context-group>
2923 </trans-unit>
2924 <trans-unit id="da44efc7b658c318651866454d258bbbe57ff21c">
2925 <source>
2926 Cancel
2927 </source>
2928 <target>
2929Annuleren</target>
2930 <context-group name="null">
2931 <context context-type="linenumber">47</context>
2932 </context-group>
2933 </trans-unit>
2934 <trans-unit id="dc75033a5238fdc4f462212c847a45ba8018a3fd">
2935 <source>Download</source>
2936 <target>Downloaden</target>
2937 <context-group name="null">
2938 <context context-type="linenumber">84</context>
2939 </context-group>
2940 </trans-unit>
2941 <trans-unit id="11749f4fc0aa1b5e37f38575e4d4e3b1b7e0e96b">
2942 <source>Report video</source>
2943 <target>Rapporteer video</target>
2944 <context-group name="null">
2945 <context context-type="linenumber">3</context>
2946 </context-group>
2947 </trans-unit>
2948 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
2949 <source>Share</source>
2950 <target>Deel</target>
2951 <context-group name="null">
2952 <context context-type="linenumber">74</context>
2953 </context-group>
2954 </trans-unit>
2955 <trans-unit id="e0cfbc8ea680e4527ebf094c035f3342e9146d9f">
2956 <source>QR-Code</source>
2957 <target>QR-Code</target>
2958 <context-group name="null">
2959 <context context-type="linenumber">29</context>
2960 </context-group>
2961 </trans-unit>
2962 <trans-unit id="d3b15c3bf4a7ea38d6002d2d2c4781642d30e79c">
2963 <source>Embed</source>
2964 <target>Inbedden</target>
2965 <context-group name="null">
2966 <context context-type="linenumber">34</context>
2967 </context-group>
2968 </trans-unit>
2969 <trans-unit id="90e0a0a3da80b46e550c1395ff4e97c27259bef8">
2970 <source>
2971 The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites).
2972 </source>
2973 <target>
2974Deze url is niet beveiligd (geen HTTPS), dus de ingebedde video werkt niet op HTTPS websites (web browsers blokkeren onbeveiligde HTTP verzoeken op HTTPS websites).</target>
2975 <context-group name="null">
2976 <context context-type="linenumber">45</context>
2977 </context-group>
2978 </trans-unit>
2979 <trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8">
2980 <source>Close</source>
2981 <target>Sluiten</target>
2982 <context-group name="null">
2983 <context context-type="linenumber">51</context>
2984 </context-group>
2985 </trans-unit>
2986 <trans-unit id="f672385c803647b063687d3c912e2ce5738b51c8">
2987 <source>Blacklist video</source>
2988 <target>Video op de zwarte lijst zetten</target>
2989 <context-group name="null">
2990 <context context-type="linenumber">3</context>
2991 </context-group>
2992 </trans-unit>
2993 <trans-unit id="7584313e33a66811eb10646627914a01fff0347d">
2994 <source>
2995 The video is being imported, it will be available when the import is finished.
2996 </source>
2997 <target>
2998De video wordt geimporteerd, hij zal beschikbaar worden wanneer de import klaar is.</target>
2999 <context-group name="null">
3000 <context context-type="linenumber">11</context>
3001 </context-group>
3002 </trans-unit>
3003 <trans-unit id="9ed65ae88f6c982bc44d6fed2796e55f47dbf304">
3004 <source>
3005 The video is being transcoded, it may not work properly.
3006 </source>
3007 <target>
3008De video wordt getranscode, hij kan misschien niet naar behoren werken.</target>
3009 <context-group name="null">
3010 <context context-type="linenumber">15</context>
3011 </context-group>
3012 </trans-unit>
3013 <trans-unit id="c89a08fd2a05d1013fed8478024f5ba37ac3d308">
3014 <source>
3015 This video will be published on <x id="INTERPOLATION" equiv-text="{{ video.scheduledUpdate.updateAt | date: 'full' }}"/>.
3016 </source>
3017 <target>
3018Deze video wordt gepubliceerd op <x id="INTERPOLATION" equiv-text="{{ video.scheduledUpdate.updateAt | date: 'full' }}"/>.</target>
3019 <context-group name="null">
3020 <context context-type="linenumber">19</context>
3021 </context-group>
3022 </trans-unit>
3023 <trans-unit id="bd7055d3e38beff538463e75d508d1c75c683710">
3024 <source>This video is blacklisted.</source>
3025 <target>Deze video staat op de zwarte lijst.</target>
3026 <context-group name="null">
3027 <context context-type="linenumber">24</context>
3028 </context-group>
3029 </trans-unit>
3030 <trans-unit id="3da5360f8314aa95973aa52629c9f635363c5a36">
3031 <source>
3032 Published <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views
3033 </source>
3034 <target>
3035Gepubliceerde <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> weergaven</target>
3036 <context-group name="null">
3037 <context context-type="linenumber">37</context>
3038 </context-group>
3039 </trans-unit>
3040 <trans-unit id="07087373dbf99b5e8b2b2f962fd53baa97d9ab95">
3041 <source>
3042 Published <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views
3043 </source>
3044 <target>
3045Gepubliceerde <x id="INTERPOLATION" equiv-text="{{ video.publishedAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> weergaven</target>
3046 <context-group name="null">
3047 <context context-type="linenumber">46</context>
3048 </context-group>
3049 </trans-unit>
3050 <trans-unit id="82b59049f3f89d900c98da9319e156dd513e3ced">
3051 <source>Like this video</source>
3052 <target>Like deze video</target>
3053 <context-group name="null">
3054 <context context-type="linenumber">57</context>
3055 </context-group>
3056 </trans-unit>
3057 <trans-unit id="623698f075025b2b2fc2e0c59fd95f4f4662a509">
3058 <source>Dislike this video</source>
3059 <target>Dislike deze video</target>
3060 <context-group name="null">
3061 <context context-type="linenumber">64</context>
3062 </context-group>
3063 </trans-unit>
3064 <trans-unit id="144fff5c40b85414d59e644d8dee7cfefba925a2">
3065 <source>Download the video</source>
3066 <target>Download de video</target>
3067 <context-group name="null">
3068 <context context-type="linenumber">83</context>
3069 </context-group>
3070 </trans-unit>
3071 <trans-unit id="f72992030f134408b675152c397f9d0ec00f3b2a">
3072 <source>Report</source>
3073 <target>Rapporteer</target>
3074 <context-group name="null">
3075 <context context-type="linenumber">88</context>
3076 </context-group>
3077 </trans-unit>
3078 <trans-unit id="2f4894617d9c44010f87473e583bd4604b7d6ecf">
3079 <source>Report this video</source>
3080 <target>Rapporteer deze video</target>
3081 <context-group name="null">
3082 <context context-type="linenumber">87</context>
3083 </context-group>
3084 </trans-unit>
3085 <trans-unit id="cd27f761b923a5bdb16ba9844da632edd878f1b1">
3086 <source>Update this video</source>
3087 <target>Werk deze video bij</target>
3088 <context-group name="null">
3089 <context context-type="linenumber">91</context>
3090 </context-group>
3091 </trans-unit>
3092 <trans-unit id="007ab5fa2aae8a7372307d3fc45a2dbcb11ffd61">
3093 <source>Blacklist</source>
3094 <target>Zet op de zwarte lijst</target>
3095 <context-group name="null">
3096 <context context-type="linenumber">96</context>
3097 </context-group>
3098 </trans-unit>
3099 <trans-unit id="803c6317abd2dbafcc93226c4e273c62932e3037">
3100 <source>Blacklist this video</source>
3101 <target>Zet deze video op de zwarte lijst</target>
3102 <context-group name="null">
3103 <context context-type="linenumber">95</context>
3104 </context-group>
3105 </trans-unit>
1307 <trans-unit id="86f26b106c67be3c2e98b82766656e5d9da86dff"> 3106 <trans-unit id="86f26b106c67be3c2e98b82766656e5d9da86dff">
1308 <source>Unblacklist</source> 3107 <source>Unblacklist</source>
1309 <target>Van zwarte lijst halen</target> 3108 <target>Van zwarte lijst halen</target>
@@ -1311,6 +3110,764 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1311 <context context-type="linenumber">100</context> 3110 <context context-type="linenumber">100</context>
1312 </context-group> 3111 </context-group>
1313 </trans-unit> 3112 </trans-unit>
3113 <trans-unit id="61021f5011bc24f69cfc3f6dbbbd8f1948328b25">
3114 <source>Unblacklist this video</source>
3115 <target>Haal deze video van de zwarte lijst</target>
3116 <context-group name="null">
3117 <context context-type="linenumber">99</context>
3118 </context-group>
3119 </trans-unit>
3120 <trans-unit id="3dbfdc68f83d91cb360172eb65578cae94e7cbe5">
3121 <source>Delete this video</source>
3122 <target>Verwijder deze video</target>
3123 <context-group name="null">
3124 <context context-type="linenumber">103</context>
3125 </context-group>
3126 </trans-unit>
3127 <trans-unit id="5cb397241041f7ad70997806227bafcdf7eb1b33">
3128 <source>Go the channel page</source>
3129 <target>Ga naar kanaalpagina</target>
3130 <context-group name="null">
3131 <context context-type="linenumber">123</context>
3132 </context-group>
3133 </trans-unit>
3134 <trans-unit id="0b7f242da10ece3f2995095c455b9a92ebcdd3b4">
3135 <source>By <x id="INTERPOLATION" equiv-text="{{ video.byAccount }}"/></source>
3136 <target>Door <x id="INTERPOLATION" equiv-text="{{ video.byAccount }}"/></target>
3137 <context-group name="null">
3138 <context context-type="linenumber">134</context>
3139 </context-group>
3140 </trans-unit>
3141 <trans-unit id="f0c5f6f270e70cbe063b5368fcf48f9afc1abd9b">
3142 <source>Show more</source>
3143 <target>Laat meer zien</target>
3144 <context-group name="null">
3145 <context context-type="linenumber">146</context>
3146 </context-group>
3147 </trans-unit>
3148 <trans-unit id="5403a767248e304199592271bba3366d2ca3f903">
3149 <source>Show less</source>
3150 <target>Laat minder zien</target>
3151 <context-group name="null">
3152 <context context-type="linenumber">152</context>
3153 </context-group>
3154 </trans-unit>
3155 <trans-unit id="4c0ba3cde3b3c58b855ffb4beaa5804a2fc3826b">
3156 <source>Friendly Reminder: </source>
3157 <target>Vriendelijke Herinnering:</target>
3158 <context-group name="null">
3159 <context context-type="linenumber">208</context>
3160 </context-group>
3161 </trans-unit>
3162 <trans-unit id="9e66f7507eb263abdbab7abafd825f1dc8bc880b">
3163 <source>
3164 the sharing system used for this video implies that some technical information about your system (such as a public IP address) can be sent to other peers.
3165 </source>
3166 <target>
3167 Uit het deelsysteem gebruikt voor deze video blijkt het dat sommige technische informatie over jouw systeem (zoals een openbaar IP adres) verstuurd kan worden naar andere peers.
3168 </target>
3169 <context-group name="null">
3170 <context context-type="linenumber">209</context>
3171 </context-group>
3172 </trans-unit>
3173 <trans-unit id="e60c11e1b1dfbbeda577364b8de39ded2d796c5e">
3174 <source>More information</source>
3175 <target>Meer informatie</target>
3176 <context-group name="null">
3177 <context context-type="linenumber">212</context>
3178 </context-group>
3179 </trans-unit>
3180 <trans-unit id="bd499ca7913bb5408fd139a4cb4f863852d5f318">
3181 <source>Get more information</source>
3182 <target>Krijg meer informatie</target>
3183 <context-group name="null">
3184 <context context-type="linenumber">212</context>
3185 </context-group>
3186 </trans-unit>
3187 <trans-unit id="20fc98888baf65b5ba9fe9622dc036fa8dec6a5f">
3188 <source>
3189 OK
3190 </source>
3191 <target>
3192 OK
3193 </target>
3194 <context-group name="null">
3195 <context context-type="linenumber">215</context>
3196 </context-group>
3197 </trans-unit>
3198 <trans-unit id="abf2b0f7b6405fa2841ca39c827e86089a95cc27">
3199 <source>
3200 Other videos
3201 </source>
3202 <target>
3203 Andere videos
3204 </target>
3205 <context-group name="null">
3206 <context context-type="linenumber">2</context>
3207 </context-group>
3208 </trans-unit>
3209 <trans-unit id="b5f5df598f2d75640849b2a7744f91e5dbd390e7">
3210 <source>
3211 Comments
3212 </source>
3213 <target>
3214 Reacties
3215 </target>
3216 <context-group name="null">
3217 <context context-type="linenumber">3</context>
3218 </context-group>
3219 </trans-unit>
3220 <trans-unit id="17810e68b0ba21e62e61eecfaf0a93b2c91033b4">
3221 <source>No comments.</source>
3222 <target>Geen reacties</target>
3223 <context-group name="null">
3224 <context context-type="linenumber">17</context>
3225 </context-group>
3226 </trans-unit>
3227 <trans-unit id="69c081796209e45e26af91152ec9bd0a65ec261e">
3228 <source>View all <x id="INTERPOLATION" equiv-text="{{ comment.totalReplies }}"/> replies</source>
3229 <target>Laat alle <x id="INTERPOLATION" equiv-text="{{ comment.totalReplies }}"/> antwoorden zien</target>
3230 <context-group name="null">
3231 <context context-type="linenumber">54</context>
3232 </context-group>
3233 </trans-unit>
3234 <trans-unit id="b7fccd922d6473725247ed85a9fdf96fe6794828">
3235 <source>
3236 Comments are disabled.
3237 </source>
3238 <target>
3239 Reacties zijn uitgeschakeld.
3240 </target>
3241 <context-group name="null">
3242 <context context-type="linenumber">63</context>
3243 </context-group>
3244 </trans-unit>
3245 <trans-unit id="db79255cb8757e9e945ba5f901a2b67e4189016e">
3246 <source>Add comment...</source>
3247 <target>Voeg reactie toe...</target>
3248 <context-group name="null">
3249 <context context-type="linenumber">6</context>
3250 </context-group>
3251 </trans-unit>
3252 <trans-unit id="26fa50ba8e69b53162b348d98e25f8b76c81343e">
3253 <source>
3254 Post comment
3255 </source>
3256 <target>
3257 Post reactie.
3258 </target>
3259 <context-group name="null">
3260 <context context-type="linenumber">20</context>
3261 </context-group>
3262 </trans-unit>
3263 <trans-unit id="8b2bb53dfb5f059f2b68cc4ac00661a865909135">
3264 <source>You are one step away from commenting</source>
3265 <target>Je bent een stap verwijderd van reageren</target>
3266 <context-group name="null">
3267 <context context-type="linenumber">28</context>
3268 </context-group>
3269 </trans-unit>
3270 <trans-unit id="7984a44ce86b961f4f18c9a58c638f5e8f07a225">
3271 <source>
3272 If you have an account on this instance, you can login:
3273 </source>
3274 <target>
3275 Als je een account hebt op deze instantie, kan je inloggen:
3276 </target>
3277 <context-group name="null">
3278 <context context-type="linenumber">32</context>
3279 </context-group>
3280 </trans-unit>
3281 <trans-unit id="afe0ad39fee662489f1033e53aea3e16a7e89228">
3282 <source>login to comment</source>
3283 <target>log in om te reageren</target>
3284 <context-group name="null">
3285 <context context-type="linenumber">35</context>
3286 </context-group>
3287 </trans-unit>
3288 <trans-unit id="a5a3f17c9b4876952d78363834d57280c8684e7c">
3289 <source>
3290 Otherwise you can comment using an account on any ActivityPub-compatible instance.
3291 On most platforms, you can find the video by typing its URL in the search bar and then comment it
3292 from within the software's interface.
3293 </source>
3294 <target>
3295 Anders kan je reageren door een account te gebruiken op welke ActivityPub-compatibele instatie dan ook.
3296 Op de meeste platforms kan je de video vinden door zijn URL in de zoekbalk te typen en vervolgens het vanuit binnenin de software's interface te reageren.</target>
3297 <context-group name="null">
3298 <context context-type="linenumber">36</context>
3299 </context-group>
3300 </trans-unit>
3301 <trans-unit id="968b02fbc645be799727de0d1ec3c6f9b11b20eb">
3302 <source>
3303 If you have an account on Mastodon or Pleroma, you can open it directly in their interface:
3304 </source>
3305 <target>
3306Als je een account op Mastodon of Pleroma hebt, kan je het direct openen vanuit hun interface:</target>
3307 <context-group name="null">
3308 <context context-type="linenumber">41</context>
3309 </context-group>
3310 </trans-unit>
3311 <trans-unit id="a607fab03e11b0e07c1640e11a1b02d7af06b285">
3312 <source>Highlighted comment</source>
3313 <target>Belichte reactie</target>
3314 <context-group name="null">
3315 <context context-type="linenumber">5</context>
3316 </context-group>
3317 </trans-unit>
3318 <trans-unit id="cb23d4d98007aa4d7123837f4c17a671848377d6">
3319 <source>Reply</source>
3320 <target>Antwoord</target>
3321 <context-group name="null">
3322 <context context-type="linenumber">14</context>
3323 </context-group>
3324 </trans-unit>
3325 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
3326 <source>No description</source>
3327 <target>Geen beschrijving</target>
3328 <context-group name="null">
3329 <context context-type="linenumber">1</context>
3330 </context-group>
3331 </trans-unit>
3332 <trans-unit id="2f03e577e8f81a9f8be0095f93e1f9376c6eedc9">
3333 <source>Published videos</source>
3334 <target>Gepubliceerde videos</target>
3335 <context-group name="null">
3336 <context context-type="linenumber">1</context>
3337 </context-group>
3338 </trans-unit>
3339 <trans-unit id="369ef5e9c0dd1251abdbf699a5db408bca10777f">
3340 <source>Published <x id="INTERPOLATION" equiv-text="{{totalVideos}}"/> videos</source>
3341 <target><x id="INTERPOLATION" equiv-text="{{totalVideos}}"/> Videos gepubliceerd</target>
3342 <context-group name="null">
3343 <context context-type="linenumber">1</context>
3344 </context-group>
3345 </trans-unit>
3346 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
3347 <source>240p</source>
3348 <target>240p</target>
3349 <context-group name="null">
3350 <context context-type="linenumber">1</context>
3351 </context-group>
3352 </trans-unit>
3353 <trans-unit id="c8cfad7e7a16c57c42535331b65cb7de40d8402e">
3354 <source>360p</source>
3355 <target>360p</target>
3356 <context-group name="null">
3357 <context context-type="linenumber">1</context>
3358 </context-group>
3359 </trans-unit>
3360 <trans-unit id="48f0af5a0d0bea4e84b27eaf41b19c85a531c2a5">
3361 <source>480p</source>
3362 <target>480p</target>
3363 <context-group name="null">
3364 <context context-type="linenumber">1</context>
3365 </context-group>
3366 </trans-unit>
3367 <trans-unit id="6f06138daf6363746ff26bfc0cb2491c09cdfdf2">
3368 <source>720p</source>
3369 <target>720p</target>
3370 <context-group name="null">
3371 <context context-type="linenumber">1</context>
3372 </context-group>
3373 </trans-unit>
3374 <trans-unit id="65c94f9beb6fe957808c40060da280cc7ace7ab9">
3375 <source>1080p</source>
3376 <target>1080p</target>
3377 <context-group name="null">
3378 <context context-type="linenumber">1</context>
3379 </context-group>
3380 </trans-unit>
3381 <trans-unit id="421a937491f19774d17eefa1d24816dae1a9f111">
3382 <source>Auto (via ffmpeg)</source>
3383 <target>Auto (via ffmpeg)</target>
3384 <context-group name="null">
3385 <context context-type="linenumber">1</context>
3386 </context-group>
3387 </trans-unit>
3388 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
3389 <source>Configuration updated.</source>
3390 <target>Configuratie bijgewerkt.</target>
3391 <context-group name="null">
3392 <context context-type="linenumber">1</context>
3393 </context-group>
3394 </trans-unit>
3395 <trans-unit id="aa6fb95c355f172bda303de1ce2f38c251a149cf">
3396 <source>Unlimited</source>
3397 <target>Oneindig</target>
3398 <context-group name="null">
3399 <context context-type="linenumber">1</context>
3400 </context-group>
3401 </trans-unit>
3402 <trans-unit id="54adc67482fdaa0d361a2992bc91e064dc61cc9a">
3403 <source>100MB</source>
3404 <target>100MB</target>
3405 <context-group name="null">
3406 <context context-type="linenumber">1</context>
3407 </context-group>
3408 </trans-unit>
3409 <trans-unit id="cd34ef1f476d5422f49f6ed429f61fc1cfcb1174">
3410 <source>500MB</source>
3411 <target>500MB</target>
3412 <context-group name="null">
3413 <context context-type="linenumber">1</context>
3414 </context-group>
3415 </trans-unit>
3416 <trans-unit id="4a47b4beea31cac6e5970b6bc522902f545acc8b">
3417 <source>1GB</source>
3418 <target>1GB</target>
3419 <context-group name="null">
3420 <context context-type="linenumber">1</context>
3421 </context-group>
3422 </trans-unit>
3423 <trans-unit id="b26d0cac75638623098ab7e06e16b096d1f55cc8">
3424 <source>5GB</source>
3425 <target>5GB</target>
3426 <context-group name="null">
3427 <context context-type="linenumber">1</context>
3428 </context-group>
3429 </trans-unit>
3430 <trans-unit id="f9fc4e7ec6743cb6f69bea2d0859a655ed44ffae">
3431 <source>20GB</source>
3432 <target>20GB</target>
3433 <context-group name="null">
3434 <context context-type="linenumber">1</context>
3435 </context-group>
3436 </trans-unit>
3437 <trans-unit id="a56e3f92fe16d97ee4f05051ea61c466ecb51d5e">
3438 <source>50GB</source>
3439 <target>50GB</target>
3440 <context-group name="null">
3441 <context context-type="linenumber">1</context>
3442 </context-group>
3443 </trans-unit>
3444 <trans-unit id="31dcc0c63f6234ace8caa84ae1abc33d4022122d">
3445 <source>10MB</source>
3446 <target>10MB</target>
3447 <context-group name="null">
3448 <context context-type="linenumber">1</context>
3449 </context-group>
3450 </trans-unit>
3451 <trans-unit id="f2f968b6f2199b919f567702c6f23b43e5ea71af">
3452 <source>50MB</source>
3453 <target>50MB</target>
3454 <context-group name="null">
3455 <context context-type="linenumber">1</context>
3456 </context-group>
3457 </trans-unit>
3458 <trans-unit id="c31575424fe1b2a57064413f3eda7ce657c46c8a">
3459 <source>2GB</source>
3460 <target>2GB</target>
3461 <context-group name="null">
3462 <context context-type="linenumber">1</context>
3463 </context-group>
3464 </trans-unit>
3465 <trans-unit id="fc5731a28a99b25c62d43333ceebb250d60aff84">
3466 <source><x id="INTERPOLATION" equiv-text="{{host}}"/> is not valid</source>
3467 <target><x id="INTERPOLATION" equiv-text="{{host}}"/> is niet valide</target>
3468 <context-group name="null">
3469 <context context-type="linenumber">1</context>
3470 </context-group>
3471 </trans-unit>
3472 <trans-unit id="e02f50674f1d96966384dc096beb42d4973997df">
3473 <source>You need to specify hosts to follow.</source>
3474 <target>Je moet de hosts specificeren om te volgen.</target>
3475 <context-group name="null">
3476 <context context-type="linenumber">1</context>
3477 </context-group>
3478 </trans-unit>
3479 <trans-unit id="c2a114eb000e7c38e8ad4b1768821bdf6e946d71">
3480 <source>Hosts need to be unique.</source>
3481 <target>Hosts moeten uniek zijn.</target>
3482 <context-group name="null">
3483 <context context-type="linenumber">1</context>
3484 </context-group>
3485 </trans-unit>
3486 <trans-unit id="a6718d6aaf5bcd1692eed48daa61d2bed62c1f50">
3487 <source>If you confirm, you will send a follow request to:<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> - </source>
3488 <target>Als je bevestigd, verzend je een volgverzoek naar:<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> - </target>
3489 <context-group name="null">
3490 <context context-type="linenumber">1</context>
3491 </context-group>
3492 </trans-unit>
3493 <trans-unit id="1266acb081ef0324c4a38ae2d514dd75d8b38409">
3494 <source>Follow new server(s)</source>
3495 <target>Volg nieuwe server(s)</target>
3496 <context-group name="null">
3497 <context context-type="linenumber">1</context>
3498 </context-group>
3499 </trans-unit>
3500 <trans-unit id="950f5111d567e5c0e971f07c26e8c2be1d919a8e">
3501 <source>Follow request(s) sent!</source>
3502 <target>Volgverzoek(en) verstuurd!</target>
3503 <context-group name="null">
3504 <context context-type="linenumber">1</context>
3505 </context-group>
3506 </trans-unit>
3507 <trans-unit id="5729c34a858c78daa1aa606f62a3665527cf97e6">
3508 <source>Do you really want to unfollow <x id="INTERPOLATION" equiv-text="{{host}}"/>?</source>
3509 <target>Wil je echt <x id="INTERPOLATION" equiv-text="{{host}}"/> onvolgen?</target>
3510 <context-group name="null">
3511 <context context-type="linenumber">1</context>
3512 </context-group>
3513 </trans-unit>
3514 <trans-unit id="a89875525c82ab81ffe32e481a5475b43d0c2902">
3515 <source>Unfollow</source>
3516 <target>Onvolgen</target>
3517 <context-group name="null">
3518 <context context-type="linenumber">1</context>
3519 </context-group>
3520 </trans-unit>
3521 <trans-unit id="fb4e35e2b0ea2abc1f71295a4b34830e57c07bd0">
3522 <source>You are not following <x id="INTERPOLATION" equiv-text="{{host}}"/> anymore.</source>
3523 <target>Je volgt <x id="INTERPOLATION" equiv-text="{{host}}"/> niet meer.</target>
3524 <context-group name="null">
3525 <context context-type="linenumber">1</context>
3526 </context-group>
3527 </trans-unit>
3528 <trans-unit id="4d8f527638f3e0b518a96e07d41d886bcce01246">
3529 <source>enabled</source>
3530 <target>ingeschakeld</target>
3531 <context-group name="null">
3532 <context context-type="linenumber">1</context>
3533 </context-group>
3534 </trans-unit>
3535 <trans-unit id="795733aac948794cadeb3be6386882efac2c38ad">
3536 <source>disabled</source>
3537 <target>uitgeschakeld</target>
3538 <context-group name="null">
3539 <context context-type="linenumber">1</context>
3540 </context-group>
3541 </trans-unit>
3542 <trans-unit id="1123807fc813c816404598147173403d00117557">
3543 <source>Redundancy for <x id="INTERPOLATION" equiv-text="{{host}}"/> is <x id="INTERPOLATION_1" equiv-text="{{stateLabel}}"/></source>
3544 <target>Overtolligheid voor<x id="INTERPOLATION" equiv-text="{{host}}"/> is <x id="INTERPOLATION_1" equiv-text="{{stateLabel}}"/></target>
3545 <context-group name="null">
3546 <context context-type="linenumber">1</context>
3547 </context-group>
3548 </trans-unit>
3549 <trans-unit id="53cc0f4a4566c4139c65f93b5dce2fe8302e78da">
3550 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by your instance.</source>
3551 <target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> niet meer gedempt door jouw instantie.</target>
3552 <context-group name="null">
3553 <context context-type="linenumber">1</context>
3554 </context-group>
3555 </trans-unit>
3556 <trans-unit id="468b52e3c04fb9a3d8c8213555dfcad0cbcae330">
3557 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by your instance.</source>
3558 <target>Instantie <x id="INTERPOLATION" equiv-text="{{host}}"/> niet meer gedempt door jouw instantie.</target>
3559 <context-group name="null">
3560 <context context-type="linenumber">1</context>
3561 </context-group>
3562 </trans-unit>
3563 <trans-unit id="800cd3cdf47751b576587259ba3a1bc0a7f435b6">
3564 <source>Comment updated.</source>
3565 <target>Reactie bijgewerkt.</target>
3566 <context-group name="null">
3567 <context context-type="linenumber">1</context>
3568 </context-group>
3569 </trans-unit>
3570 <trans-unit id="586bee8c27a761611eb05661524cc7ca944b5978">
3571 <source>Delete this report</source>
3572 <target>Verwijder deze rapportage</target>
3573 <context-group name="null">
3574 <context context-type="linenumber">1</context>
3575 </context-group>
3576 </trans-unit>
3577 <trans-unit id="cf3b28ba29a907b334ab0e6dccd080a60ba23321">
3578 <source>Update moderation comment</source>
3579 <target>Werk beheerder-reactie bij</target>
3580 <context-group name="null">
3581 <context context-type="linenumber">1</context>
3582 </context-group>
3583 </trans-unit>
3584 <trans-unit id="d512430037b6580ba970c80cfc1687b6bdc221a3">
3585 <source>Mark as accepted</source>
3586 <target>Markeer als geaccepteerd</target>
3587 <context-group name="null">
3588 <context context-type="linenumber">1</context>
3589 </context-group>
3590 </trans-unit>
3591 <trans-unit id="d895b090c054bfc0ad3aba816af0615a1997f5a3">
3592 <source>Mark as rejected</source>
3593 <target>Markeer als afgewezen</target>
3594 <context-group name="null">
3595 <context context-type="linenumber">1</context>
3596 </context-group>
3597 </trans-unit>
3598 <trans-unit id="73b70e37cddaa6494d8a666b6cba90dc80595599">
3599 <source>Do you really want to delete this abuse report?</source>
3600 <target>Wil je echt dit misbruiksrapportage verwijderen?</target>
3601 <context-group name="null">
3602 <context context-type="linenumber">1</context>
3603 </context-group>
3604 </trans-unit>
3605 <trans-unit id="6a7938b8780c27540ea70cc0f8f4d928c8916cf9">
3606 <source>Abuse deleted.</source>
3607 <target>Misbruik verwijdert.</target>
3608 <context-group name="null">
3609 <context context-type="linenumber">1</context>
3610 </context-group>
3611 </trans-unit>
3612 <trans-unit id="652845b2b32b2e117b9b02879b1af07859b0e223">
3613 <source>Do you really want to remove this video from the blacklist? It will be available again in the videos list.</source>
3614 <target>Wil je deze video echt verwijderen van je zwarte lijst? Hij zal weer beschikbaar zijn in de videolijst.</target>
3615 <context-group name="null">
3616 <context context-type="linenumber">1</context>
3617 </context-group>
3618 </trans-unit>
3619 <trans-unit id="1585babc36806e20e225ac27dbba0e7c7cd09e0f">
3620 <source>Video <x id="INTERPOLATION" equiv-text="{{name}}"/> removed from the blacklist.</source>
3621 <target>Video <x id="INTERPOLATION" equiv-text="{{name}}"/> verwijdert van de zwarte lijst.</target>
3622 <context-group name="null">
3623 <context context-type="linenumber">1</context>
3624 </context-group>
3625 </trans-unit>
3626 <trans-unit id="364463fab6c5714118d6449561a0f8de1cc10bfa">
3627 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> created.</source>
3628 <target>Gebruiker <x id="INTERPOLATION" equiv-text="{{username}}"/> verwijdert.</target>
3629 <context-group name="null">
3630 <context context-type="linenumber">1</context>
3631 </context-group>
3632 </trans-unit>
3633 <trans-unit id="964865a3cd90b4af99902f071644a4b2aede4c32">
3634 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> updated.</source>
3635 <target>Gebruiker <x id="INTERPOLATION" equiv-text="{{username}}"/> bijgewerkt.</target>
3636 <context-group name="null">
3637 <context context-type="linenumber">1</context>
3638 </context-group>
3639 </trans-unit>
3640 <trans-unit id="9910122dfedd2eaa544a990f1430e5b82a76d99f">
3641 <source>Update user</source>
3642 <target>Werk gebruiker bij</target>
3643 <context-group name="null">
3644 <context context-type="linenumber">1</context>
3645 </context-group>
3646 </trans-unit>
3647 <trans-unit id="50dc7afa2305131cdbdb384cfc1f2a5f0f4647d8">
3648 <source>Unban</source>
3649 <target>Onverban</target>
3650 <context-group name="null">
3651 <context context-type="linenumber">1</context>
3652 </context-group>
3653 </trans-unit>
3654 <trans-unit id="910ed85f550272401b134a40d019ab3359fe883f">
3655 <source>Set Email as Verified</source>
3656 <target>Zet E-mail als Geverifieerd</target>
3657 <context-group name="null">
3658 <context context-type="linenumber">1</context>
3659 </context-group>
3660 </trans-unit>
3661 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf">
3662 <source>You cannot ban root.</source>
3663 <target>Je kan root niet verbannen.</target>
3664 <context-group name="null">
3665 <context context-type="linenumber">1</context>
3666 </context-group>
3667 </trans-unit>
3668 <trans-unit id="98119091712a8ca72905e3b4c1cf60649af7565e">
3669 <source>Do you really want to unban <x id="INTERPOLATION" equiv-text="{{num}}"/> users?</source>
3670 <target>Wil jij echt <x id="INTERPOLATION" equiv-text="{{num}}"/> gebruikers onverbannen?</target>
3671 <context-group name="null">
3672 <context context-type="linenumber">1</context>
3673 </context-group>
3674 </trans-unit>
3675 <trans-unit id="6121be086a51c4c73bbdd8aebdddd9744c8f1ffd">
3676 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users unbanned.</source>
3677 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> gebruikers onverbannen.</target>
3678 <context-group name="null">
3679 <context context-type="linenumber">1</context>
3680 </context-group>
3681 </trans-unit>
3682 <trans-unit id="911fc197949e47aa5f0541627bc319f59edd9d11">
3683 <source>You cannot delete root.</source>
3684 <target>Je kan root niet verwijderen.</target>
3685 <context-group name="null">
3686 <context context-type="linenumber">1</context>
3687 </context-group>
3688 </trans-unit>
3689 <trans-unit id="9de914fe915cc730efc57e81c987188a24d3ac51">
3690 <source>If you remove these users, you will not be able to create others with the same username!</source>
3691 <target>Als jij deze gebruikers verwijdert, kan je niet meer anderen maken met dezelfde gebruikersnaam!</target>
3692 <context-group name="null">
3693 <context context-type="linenumber">1</context>
3694 </context-group>
3695 </trans-unit>
3696 <trans-unit id="b708d332e3f89b24745e749fa530210f0bdea329">
3697 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users deleted.</source>
3698 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> gebruikers verwijdert.</target>
3699 <context-group name="null">
3700 <context context-type="linenumber">1</context>
3701 </context-group>
3702 </trans-unit>
3703 <trans-unit id="f4a8f2ef1fbfc19e1e049e69f63c40063c0d0650">
3704 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users email set as verified.</source>
3705 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> gebruikers'' gezet als geverifieerd.</target>
3706 <context-group name="null">
3707 <context context-type="linenumber">1</context>
3708 </context-group>
3709 </trans-unit>
3710 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de">
3711 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source>
3712 <target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> niet meer gedempt.</target>
3713 <context-group name="null">
3714 <context context-type="linenumber">1</context>
3715 </context-group>
3716 </trans-unit>
3717 <trans-unit id="c6af80b42938d4a49e6f6c4f60ce26228916994c">
3718 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted.</source>
3719 <target>Instantie <x id="INTERPOLATION" equiv-text="{{host}}"/> niet meer gedempt.</target>
3720 <context-group name="null">
3721 <context context-type="linenumber">1</context>
3722 </context-group>
3723 </trans-unit>
3724 <trans-unit id="507192ee1fa84aefed02d603caada2d84927023e">
3725 <source>Ownership accepted</source>
3726 <target>Eigendom geaccepteerd</target>
3727 <context-group name="null">
3728 <context context-type="linenumber">1</context>
3729 </context-group>
3730 </trans-unit>
3731 <trans-unit id="19508af0dfbc685cbf10cf02061bb5a0f423b6fc">
3732 <source>Password updated.</source>
3733 <target>Wachtwoord bijgewerkt.</target>
3734 <context-group name="null">
3735 <context context-type="linenumber">1</context>
3736 </context-group>
3737 </trans-unit>
3738 <trans-unit id="466fc8cf56fd4e4e90fec4b900ef083d52bec38c">
3739 <source>You current password is invalid.</source>
3740 <target>Jouw huide wachtwoord is invalide.</target>
3741 <context-group name="null">
3742 <context context-type="linenumber">1</context>
3743 </context-group>
3744 </trans-unit>
3745 <trans-unit id="ca8e8cf0f1686604db3b6a2ebadab7f7b426a047">
3746 <source>Are you sure you want to delete your account? This will delete all you data, including channels, videos etc.</source>
3747 <target>Weet je zeker dat je jouw account wil verwijderen? Dit verwijdert al jouw data, inclusief kanalen, videos etc.</target>
3748 <context-group name="null">
3749 <context context-type="linenumber">1</context>
3750 </context-group>
3751 </trans-unit>
3752 <trans-unit id="e7d5b2de566e4c807c285daf8d8a78b5f7f33311">
3753 <source>Type your username to confirm</source>
3754 <target>Typ je gebruikersnaam in om te bevestigen</target>
3755 <context-group name="null">
3756 <context context-type="linenumber">1</context>
3757 </context-group>
3758 </trans-unit>
3759 <trans-unit id="d8a8a7f7160939fb55e82bc01fe9f876f5f2e065">
3760 <source>Delete my account</source>
3761 <target>Verwijder mijn account</target>
3762 <context-group name="null">
3763 <context context-type="linenumber">1</context>
3764 </context-group>
3765 </trans-unit>
3766 <trans-unit id="8eb8b1a728159f43c31abf76c28ef3ff6c230af7">
3767 <source>Your account is deleted.</source>
3768 <target>Jouw account is verwijdert.</target>
3769 <context-group name="null">
3770 <context context-type="linenumber">1</context>
3771 </context-group>
3772 </trans-unit>
3773 <trans-unit id="db4ff52375f6a25ad0472e92754c8c265ae47c6b">
3774 <source>Profile updated.</source>
3775 <target>Profiel bijgewerkt.</target>
3776 <context-group name="null">
3777 <context context-type="linenumber">1</context>
3778 </context-group>
3779 </trans-unit>
3780 <trans-unit id="1e003ad599ef836949b9f4dad3037a58ef3ff8d1">
3781 <source>Avatar changed.</source>
3782 <target>Avatar verandert.</target>
3783 <context-group name="null">
3784 <context context-type="linenumber">1</context>
3785 </context-group>
3786 </trans-unit>
3787 <trans-unit id="214b802dfd6f544003147a7a68938ec1055c8f32">
3788 <source>Information updated.</source>
3789 <target>Informatie bijgewerkt.</target>
3790 <context-group name="null">
3791 <context context-type="linenumber">1</context>
3792 </context-group>
3793 </trans-unit>
3794 <trans-unit id="3ef8bf973a9a481a08c6f0aaa875f0259b3ea645">
3795 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> created.</source>
3796 <target>Videokanaal <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> gecreëerd.</target>
3797 <context-group name="null">
3798 <context context-type="linenumber">1</context>
3799 </context-group>
3800 </trans-unit>
3801 <trans-unit id="f359f6adf6cccca7770019f947ed594169ee7d47">
3802 <source>This name already exists on this instance.</source>
3803 <target>Deze naam bestaat al op deze instantie.</target>
3804 <context-group name="null">
3805 <context context-type="linenumber">1</context>
3806 </context-group>
3807 </trans-unit>
3808 <trans-unit id="70a67e04629f6d412db0a12d51820b480788d795">
3809 <source>Create</source>
3810 <target>Creeër</target>
3811 <context-group name="null">
3812 <context context-type="linenumber">1</context>
3813 </context-group>
3814 </trans-unit>
3815 <trans-unit id="98ab64f0af924a60a48b40835c1b655bd17c6559">
3816 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> updated.</source>
3817 <target>Videokanaal <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> bijgewerkt.</target>
3818 <context-group name="null">
3819 <context context-type="linenumber">1</context>
3820 </context-group>
3821 </trans-unit>
3822 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
3823 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
3824 <target>Videokanaal <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> verwijdert.</target>
3825 <context-group name="null">
3826 <context context-type="linenumber">1</context>
3827 </context-group>
3828 </trans-unit>
3829 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
3830 <source>My videos</source>
3831 <target>Mijn video's</target>
3832 <context-group name="null">
3833 <context context-type="linenumber">1</context>
3834 </context-group>
3835 </trans-unit>
3836 <trans-unit id="00e16d1f1c5cc936ec0881cd02cbf66aa1b4cddd">
3837 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{deleteLength}}"/> videos?</source>
3838 <target>Wil jij echt <x id="INTERPOLATION" equiv-text="{{deleteLength}}"/> videos verwijderen?</target>
3839 <context-group name="null">
3840 <context context-type="linenumber">1</context>
3841 </context-group>
3842 </trans-unit>
3843 <trans-unit id="dff7d4574cfaa785cbd4c0a5ffb5befec19a5d83">
3844 <source><x id="INTERPOLATION" equiv-text="{{deleteLength}}"/> videos deleted.</source>
3845 <target><x id="INTERPOLATION" equiv-text="{{deleteLength}}"/> videos verwijdert.</target>
3846 <context-group name="null">
3847 <context context-type="linenumber">1</context>
3848 </context-group>
3849 </trans-unit>
3850 <trans-unit id="4ec5852c869b2fb4ae0e564b51278d7be8013fc7">
3851 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoName}}"/>?</source>
3852 <target>Weet jij zeker dat je<x id="INTERPOLATION" equiv-text="{{videoName}}"/> wilt verwijderen?</target>
3853 <context-group name="null">
3854 <context context-type="linenumber">1</context>
3855 </context-group>
3856 </trans-unit>
3857 <trans-unit id="d39a0bfa616a9a8473b2e379eefe17d8ed1af118">
3858 <source>Video <x id="INTERPOLATION" equiv-text="{{videoName}}"/> deleted.</source>
3859 <target>Video <x id="INTERPOLATION" equiv-text="{{videoName}}"/> verwijdert.</target>
3860 <context-group name="null">
3861 <context context-type="linenumber">1</context>
3862 </context-group>
3863 </trans-unit>
3864 <trans-unit id="dd9f3264feed4935008861c15d81c947124e4ac3">
3865 <source>Published</source>
3866 <target>Gepubliceerd</target>
3867 <context-group name="null">
3868 <context context-type="linenumber">1</context>
3869 </context-group>
3870 </trans-unit>
1314 <trans-unit id="8e6d54c4f760d9e90518eef5334211c48c0b71e2"> 3871 <trans-unit id="8e6d54c4f760d9e90518eef5334211c48c0b71e2">
1315 <source>Publication scheduled on </source> 3872 <source>Publication scheduled on </source>
1316 <target>Publicatie uitgesteld tot</target> 3873 <target>Publicatie uitgesteld tot</target>
@@ -1318,23 +3875,1699 @@ Als je een video uploadt in dit kanaal, wordt deze tekst ingevuld in het "onders
1318 <context context-type="linenumber">1</context> 3875 <context context-type="linenumber">1</context>
1319 </context-group> 3876 </context-group>
1320 </trans-unit> 3877 </trans-unit>
3878 <trans-unit id="4a7e91ebe1cf184db5f2bfecf9c16ff81c9e2c02">
3879 <source>Waiting transcoding</source>
3880 <target>Wachten op transcoding</target>
3881 <context-group name="null">
3882 <context context-type="linenumber">1</context>
3883 </context-group>
3884 </trans-unit>
3885 <trans-unit id="21f1c9d5c67346c830aced4f670045fcf0aeb83a">
3886 <source>To transcode</source>
3887 <target>Om te transcoden</target>
3888 <context-group name="null">
3889 <context context-type="linenumber">1</context>
3890 </context-group>
3891 </trans-unit>
3892 <trans-unit id="289fe8342e8b7df689c75026a24a60fd7f5e9392">
3893 <source>To import</source>
3894 <target>Om te importeren</target>
3895 <context-group name="null">
3896 <context context-type="linenumber">1</context>
3897 </context-group>
3898 </trans-unit>
3899 <trans-unit id="740c53a50a618bf5c7a5bd5c3f7321f0bd1840dd">
3900 <source>Ownership change request sent.</source>
3901 <target>Eigenaarsveranderingsaanvrag gestuurd.</target>
3902 <context-group name="null">
3903 <context context-type="linenumber">1</context>
3904 </context-group>
3905 </trans-unit>
3906 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
3907 <source>My library</source>
3908 <target>Mijn bibliotheek</target>
3909 <context-group name="null">
3910 <context context-type="linenumber">1</context>
3911 </context-group>
3912 </trans-unit>
3913 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
3914 <source>My channels</source>
3915 <target>Mijn kanalen</target>
3916 <context-group name="null">
3917 <context context-type="linenumber">1</context>
3918 </context-group>
3919 </trans-unit>
3920 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
3921 <source>My subscriptions</source>
3922 <target>Mijn abonnementen</target>
3923 <context-group name="null">
3924 <context context-type="linenumber">1</context>
3925 </context-group>
3926 </trans-unit>
3927 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
3928 <source>Misc</source>
3929 <target>Varia</target>
3930 <context-group name="null">
3931 <context context-type="linenumber">1</context>
3932 </context-group>
3933 </trans-unit>
3934 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
3935 <source>Ownership changes</source>
3936 <target>Veranderingen van eigenaar</target>
3937 <context-group name="null">
3938 <context context-type="linenumber">1</context>
3939 </context-group>
3940 </trans-unit>
3941 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
3942 <source>My settings</source>
3943 <target>Mijn instellingen</target>
3944 <context-group name="null">
3945 <context context-type="linenumber">1</context>
3946 </context-group>
3947 </trans-unit>
3948 <trans-unit id="af55337b4032d675ab6b2081af797ca9c979b706">
3949 <source>An email with verification link will be sent to <x id="INTERPOLATION" equiv-text="{{email}}"/>.</source>
3950 <target>Een e-mail met verificatielink wordt verstuurd naar <x id="INTERPOLATION" equiv-text="{{email}}"/>.</target>
3951 <context-group name="null">
3952 <context context-type="linenumber">1</context>
3953 </context-group>
3954 </trans-unit>
3955 <trans-unit id="ccbf0490fb6b60d21e03bb2c9003df0ce1a58752">
3956 <source>Unable to find user id or verification string.</source>
3957 <target>Niet in staat om gebruikersid of verificatiestring te vinden.</target>
3958 <context-group name="null">
3959 <context context-type="linenumber">1</context>
3960 </context-group>
3961 </trans-unit>
3962 <trans-unit id="ff6becacbce7fc0943b0af0df4dd67e5e11bf598">
3963 <source>Subscribe to the account</source>
3964 <target>Abonneer op het account</target>
3965 <context-group name="null">
3966 <context context-type="linenumber">1</context>
3967 </context-group>
3968 </trans-unit>
3969 <trans-unit id="1c95cc372311830f936b39f73c5d6d20c0b16013">
3970 <source>Focus the search bar</source>
3971 <target>Focus de zoekbalk</target>
3972 <context-group name="null">
3973 <context context-type="linenumber">1</context>
3974 </context-group>
3975 </trans-unit>
3976 <trans-unit id="b19ee83cbd2b735fd081b9aa483a890578019099">
3977 <source>Toggle the left menu</source>
3978 <target>Schakel het linker menu aan of uit</target>
3979 <context-group name="null">
3980 <context context-type="linenumber">1</context>
3981 </context-group>
3982 </trans-unit>
3983 <trans-unit id="b54759e30f7c1983940cdacb8eb03f102a869084">
3984 <source>Go to the videos overview page</source>
3985 <target>Ga naar de video-overzichtspagina</target>
3986 <context-group name="null">
3987 <context context-type="linenumber">1</context>
3988 </context-group>
3989 </trans-unit>
3990 <trans-unit id="1e919c88a3f889d6659288e69d3e178da0ea7ab0">
3991 <source>Go to the trending videos page</source>
3992 <target>Ga naar de trending videos pagina</target>
3993 <context-group name="null">
3994 <context context-type="linenumber">1</context>
3995 </context-group>
3996 </trans-unit>
3997 <trans-unit id="249618dcdd7fbdc863c0714e2eb9e8940bc9c37d">
3998 <source>Go to the recently added videos page</source>
3999 <target>Ga naar recent toegevoegde videos pagina</target>
4000 <context-group name="null">
4001 <context context-type="linenumber">1</context>
4002 </context-group>
4003 </trans-unit>
4004 <trans-unit id="7e194daef3a3509128c4300d4c7c292c49ebf3f5">
4005 <source>Go to the local videos page</source>
4006 <target>Ga naar de locale videos pagina</target>
4007 <context-group name="null">
4008 <context context-type="linenumber">1</context>
4009 </context-group>
4010 </trans-unit>
4011 <trans-unit id="f1fb6204f39a7338e5110b2f113643c9288496ba">
4012 <source>Go to the videos upload page</source>
4013 <target>Ga naar de videos uploadpagina</target>
4014 <context-group name="null">
4015 <context context-type="linenumber">1</context>
4016 </context-group>
4017 </trans-unit>
4018 <trans-unit id="0ed7b40c11da9d4565af9c041df20c15bc6be97e">
4019 <source>Toggle Dark theme</source>
4020 <target>Schakel donker thema aan of uit</target>
4021 <context-group name="null">
4022 <context context-type="linenumber">1</context>
4023 </context-group>
4024 </trans-unit>
4025 <trans-unit id="badd4b24618ccc8a34620acb9053fc654b9612b2">
4026 <source>Go to my subscriptions</source>
4027 <target>Ga naar mijn abonnementen</target>
4028 <context-group name="null">
4029 <context context-type="linenumber">1</context>
4030 </context-group>
4031 </trans-unit>
4032 <trans-unit id="b7184b5a236618e8edd747529869c392ab6dace1">
4033 <source>Go to my videos</source>
4034 <target>Ga naar mijn videos</target>
4035 <context-group name="null">
4036 <context context-type="linenumber">1</context>
4037 </context-group>
4038 </trans-unit>
4039 <trans-unit id="acf985bd42886b9b3030b5f68f0e8417c39b40a7">
4040 <source>Go to my imports</source>
4041 <target>Ga naar mijn imports</target>
4042 <context-group name="null">
4043 <context context-type="linenumber">1</context>
4044 </context-group>
4045 </trans-unit>
4046 <trans-unit id="cfe3c51f0ae9385dc2ce6df740d87e5514aa9390">
4047 <source>Go to my channels</source>
4048 <target>Ga naar mijn kanalen</target>
4049 <context-group name="null">
4050 <context context-type="linenumber">1</context>
4051 </context-group>
4052 </trans-unit>
4053 <trans-unit id="edeaa933b09690523e46977e11064e9c655d77d7">
4054 <source>Cannot retrieve OAuth Client credentials: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>.
4055</source>
4056 <target>Kan niet credenties van OAuth Client verkrijgen: <x id="INTERPOLATION" equiv-text="{{errorText}}"/>.
4057</target>
4058 <context-group name="null">
4059 <context context-type="linenumber">1</context>
4060 </context-group>
4061 </trans-unit>
4062 <trans-unit id="8d9b4f4b69108c3c9aa0f3b0dbde87786ba9b319">
4063 <source>Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.</source>
4064 <target>Weet zeker dat je correct PeerTube geconfigureerd hebt (config/directory), vooral de "webserver" sectie.</target>
4065 <context-group name="null">
4066 <context context-type="linenumber">1</context>
4067 </context-group>
4068 </trans-unit>
4069 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
4070 <source>Error</source>
4071 <target>Fout</target>
4072 <context-group name="null">
4073 <context context-type="linenumber">1</context>
4074 </context-group>
4075 </trans-unit>
4076 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
4077 <source>You need to reconnect.</source>
4078 <target>Je moet opnieuw verbinden.</target>
4079 <context-group name="null">
4080 <context context-type="linenumber">1</context>
4081 </context-group>
4082 </trans-unit>
4083 <trans-unit id="68e710782ccb5398b3acb8844caf0b199da2c3da">
4084 <source>Confirm</source>
4085 <target>Bevestigen</target>
4086 <context-group name="null">
4087 <context context-type="linenumber">1</context>
4088 </context-group>
4089 </trans-unit>
4090 <trans-unit id="5c0c574151dc8671d9199980ee04bf65aec3b452">
4091 <source>Keyboard Shortcuts:</source>
4092 <target>Keyboard Shortcuts:</target>
4093 <context-group name="null">
4094 <context context-type="linenumber">1</context>
4095 </context-group>
4096 </trans-unit>
4097 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4098 <source>Info</source>
4099 <target>Info</target>
4100 <context-group name="null">
4101 <context context-type="linenumber">1</context>
4102 </context-group>
4103 </trans-unit>
4104 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
4105 <source>Success</source>
4106 <target>Success</target>
4107 <context-group name="null">
4108 <context context-type="linenumber">1</context>
4109 </context-group>
4110 </trans-unit>
4111 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
4112 <source>Incorrect username or password.</source>
4113 <target>Incorrecte gebruikersnaam of wachtwoord.</target>
4114 <context-group name="null">
4115 <context context-type="linenumber">1</context>
4116 </context-group>
4117 </trans-unit>
4118 <trans-unit id="39980cc1cf8df621d43f5480d001bdf5d4139338">
4119 <source>You account is blocked.</source>
4120 <target>Jouw account is geblokkeerd.</target>
4121 <context-group name="null">
4122 <context context-type="linenumber">1</context>
4123 </context-group>
4124 </trans-unit>
4125 <trans-unit id="7701e3762dc4a2b2e302c24f17820bc8dd7cacc1">
4126 <source>An email with the reset password instructions will be sent to <x id="INTERPOLATION" equiv-text="{{email}}"/>.</source>
4127 <target>Een e-mail met de wachtwoord reset instructies wordt gestuurd naar <x id="INTERPOLATION" equiv-text="{{email}}"/>.</target>
4128 <context-group name="null">
4129 <context context-type="linenumber">1</context>
4130 </context-group>
4131 </trans-unit>
4132 <trans-unit id="b0f24b7136e551a0deba831f1525711245b31a26">
4133 <source>Your password has been successfully reset!</source>
4134 <target>Jouw wachtwoord is succesvol gereset!</target>
4135 <context-group name="null">
4136 <context context-type="linenumber">1</context>
4137 </context-group>
4138 </trans-unit>
4139 <trans-unit id="7fb1099e29660162f9154d5b2feee7743a423df6">
4140 <source>Today</source>
4141 <target>Vandaag</target>
4142 <context-group name="null">
4143 <context context-type="linenumber">1</context>
4144 </context-group>
4145 </trans-unit>
4146 <trans-unit id="02e0243b60007368f87dc01e083f232dd025096d">
4147 <source>Last 7 days</source>
4148 <target>Laatste 7 dagen </target>
4149 <context-group name="null">
4150 <context context-type="linenumber">1</context>
4151 </context-group>
4152 </trans-unit>
4153 <trans-unit id="7668986b9f753fcd72ad4a00b1a0c4861d1f7fb8">
4154 <source>Last 30 days</source>
4155 <target>Laatste 30 dagen</target>
4156 <context-group name="null">
4157 <context context-type="linenumber">1</context>
4158 </context-group>
4159 </trans-unit>
4160 <trans-unit id="a77b663fd9b94c38bc9c6493a51b5f3acacb9bca">
4161 <source>Last 365 days</source>
4162 <target>Laatste 365 dagen</target>
4163 <context-group name="null">
4164 <context context-type="linenumber">1</context>
4165 </context-group>
4166 </trans-unit>
4167 <trans-unit id="d2f3bf121699ff08a25fa4859bfdf3996bf821cc">
4168 <source>Short (&lt; 4 min)</source>
4169 <target>Kort (&lt; 4 min)</target>
4170 <context-group name="null">
4171 <context context-type="linenumber">1</context>
4172 </context-group>
4173 </trans-unit>
4174 <trans-unit id="ac0fa1039f09ec0d917303658c5bb1ee813a4225">
4175 <source>Long (&gt; 10 min)</source>
4176 <target>Long (&gt; 10 min)</target>
4177 <context-group name="null">
4178 <context context-type="linenumber">1</context>
4179 </context-group>
4180 </trans-unit>
4181 <trans-unit id="f24d368d6be0fee70fb4503d2ad37a612e1b0889">
4182 <source>Medium (4-10 min)</source>
4183 <target>Middelmatig (4-10 min)</target>
4184 <context-group name="null">
4185 <context context-type="linenumber">1</context>
4186 </context-group>
4187 </trans-unit>
4188 <trans-unit id="ed073fec00d699b7a97bb65b4f3a722b203c5bca">
4189 <source>Relevance</source>
4190 <target>Relevantie</target>
4191 <context-group name="null">
4192 <context context-type="linenumber">1</context>
4193 </context-group>
4194 </trans-unit>
4195 <trans-unit id="1aee80ab35aa99508802cdec6306e110b2feaf9e">
4196 <source>Publish date</source>
4197 <target>Publicatiedatum</target>
4198 <context-group name="null">
4199 <context context-type="linenumber">1</context>
4200 </context-group>
4201 </trans-unit>
4202 <trans-unit id="b7641aed03492978b4ec6843b1e53f30464294d9">
4203 <source>Views</source>
4204 <target>Weergaven</target>
4205 <context-group name="null">
4206 <context context-type="linenumber">1</context>
4207 </context-group>
4208 </trans-unit>
4209 <trans-unit id="7e892ba15f2c6c17e83510e273b3e10fc32ea016">
4210 <source>Search</source>
4211 <target>Zoeken</target>
4212 <context-group name="null">
4213 <context context-type="linenumber">1</context>
4214 </context-group>
4215 </trans-unit>
4216 <trans-unit id="b67c8e57904c67c4566610363b7f82c748d04323">
4217 <source>Instance name is required.</source>
4218 <target>Instantienaam is vereist.</target>
4219 <context-group name="null">
4220 <context context-type="linenumber">1</context>
4221 </context-group>
4222 </trans-unit>
4223 <trans-unit id="10a248adb1ee12830355a04ac3cde2bad2d41d7d">
4224 <source>Short description should not be longer than 250 characters.</source>
4225 <target>Korte beschrijvingen moeten niet langer zijn dan 250 karakters.</target>
4226 <context-group name="null">
4227 <context context-type="linenumber">1</context>
4228 </context-group>
4229 </trans-unit>
4230 <trans-unit id="356e63270712273da168072ec0fc78a969919bf1">
4231 <source>Twitter username is required.</source>
4232 <target>Twitter gebruikersnaam is vereist.</target>
4233 <context-group name="null">
4234 <context context-type="linenumber">1</context>
4235 </context-group>
4236 </trans-unit>
4237 <trans-unit id="dbb2ef02020afc05e146855f2e1dd7c9522d49b6">
4238 <source>Previews cache size is required.</source>
4239 <target>Cachegrootte van voorvertoning is vereist.</target>
4240 <context-group name="null">
4241 <context context-type="linenumber">1</context>
4242 </context-group>
4243 </trans-unit>
4244 <trans-unit id="97836c6e698185b4ce357de9d4b2ab3e838f2459">
4245 <source>Previews cache size must be greater than 1.</source>
4246 <target>Cachegrootte van voorvertoning moet groter zijn dan 1.</target>
4247 <context-group name="null">
4248 <context context-type="linenumber">1</context>
4249 </context-group>
4250 </trans-unit>
4251 <trans-unit id="e7393dc4a4aa12d005582eb9e1ddc7e5ca5bebd3">
4252 <source>Previews cache size must be a number.</source>
4253 <target>Cachegrootte van voorvertoning moet een nummer zijn.</target>
4254 <context-group name="null">
4255 <context context-type="linenumber">1</context>
4256 </context-group>
4257 </trans-unit>
4258 <trans-unit id="545f5dea553b2d7c4a65920ccdcb1e9dbdc7f4d8">
4259 <source>Captions cache size is required.</source>
4260 <target>Cachegrootte van ondertiteling is vereist.</target>
4261 <context-group name="null">
4262 <context context-type="linenumber">1</context>
4263 </context-group>
4264 </trans-unit>
4265 <trans-unit id="a8d7131c0ca1eefe7b058e6081236ca1be364e2c">
4266 <source>Captions cache size must be greater than 1.</source>
4267 <target>Cachegrootte van ondertiteling moet groter zijn dan 1.</target>
4268 <context-group name="null">
4269 <context context-type="linenumber">1</context>
4270 </context-group>
4271 </trans-unit>
4272 <trans-unit id="c3decd47b03cf542df091c1a2fb25b756e59074e">
4273 <source>Captions cache size must be a number.</source>
4274 <target>Cachegrootte van ondertiteling moet een nummer zijn.</target>
4275 <context-group name="null">
4276 <context context-type="linenumber">1</context>
4277 </context-group>
4278 </trans-unit>
4279 <trans-unit id="2cdd5a8c604ef16c2f9a17ed81d73f4f9509e828">
4280 <source>Signup limit is required.</source>
4281 <target>Inschrijflimiet is vereist.</target>
4282 <context-group name="null">
4283 <context context-type="linenumber">1</context>
4284 </context-group>
4285 </trans-unit>
4286 <trans-unit id="0ca9f7ec55c9896add6e82d2b52e9217e1140cf7">
4287 <source>Signup limit must be greater than 1.</source>
4288 <target>Inschrijflimiet moet groter zijn dan 1.</target>
4289 <context-group name="null">
4290 <context context-type="linenumber">1</context>
4291 </context-group>
4292 </trans-unit>
4293 <trans-unit id="58c2f66ba74f1400914031ef4ed635938e9e8ced">
4294 <source>Signup limit must be a number.</source>
4295 <target>Inschrijflimiet moet een nummer zijn.</target>
4296 <context-group name="null">
4297 <context context-type="linenumber">1</context>
4298 </context-group>
4299 </trans-unit>
4300 <trans-unit id="1245841647f9b42d3e7554903c1c50bdd80ab021">
4301 <source>Admin email is required.</source>
4302 <target>Administrator e-mail is vereist.</target>
4303 <context-group name="null">
4304 <context context-type="linenumber">1</context>
4305 </context-group>
4306 </trans-unit>
4307 <trans-unit id="3fd2feb77dfe57fe82573e3cdf996105e2fafc66">
4308 <source>Admin email must be valid.</source>
4309 <target>Administrator e-mail moet valide zijn.</target>
4310 <context-group name="null">
4311 <context context-type="linenumber">1</context>
4312 </context-group>
4313 </trans-unit>
4314 <trans-unit id="f15f2e02b1f6a96553e98ea4a969045d17ec1400">
4315 <source>Transcoding threads is required.</source>
4316 <target>Transcoding threads zijn vereist.</target>
4317 <context-group name="null">
4318 <context context-type="linenumber">1</context>
4319 </context-group>
4320 </trans-unit>
4321 <trans-unit id="4166cc066b963a23829b48a09e394f73b453fabd">
4322 <source>Transcoding threads must be greater or equal to 0.</source>
4323 <target>Transcoding threads moeten groter of gelijk zijn aan 0.</target>
4324 <context-group name="null">
4325 <context context-type="linenumber">1</context>
4326 </context-group>
4327 </trans-unit>
4328 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4329 <source>Email is required.</source>
4330 <target>E-mail is vereist.</target>
4331 <context-group name="null">
4332 <context context-type="linenumber">1</context>
4333 </context-group>
4334 </trans-unit>
4335 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4336 <source>Email must be valid.</source>
4337 <target>E-mail moet valide zijn.</target>
4338 <context-group name="null">
4339 <context context-type="linenumber">1</context>
4340 </context-group>
4341 </trans-unit>
4342 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
4343 <source>Username is required.</source>
4344 <target>Gebruikersnaam is vereist.</target>
4345 <context-group name="null">
4346 <context context-type="linenumber">1</context>
4347 </context-group>
4348 </trans-unit>
4349 <trans-unit id="4eb39d69b74d7a56652ec84fa6826994ee26c0e5">
4350 <source>Password is required.</source>
4351 <target>Wachtwoord is vereist.</target>
4352 <context-group name="null">
4353 <context context-type="linenumber">1</context>
4354 </context-group>
4355 </trans-unit>
4356 <trans-unit id="c90872a06666a51c2957c4b29724e68df5c67154">
4357 <source>Confirmation of the password is required.</source>
4358 <target>Bevestiging van het wachtwoord is vereist.</target>
4359 <context-group name="null">
4360 <context context-type="linenumber">1</context>
4361 </context-group>
4362 </trans-unit>
4363 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
4364 <source>Password must be at least 6 characters long.</source>
4365 <target>Wachtwoord moet minstens 6 karakters lang zijn.</target>
4366 <context-group name="null">
4367 <context context-type="linenumber">1</context>
4368 </context-group>
4369 </trans-unit>
4370 <trans-unit id="0a154031f3e66985af96d5f903441cf84f0dc75e">
4371 <source>Password cannot be more than 255 characters long.</source>
4372 <target>Wachtwoord kan niet langer zijn dan 255 karakters.</target>
4373 <context-group name="null">
4374 <context context-type="linenumber">1</context>
4375 </context-group>
4376 </trans-unit>
4377 <trans-unit id="2db8f1f93a5485c32267762a3bf4da499832e732">
4378 <source>The new password and the confirmed password do not correspond.</source>
4379 <target>Het nieuwe wachtwoord en het bevestigde wachtwoord zijn niet hetzelfde.</target>
4380 <context-group name="null">
4381 <context context-type="linenumber">1</context>
4382 </context-group>
4383 </trans-unit>
4384 <trans-unit id="abede840116d58f04a55d99a6cbd68da8a3e1bbf">
4385 <source>Video quota is required.</source>
4386 <target>Videoquotum is vereist.</target>
4387 <context-group name="null">
4388 <context context-type="linenumber">1</context>
4389 </context-group>
4390 </trans-unit>
4391 <trans-unit id="93a6dc1d3aa0d3201c86ef1ec8adf5cf0ada3c80">
4392 <source>Quota must be greater than -1.</source>
4393 <target>Quota moet groter zijn dan -1</target>
4394 <context-group name="null">
4395 <context context-type="linenumber">1</context>
4396 </context-group>
4397 </trans-unit>
4398 <trans-unit id="7e58d1fb4e86af94f5199660ef349d55811888bb">
4399 <source>Daily upload limit is required.</source>
4400 <target>Dagelijks uploadlimiet is vereist.</target>
4401 <context-group name="null">
4402 <context context-type="linenumber">1</context>
4403 </context-group>
4404 </trans-unit>
4405 <trans-unit id="e283cbc4469959ea664f9d545f15278e089a6f1e">
4406 <source>Daily upload limit must be greater than -1.</source>
4407 <target>Dagelijks uploadlimiet moet groter zijn dan -1.</target>
4408 <context-group name="null">
4409 <context context-type="linenumber">1</context>
4410 </context-group>
4411 </trans-unit>
4412 <trans-unit id="545e77fd5d9526228a2133109447c23225ed9c85">
4413 <source>User role is required.</source>
4414 <target>Gebruikersrol is vereist.</target>
4415 <context-group name="null">
4416 <context context-type="linenumber">1</context>
4417 </context-group>
4418 </trans-unit>
1321 <trans-unit id="1c417b7aef730d6ef5d62fa8a0a7e25e3a2393e4"> 4419 <trans-unit id="1c417b7aef730d6ef5d62fa8a0a7e25e3a2393e4">
1322 <source>Display name is required.</source> 4420 <source>Display name is required.</source>
1323 <target>Een weergavenaam is verplicht</target> 4421 <target>Een weergavenaam is verplicht.</target>
4422 <context-group name="null">
4423 <context context-type="linenumber">1</context>
4424 </context-group>
4425 </trans-unit>
4426 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
4427 <source>Description must be at least 3 characters long.</source>
4428 <target>Beschrijvingen moeten minstens 3 karakters lang zijn.</target>
4429 <context-group name="null">
4430 <context context-type="linenumber">1</context>
4431 </context-group>
4432 </trans-unit>
4433 <trans-unit id="a4179e366d4aa335f1ddd0a13e9109c71a9338d0">
4434 <source>Description cannot be more than 1000 characters long.</source>
4435 <target>Beschrijvingen mogen niet langer dan 1000 karakters zijn.</target>
4436 <context-group name="null">
4437 <context context-type="linenumber">1</context>
4438 </context-group>
4439 </trans-unit>
4440 <trans-unit id="4a3ebc6ddb6b6677aed7b04eb503f9ddd0cfe561">
4441 <source>You must to agree with the instance terms in order to registering on it.</source>
4442 <target>Je moet akkoord gaan met de instantie's termijnen om erop te registreren.</target>
4443 <context-group name="null">
4444 <context context-type="linenumber">1</context>
4445 </context-group>
4446 </trans-unit>
4447 <trans-unit id="6d2c3ebffd49b8933200a6d4e5b74712be49bf00">
4448 <source>Ban reason must be at least 3 characters long.</source>
4449 <target>Verbanningsreden moet minstens 3 karakters zijn.</target>
4450 <context-group name="null">
4451 <context context-type="linenumber">1</context>
4452 </context-group>
4453 </trans-unit>
4454 <trans-unit id="be32ff1dd6e464c5c085dd7d128316f476d2e0fd">
4455 <source>Ban reason cannot be more than 250 characters long.</source>
4456 <target>Verbanningsreden kan niet langer dan 250 tekens zijn.</target>
4457 <context-group name="null">
4458 <context context-type="linenumber">1</context>
4459 </context-group>
4460 </trans-unit>
4461 <trans-unit id="b3cf1889d2fdd6b15e697c270c9b80772fe2cae6">
4462 <source>Report reason is required.</source>
4463 <target>Rapportagereden is vereist.</target>
4464 <context-group name="null">
4465 <context context-type="linenumber">1</context>
4466 </context-group>
4467 </trans-unit>
4468 <trans-unit id="993f9f5703d449a1d467243db75253d288a2947e">
4469 <source>Report reason must be at least 2 characters long.</source>
4470 <target>Rapportagereden moet minstens 2 tekens zijn.</target>
4471 <context-group name="null">
4472 <context context-type="linenumber">1</context>
4473 </context-group>
4474 </trans-unit>
4475 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
4476 <source>Moderation comment is required.</source>
4477 <target>Beheersreactie is vereist.</target>
4478 <context-group name="null">
4479 <context context-type="linenumber">1</context>
4480 </context-group>
4481 </trans-unit>
4482 <trans-unit id="82e31d0837eaa69a4364e7434d253ce138b3c5c2">
4483 <source>Moderation comment must be at least 2 characters long.</source>
4484 <target>Beheersreactie moet minstens 2 karakters zijn.</target>
4485 <context-group name="null">
4486 <context context-type="linenumber">1</context>
4487 </context-group>
4488 </trans-unit>
4489 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
4490 <source>The channel is required.</source>
4491 <target>Het kanaal is vereist.</target>
4492 <context-group name="null">
4493 <context context-type="linenumber">1</context>
4494 </context-group>
4495 </trans-unit>
4496 <trans-unit id="0776b05d442a0a16f083a5eefa52a166b9d514ca">
4497 <source>Blacklist reason must be at least 2 characters long.</source>
4498 <target>Zwartelijstreden moet minstens 2 karakters zijn.</target>
4499 <context-group name="null">
4500 <context context-type="linenumber">1</context>
4501 </context-group>
4502 </trans-unit>
4503 <trans-unit id="5009443905b0b152915247799492bf5e164e7626">
4504 <source>Blacklist reason cannot be more than 300 characters long.</source>
4505 <target>Zwartelijstreden kan niet langer dan 300 karakters zijn.</target>
4506 <context-group name="null">
4507 <context context-type="linenumber">1</context>
4508 </context-group>
4509 </trans-unit>
4510 <trans-unit id="c9eadf8830b3bc09bd444d739af86414eed9bd9e">
4511 <source>Video caption language is required.</source>
4512 <target>Video ondertitelingstaal is vereist.</target>
4513 <context-group name="null">
4514 <context context-type="linenumber">1</context>
4515 </context-group>
4516 </trans-unit>
4517 <trans-unit id="82083ae96724851ff37e1c7e4e9f907c25677963">
4518 <source>Video caption file is required.</source>
4519 <target>Video ondertitelingsbestand is vereist.</target>
4520 <context-group name="null">
4521 <context context-type="linenumber">1</context>
4522 </context-group>
4523 </trans-unit>
4524 <trans-unit id="bd7fc070c728dc6dbf3959d49fe5bb27ce15d294">
4525 <source>The username is required.</source>
4526 <target>De gebruikersnaam is vereist.</target>
4527 <context-group name="null">
4528 <context context-type="linenumber">1</context>
4529 </context-group>
4530 </trans-unit>
4531 <trans-unit id="c8465c3773699dd075e0147e264d2e232f605803">
4532 <source>You can only transfer ownership to a local account</source>
4533 <target>Je kan alleen je eigendom transporteren naar een lokaal account</target>
4534 <context-group name="null">
4535 <context context-type="linenumber">1</context>
4536 </context-group>
4537 </trans-unit>
4538 <trans-unit id="541087322c34e8b26954fd67ff4fc80d1a6c1b33">
4539 <source>Name is required.</source>
4540 <target>Naam is vereist.</target>
4541 <context-group name="null">
4542 <context context-type="linenumber">1</context>
4543 </context-group>
4544 </trans-unit>
4545 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
4546 <source>Support text must be at least 3 characters long.</source>
4547 <target>Supporttekst moet minstens 3 karakters zijn.</target>
4548 <context-group name="null">
4549 <context context-type="linenumber">1</context>
4550 </context-group>
4551 </trans-unit>
4552 <trans-unit id="15ec53d9ee65cb930c5f5d10ae2e8dd3fd44fc85">
4553 <source>Support text cannot be more than 1000 characters long.</source>
4554 <target>Supporttekst mag niet meer zijn dan 1000 karakters.</target>
4555 <context-group name="null">
4556 <context context-type="linenumber">1</context>
4557 </context-group>
4558 </trans-unit>
4559 <trans-unit id="6ca60e0f6dfbc0073b0514bce7d273150b0b9e79">
4560 <source>Comment is required.</source>
4561 <target>Reactie is vereist.</target>
4562 <context-group name="null">
4563 <context context-type="linenumber">1</context>
4564 </context-group>
4565 </trans-unit>
4566 <trans-unit id="f5a94cae76685e72f33541b977efdd7845cb0ed6">
4567 <source>Comment must be at least 2 characters long.</source>
4568 <target>Reactie moet minstens 2 karakters zijn.</target>
4569 <context-group name="null">
4570 <context context-type="linenumber">1</context>
4571 </context-group>
4572 </trans-unit>
4573 <trans-unit id="7c194080446ee6901fd17a8b8648534ffe98b123">
4574 <source>Comment cannot be more than 3000 characters long.</source>
4575 <target>Reactie kan niet meer dan 3000 karakters zijn.</target>
4576 <context-group name="null">
4577 <context context-type="linenumber">1</context>
4578 </context-group>
4579 </trans-unit>
4580 <trans-unit id="cdc51eaeab88683610a28af8645cf91d136b39e1">
4581 <source>Video name is required.</source>
4582 <target>Videonaam is vereist.</target>
4583 <context-group name="null">
4584 <context context-type="linenumber">1</context>
4585 </context-group>
4586 </trans-unit>
4587 <trans-unit id="c27cc734f76efd221663921dd0898ea7c8bcbb5c">
4588 <source>Video name must be at least 3 characters long.</source>
4589 <target>Videonaam moet minstens 3 karakters zijn.</target>
4590 <context-group name="null">
4591 <context context-type="linenumber">1</context>
4592 </context-group>
4593 </trans-unit>
4594 <trans-unit id="0320d0f7f8eec2341e27ca53d7875217a3d99695">
4595 <source>Video name cannot be more than 120 characters long.</source>
4596 <target>Videonaam kan niet meer dan 120 karakters zijn.</target>
4597 <context-group name="null">
4598 <context context-type="linenumber">1</context>
4599 </context-group>
4600 </trans-unit>
4601 <trans-unit id="a627c58cf1849d7d838696e7f36c1bae1a8b31a4">
4602 <source>Video privacy is required.</source>
4603 <target>Videoprivacy is vereist.</target>
4604 <context-group name="null">
4605 <context context-type="linenumber">1</context>
4606 </context-group>
4607 </trans-unit>
4608 <trans-unit id="97afb789c1ab09074495d49aaadb92a1c3e71a16">
4609 <source>Video channel is required.</source>
4610 <target>Videokanaal is vereist.</target>
4611 <context-group name="null">
4612 <context context-type="linenumber">1</context>
4613 </context-group>
4614 </trans-unit>
4615 <trans-unit id="af5e2d5f3ac817c735fb7ff9ca16322789f66fef">
4616 <source>Video description must be at least 3 characters long.</source>
4617 <target>Videobeschrijving moet minstens 3 karakters zijn.</target>
4618 <context-group name="null">
4619 <context context-type="linenumber">1</context>
4620 </context-group>
4621 </trans-unit>
4622 <trans-unit id="ce28a9403c2d7e5da2e59af27118f8b6d109e906">
4623 <source>Video description cannot be more than 10000 characters long.</source>
4624 <target>Videobeschrijving kan niet meer dan 10000 karakters zijn.</target>
4625 <context-group name="null">
4626 <context context-type="linenumber">1</context>
4627 </context-group>
4628 </trans-unit>
4629 <trans-unit id="f1cffdc2e156716cd9880201d65ba457d11464f8">
4630 <source>A tag should be more than 2 characters long.</source>
4631 <target>Een tag moet minstens 2 karakters zijn.</target>
4632 <context-group name="null">
4633 <context context-type="linenumber">1</context>
4634 </context-group>
4635 </trans-unit>
4636 <trans-unit id="34a0811f9a2a7366cc9efcdad52ea59b105326ea">
4637 <source>A tag should be less than 30 characters long.</source>
4638 <target>Een tag moet minder dan 30 karakters zijn.</target>
4639 <context-group name="null">
4640 <context context-type="linenumber">1</context>
4641 </context-group>
4642 </trans-unit>
4643 <trans-unit id="665092574f9af9fec262f8349b67b14192391ae6">
4644 <source>Video support must be at least 3 characters long.</source>
4645 <target>Videosupport moet minstens 3 karakters zijn.</target>
4646 <context-group name="null">
4647 <context context-type="linenumber">1</context>
4648 </context-group>
4649 </trans-unit>
4650 <trans-unit id="f17de746af56840511cae11559539b6d8b6955ad">
4651 <source>Video support cannot be more than 1000 characters long.</source>
4652 <target>Videosupport kan niet meer dan 1000 karakters zijn.</target>
4653 <context-group name="null">
4654 <context context-type="linenumber">1</context>
4655 </context-group>
4656 </trans-unit>
4657 <trans-unit id="453413bf387dea681958871319bab489dd5e6ec0">
4658 <source>A date is required to schedule video update.</source>
4659 <target>Een datum is vereist om videoupdates in te roosteren.</target>
4660 <context-group name="null">
4661 <context context-type="linenumber">1</context>
4662 </context-group>
4663 </trans-unit>
4664 <trans-unit id="3b7ed22d0730d03b38c254332829d855ee7256c4">
4665 <source>This file is too large.</source>
4666 <target>Dit bestand is te groot.</target>
4667 <context-group name="null">
4668 <context context-type="linenumber">1</context>
4669 </context-group>
4670 </trans-unit>
4671 <trans-unit id="0bf41abaa85526711f7952b4600e4044bc7f04a4">
4672 <source>All unsaved data will be lost, are you sure you want to leave this page?</source>
4673 <target>Alle onopgeslagen data zal verloren worden, weet je zeker dat je deze pagina wil verlaten?</target>
4674 <context-group name="null">
4675 <context context-type="linenumber">1</context>
4676 </context-group>
4677 </trans-unit>
4678 <trans-unit id="a8059e31694578c1b0344a76a345357dd60e8f01">
4679 <source>Warning</source>
4680 <target>Waarschuwing</target>
4681 <context-group name="null">
4682 <context context-type="linenumber">1</context>
4683 </context-group>
4684 </trans-unit>
4685 <trans-unit id="8339364b054610983b7f2334bb807fff7613bddf">
4686 <source>Sunday</source>
4687 <target>Zondag</target>
4688 <context-group name="null">
4689 <context context-type="linenumber">1</context>
4690 </context-group>
4691 </trans-unit>
4692 <trans-unit id="a43c57a7cbebf57eb33a2eae5e994c91d9887596">
4693 <source>Monday</source>
4694 <target>Maandag</target>
4695 <context-group name="null">
4696 <context context-type="linenumber">1</context>
4697 </context-group>
4698 </trans-unit>
4699 <trans-unit id="48a2a35957ce394eb2c59ae35c99642360af70ee">
4700 <source>Tuesday</source>
4701 <target>Dinsdag</target>
4702 <context-group name="null">
4703 <context context-type="linenumber">1</context>
4704 </context-group>
4705 </trans-unit>
4706 <trans-unit id="b0af441f9ba8b82952b9ec10fb8c62e8fec67df9">
4707 <source>Wednesday</source>
4708 <target>Woensdag</target>
4709 <context-group name="null">
4710 <context context-type="linenumber">1</context>
4711 </context-group>
4712 </trans-unit>
4713 <trans-unit id="55c583b99c809818ec27df065ccf05357a6ac10b">
4714 <source>Thursday</source>
4715 <target>Donderdag</target>
4716 <context-group name="null">
4717 <context context-type="linenumber">1</context>
4718 </context-group>
4719 </trans-unit>
4720 <trans-unit id="e91b54925dc5f490753f60f53ef6f8b4609e6215">
4721 <source>Friday</source>
4722 <target>Vrijdag</target>
4723 <context-group name="null">
4724 <context context-type="linenumber">1</context>
4725 </context-group>
4726 </trans-unit>
4727 <trans-unit id="c0d2dd391a3eca8e841a5d0e035cd268280eb68e">
4728 <source>Saturday</source>
4729 <target>Zaterdag</target>
4730 <context-group name="null">
4731 <context context-type="linenumber">1</context>
4732 </context-group>
4733 </trans-unit>
4734 <trans-unit id="6549890cd0d6b59fb0e1aa383b00483a68a55eef">
4735 <source>Sun</source>
4736 <target>Zon</target>
4737 <context-group name="null">
4738 <context context-type="linenumber">1</context>
4739 </context-group>
4740 </trans-unit>
4741 <trans-unit id="3382aa5d7f520e197fb59a4995fe1beffca2d0ff">
4742 <source>Mon</source>
4743 <target>Maa</target>
4744 <context-group name="null">
4745 <context context-type="linenumber">1</context>
4746 </context-group>
4747 </trans-unit>
4748 <trans-unit id="f883ec926274974df0fc46c037cbffd6a863ebc9">
4749 <source>Tue</source>
4750 <target>Din</target>
4751 <context-group name="null">
4752 <context context-type="linenumber">1</context>
4753 </context-group>
4754 </trans-unit>
4755 <trans-unit id="242b4f4b5651e24f9a9007ef153a57981e4b989d">
4756 <source>Wed</source>
4757 <target>Woe</target>
4758 <context-group name="null">
4759 <context context-type="linenumber">1</context>
4760 </context-group>
4761 </trans-unit>
4762 <trans-unit id="5a2c39d56b8f00a6a4670a63b53caacbda953be6">
4763 <source>Thu</source>
4764 <target>Don</target>
4765 <context-group name="null">
4766 <context context-type="linenumber">1</context>
4767 </context-group>
4768 </trans-unit>
4769 <trans-unit id="4cdf23d523a0e52e0dec9cd650ffd9bd6952792c">
4770 <source>Fri</source>
4771 <target>Vri</target>
4772 <context-group name="null">
4773 <context context-type="linenumber">1</context>
4774 </context-group>
4775 </trans-unit>
4776 <trans-unit id="1283d165a942d7f4c469ba34f99dbb9e927d0261">
4777 <source>Sat</source>
4778 <target>Zat</target>
4779 <context-group name="null">
4780 <context context-type="linenumber">1</context>
4781 </context-group>
4782 </trans-unit>
4783 <trans-unit id="2fba8448ff13105c57665a9a6ffcfe9615d855dd">
4784 <source>Su</source>
4785 <target>Zon</target>
4786 <context-group name="null">
4787 <context context-type="linenumber">1</context>
4788 </context-group>
4789 </trans-unit>
4790 <trans-unit id="388144af7ac7651d2615b9be0e84f43ae71d9fb3">
4791 <source>Mo</source>
4792 <target>Ma</target>
4793 <context-group name="null">
4794 <context context-type="linenumber">1</context>
4795 </context-group>
4796 </trans-unit>
4797 <trans-unit id="d96313e42b5f0751ce2676a31d309b4d322ab462">
4798 <source>Tu</source>
4799 <target>Di</target>
4800 <context-group name="null">
4801 <context context-type="linenumber">1</context>
4802 </context-group>
4803 </trans-unit>
4804 <trans-unit id="06cc3d39f78c0615b707cef39cd4875599611fef">
4805 <source>We</source>
4806 <target>Wo</target>
4807 <context-group name="null">
4808 <context context-type="linenumber">1</context>
4809 </context-group>
4810 </trans-unit>
4811 <trans-unit id="790894436cca9d675d59be9a8aafd58acccde2cd">
4812 <source>Th</source>
4813 <target>Do</target>
4814 <context-group name="null">
4815 <context context-type="linenumber">1</context>
4816 </context-group>
4817 </trans-unit>
4818 <trans-unit id="42dfe37169f8471367c31489155229bbe1747ea5">
4819 <source>Fr</source>
4820 <target>Vr</target>
4821 <context-group name="null">
4822 <context context-type="linenumber">1</context>
4823 </context-group>
4824 </trans-unit>
4825 <trans-unit id="1b64ea3e04ceeb512e8974eb0019dee4f211c7a0">
4826 <source>Sa</source>
4827 <target>Za</target>
4828 <context-group name="null">
4829 <context context-type="linenumber">1</context>
4830 </context-group>
4831 </trans-unit>
4832 <trans-unit id="e7815f1c4a6d3cc157a16407a48865023cc35ec0">
4833 <source>January</source>
4834 <target>Januari</target>
4835 <context-group name="null">
4836 <context context-type="linenumber">1</context>
4837 </context-group>
4838 </trans-unit>
4839 <trans-unit id="0393a96b58df82af39a2ec83deec624749e42036">
4840 <source>February</source>
4841 <target>Februari</target>
4842 <context-group name="null">
4843 <context context-type="linenumber">1</context>
4844 </context-group>
4845 </trans-unit>
4846 <trans-unit id="ea41ee3743ec5bdbbf863ab793bbdd6e6d9af96e">
4847 <source>March</source>
4848 <target>Maart</target>
4849 <context-group name="null">
4850 <context context-type="linenumber">1</context>
4851 </context-group>
4852 </trans-unit>
4853 <trans-unit id="b87ee784d9e93b5557aca9bdc9464dbd4328920a">
4854 <source>April</source>
4855 <target>April</target>
4856 <context-group name="null">
4857 <context context-type="linenumber">1</context>
4858 </context-group>
4859 </trans-unit>
4860 <trans-unit id="862da1034ac2707cc44123ed963b2f42109b6b3e">
4861 <source>May</source>
4862 <target>Mei</target>
4863 <context-group name="null">
4864 <context context-type="linenumber">1</context>
4865 </context-group>
4866 </trans-unit>
4867 <trans-unit id="2f234249d4c3c39e27c0f05d4a6b73a7959caeb2">
4868 <source>June</source>
4869 <target>Juni</target>
4870 <context-group name="null">
4871 <context context-type="linenumber">1</context>
4872 </context-group>
4873 </trans-unit>
4874 <trans-unit id="11447f95e83c8de675ab6c492150f88e4d9bd15e">
4875 <source>July</source>
4876 <target>July</target>
4877 <context-group name="null">
4878 <context context-type="linenumber">1</context>
4879 </context-group>
4880 </trans-unit>
4881 <trans-unit id="ddd9a3d59a8db4e822e54e9473c05b571aca9829">
4882 <source>August</source>
4883 <target>Augustus</target>
4884 <context-group name="null">
4885 <context context-type="linenumber">1</context>
4886 </context-group>
4887 </trans-unit>
4888 <trans-unit id="e21dc41f9b3fdaf35ab6b2d9e2e5e8a926fb1938">
4889 <source>September</source>
4890 <target>September</target>
4891 <context-group name="null">
4892 <context context-type="linenumber">1</context>
4893 </context-group>
4894 </trans-unit>
4895 <trans-unit id="71f49c502d13e22079a958a5532afa28dbe98b3b">
4896 <source>October</source>
4897 <target>Oktober</target>
4898 <context-group name="null">
4899 <context context-type="linenumber">1</context>
4900 </context-group>
4901 </trans-unit>
4902 <trans-unit id="64b5ce921faa5e3d277d6d528ddcfc8c2bfe9f52">
4903 <source>November</source>
4904 <target>November</target>
4905 <context-group name="null">
4906 <context context-type="linenumber">1</context>
4907 </context-group>
4908 </trans-unit>
4909 <trans-unit id="2006e2aabb31714ebc684dc382539649f690ed5c">
4910 <source>December</source>
4911 <target>December</target>
4912 <context-group name="null">
4913 <context context-type="linenumber">1</context>
4914 </context-group>
4915 </trans-unit>
4916 <trans-unit id="8270e687cfb5624b3f6fbb7991a2e916c96464b7">
4917 <source>Jan</source>
4918 <target>Jan</target>
4919 <context-group name="null">
4920 <context context-type="linenumber">1</context>
4921 </context-group>
4922 </trans-unit>
4923 <trans-unit id="23544170afbb981dd52750b641576841cf5dcf60">
4924 <source>Feb</source>
4925 <target>Feb</target>
4926 <context-group name="null">
4927 <context context-type="linenumber">1</context>
4928 </context-group>
4929 </trans-unit>
4930 <trans-unit id="1f14355742459b7d6a0126a1564e1c18f39f86e7">
4931 <source>Mar</source>
4932 <target>Mar</target>
4933 <context-group name="null">
4934 <context context-type="linenumber">1</context>
4935 </context-group>
4936 </trans-unit>
4937 <trans-unit id="964a5f032bc846d32806a4838580a4f81cf14463">
4938 <source>Apr</source>
4939 <target>Apr</target>
4940 <context-group name="null">
4941 <context context-type="linenumber">1</context>
4942 </context-group>
4943 </trans-unit>
4944 <trans-unit id="8f7274f606f71d9290ed01c5683092d701632d7f">
4945 <source>Jun</source>
4946 <target>Jun</target>
4947 <context-group name="null">
4948 <context context-type="linenumber">1</context>
4949 </context-group>
4950 </trans-unit>
4951 <trans-unit id="7c3d8318d6d8d9920ae0a80350616732c33a3211">
4952 <source>Jul</source>
4953 <target>Jul</target>
4954 <context-group name="null">
4955 <context context-type="linenumber">1</context>
4956 </context-group>
4957 </trans-unit>
4958 <trans-unit id="be1335ffd1c606321e2c020b638dd3c84b434212">
4959 <source>Aug</source>
4960 <target>Aug</target>
4961 <context-group name="null">
4962 <context context-type="linenumber">1</context>
4963 </context-group>
4964 </trans-unit>
4965 <trans-unit id="4f739d03be1c936c58978739c317d91566348204">
4966 <source>Sep</source>
4967 <target>Sep</target>
4968 <context-group name="null">
4969 <context context-type="linenumber">1</context>
4970 </context-group>
4971 </trans-unit>
4972 <trans-unit id="6607cacb987a588530a13de7018d959240d19153">
4973 <source>Oct</source>
4974 <target>Oct</target>
4975 <context-group name="null">
4976 <context context-type="linenumber">1</context>
4977 </context-group>
4978 </trans-unit>
4979 <trans-unit id="e597400ded12a366855615e18fcc8f9ac05b72e0">
4980 <source>Nov</source>
4981 <target>Nov</target>
4982 <context-group name="null">
4983 <context context-type="linenumber">1</context>
4984 </context-group>
4985 </trans-unit>
4986 <trans-unit id="adf2dfa2a9cb490d6a4a74510b7b0846b62d429e">
4987 <source>Dec</source>
4988 <target>Dec</target>
4989 <context-group name="null">
4990 <context context-type="linenumber">1</context>
4991 </context-group>
4992 </trans-unit>
4993 <trans-unit id="99ee4faa69cd2ea8e3678c1f557c0ff1f05aae46">
4994 <source>Clear</source>
4995 <target>Wissen</target>
4996 <context-group name="null">
4997 <context context-type="linenumber">1</context>
4998 </context-group>
4999 </trans-unit>
5000 <trans-unit id="8fb519ba47ea7806beeacdcd44829d85a2aa0cc5">
5001 <source>yy-mm-dd </source>
5002 <target>jj-mm-dd</target>
5003 <context-group name="null">
5004 <context context-type="linenumber">1</context>
5005 </context-group>
5006 </trans-unit>
5007 <trans-unit id="a0fdb831d4557925dbaa4f8aff7e5035f7506411">
5008 <source>Transcode your videos in multiple resolutions</source>
5009 <target>Transcodeer je videos in meerdere resoluties</target>
5010 <context-group name="null">
5011 <context context-type="linenumber">1</context>
5012 </context-group>
5013 </trans-unit>
5014 <trans-unit id="590fc27fcbd7dd680da2bb2da644a183338f6bd1">
5015 <source>HTTP import (YouTube, Vimeo, direct URL...)</source>
5016 <target>HTTP import(Youtube, Vimeo, directe URL...)</target>
5017 <context-group name="null">
5018 <context context-type="linenumber">1</context>
5019 </context-group>
5020 </trans-unit>
5021 <trans-unit id="4e231a74ad4739e7b0606e8e66d5a656f5855a5a">
5022 <source>Torrent import</source>
5023 <target>Torrentimport</target>
5024 <context-group name="null">
5025 <context context-type="linenumber">1</context>
5026 </context-group>
5027 </trans-unit>
5028 <trans-unit id="7296e9f7cc4956b6d57c541728b0826e76d108ba">
5029 <source>~ <x id="INTERPOLATION" equiv-text="{{minutes}}"/> <x id="ICU" equiv-text="{minutes, plural, =1 {...} other {...}}"/></source>
5030 <target>~ <x id="INTERPOLATION" equiv-text="{{minutes}}"/> <x id="ICU" equiv-text="{minutes, plural, =1 {...} other {...}}"/></target>
5031 <context-group name="null">
5032 <context context-type="linenumber">1</context>
5033 </context-group>
5034 </trans-unit>
5035 <trans-unit id="cf9ddbb55b25178660e09346209aedc10108aa24">
5036 <source>{VAR_PLURAL, plural, =1 {minute} other {minutes} }</source>
5037 <target>{VAR_PLURAL, plural, =1 {minute} other {minutes} }</target>
5038 <context-group name="null">
5039 <context context-type="linenumber">1</context>
5040 </context-group>
5041 </trans-unit>
5042 <trans-unit id="10ffa5c3dbcee491d66f80d8d4dce3e119a6ec86">
5043 <source><x id="INTERPOLATION" equiv-text="{{seconds}}"/> of full HD videos</source>
5044 <target><x id="INTERPOLATION" equiv-text="{{seconds}}"/> aan full HD videos</target>
5045 <context-group name="null">
5046 <context context-type="linenumber">1</context>
5047 </context-group>
5048 </trans-unit>
5049 <trans-unit id="344ddae9f45b344e98e7b28cd5e33243982700f8">
5050 <source><x id="INTERPOLATION" equiv-text="{{seconds}}"/> of HD videos</source>
5051 <target><x id="INTERPOLATION" equiv-text="{{seconds}}"/> aan HD videos</target>
5052 <context-group name="null">
5053 <context context-type="linenumber">1</context>
5054 </context-group>
5055 </trans-unit>
5056 <trans-unit id="435c012df6dd990a1ccb7ee73dd79c488bde28b5">
5057 <source><x id="INTERPOLATION" equiv-text="{{seconds}}"/> of average quality videos</source>
5058 <target><x id="INTERPOLATION" equiv-text="{{seconds}}"/> aan gemiddelde kwaliteit videos</target>
5059 <context-group name="null">
5060 <context context-type="linenumber">1</context>
5061 </context-group>
5062 </trans-unit>
5063 <trans-unit id="0b2054a863319d2cf59867addd125b6717cae41d">
5064 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> years ago</source>
5065 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> jaar geleden</target>
5066 <context-group name="null">
5067 <context context-type="linenumber">1</context>
5068 </context-group>
5069 </trans-unit>
5070 <trans-unit id="e622d3813449fe36371ea258281059306819199d">
5071 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> months ago</source>
5072 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> maanden geleden</target>
5073 <context-group name="null">
5074 <context context-type="linenumber">1</context>
5075 </context-group>
5076 </trans-unit>
5077 <trans-unit id="2f8a5a5f7efb521d7d89dc659ff65dd13cb7b17b">
5078 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> month ago</source>
5079 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> maand geleden</target>
5080 <context-group name="null">
5081 <context context-type="linenumber">1</context>
5082 </context-group>
5083 </trans-unit>
5084 <trans-unit id="1d1a46543a29096d3c6676be2d561380a0bc94e1">
5085 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> weeks ago</source>
5086 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> weken geleden</target>
5087 <context-group name="null">
5088 <context context-type="linenumber">1</context>
5089 </context-group>
5090 </trans-unit>
5091 <trans-unit id="e1db0b98b6cdf817508195f3649c48475c32ae7e">
5092 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> week ago</source>
5093 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> week geleden</target>
5094 <context-group name="null">
5095 <context context-type="linenumber">1</context>
5096 </context-group>
5097 </trans-unit>
5098 <trans-unit id="a7654c3ece96e777527606f1c2870d6ee0b180f7">
5099 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> days ago</source>
5100 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> dagen geleden</target>
5101 <context-group name="null">
5102 <context context-type="linenumber">1</context>
5103 </context-group>
5104 </trans-unit>
5105 <trans-unit id="5b465235ae55091d32535e23dd180c407f1352d1">
5106 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> day ago</source>
5107 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> dag geleden</target>
5108 <context-group name="null">
5109 <context context-type="linenumber">1</context>
5110 </context-group>
5111 </trans-unit>
5112 <trans-unit id="dc7addf53bd6405a9c746db6dfca665c33679a84">
5113 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> hours ago</source>
5114 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> uren geleden</target>
5115 <context-group name="null">
5116 <context context-type="linenumber">1</context>
5117 </context-group>
5118 </trans-unit>
5119 <trans-unit id="d54a610250ed38efccf0e3afdd0004f6ad83ea8d">
5120 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> hour ago</source>
5121 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> uur geleden</target>
5122 <context-group name="null">
5123 <context context-type="linenumber">1</context>
5124 </context-group>
5125 </trans-unit>
5126 <trans-unit id="9704e5e3adce178c127ead05f7057d3fb827308a">
5127 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> min ago</source>
5128 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> min geleden</target>
5129 <context-group name="null">
5130 <context context-type="linenumber">1</context>
5131 </context-group>
5132 </trans-unit>
5133 <trans-unit id="7a158a7555a44ea7eff9fa4988df9aa24d262ceb">
5134 <source><x id="INTERPOLATION" equiv-text="{{interval}}"/> sec ago</source>
5135 <target><x id="INTERPOLATION" equiv-text="{{interval}}"/> sec geleden</target>
5136 <context-group name="null">
5137 <context context-type="linenumber">1</context>
5138 </context-group>
5139 </trans-unit>
5140 <trans-unit id="457f161d3ca706b8de263b0cd58e493d54e7d4c5">
5141 <source><x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>Markdown<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> compatible that supports:</source>
5142 <target><x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>Markeer<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> compatibele dat support:</target>
5143 <context-group name="null">
5144 <context context-type="linenumber">1</context>
5145 </context-group>
5146 </trans-unit>
5147 <trans-unit id="ab4426b60f13c00b61d6b714d390dc629f314980">
5148 <source>Emphasis</source>
5149 <target>Nadruk</target>
5150 <context-group name="null">
5151 <context context-type="linenumber">1</context>
5152 </context-group>
5153 </trans-unit>
5154 <trans-unit id="dc60677d5a906e69f38a5cf9da7f2eb03931bea0">
5155 <source>Links</source>
5156 <target>Links</target>
5157 <context-group name="null">
5158 <context context-type="linenumber">1</context>
5159 </context-group>
5160 </trans-unit>
5161 <trans-unit id="80220239e07f36ea8d5f10118dc52ce4b13bc15a">
5162 <source>New lines</source>
5163 <target>Nieuwe lijnen</target>
5164 <context-group name="null">
5165 <context context-type="linenumber">1</context>
5166 </context-group>
5167 </trans-unit>
5168 <trans-unit id="b15e7bec5c7833d2d9634946ccbed68967b1bee1">
5169 <source>Lists</source>
5170 <target>Lijsten</target>
5171 <context-group name="null">
5172 <context context-type="linenumber">1</context>
5173 </context-group>
5174 </trans-unit>
5175 <trans-unit id="b73f7f5060fb22a1e9ec462b1bb02493fa3ab866">
5176 <source>Images</source>
5177 <target>Afbeeldingen</target>
5178 <context-group name="null">
5179 <context context-type="linenumber">1</context>
5180 </context-group>
5181 </trans-unit>
5182 <trans-unit id="f9b4f2d8146c789cd40314f640ec4e88efbaf681">
5183 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users banned.</source>
5184 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> gebruikers verbannen.</target>
5185 <context-group name="null">
5186 <context context-type="linenumber">1</context>
5187 </context-group>
5188 </trans-unit>
5189 <trans-unit id="3ab99e62550869aebc85661fca2faf46785263dd">
5190 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> banned.</source>
5191 <target>Gebruiker <x id="INTERPOLATION" equiv-text="{{username}}"/> verbannen.</target>
5192 <context-group name="null">
5193 <context context-type="linenumber">1</context>
5194 </context-group>
5195 </trans-unit>
5196 <trans-unit id="faafee0c03ad25c8a43aa91bd5d98185b67ff734">
5197 <source>Do you really want to unban <x id="INTERPOLATION" equiv-text="{{username}}"/>?</source>
5198 <target>Weet je zeker dat je <x id="INTERPOLATION" equiv-text="{{username}}"/> wilt onverbannen?</target>
5199 <context-group name="null">
5200 <context context-type="linenumber">1</context>
5201 </context-group>
5202 </trans-unit>
5203 <trans-unit id="925ba9946b7b256a586f0fcbe3e04fa7a0dee7bd">
5204 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> unbanned.</source>
5205 <target>Gebruiker <x id="INTERPOLATION" equiv-text="{{username}}"/> onverbannen.</target>
5206 <context-group name="null">
5207 <context context-type="linenumber">1</context>
5208 </context-group>
5209 </trans-unit>
5210 <trans-unit id="ad07d34d4aadfe03c964cec02ca1d3a921e6b603">
5211 <source>If you remove this user, you will not be able to create another with the same username!</source>
5212 <target>Als je deze gebruiker verwijdert, is het niet meer mogelijk om een andere te maken met dezelfde gebruikersnaam!</target>
5213 <context-group name="null">
5214 <context context-type="linenumber">1</context>
5215 </context-group>
5216 </trans-unit>
5217 <trans-unit id="28220fae6799ab98ef6b41af449aa9680082357a">
5218 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> deleted.</source>
5219 <target>Gebruiker <x id="INTERPOLATION" equiv-text="{{username}}"/> verwijdert.</target>
5220 <context-group name="null">
5221 <context context-type="linenumber">1</context>
5222 </context-group>
5223 </trans-unit>
5224 <trans-unit id="534202c90c6dcadd2989fc72c5030d5483e26096">
5225 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> email set as verified</source>
5226 <target>Gebruiker <x id="INTERPOLATION" equiv-text="{{username}}"/> e-mail gezet als geverifieerd</target>
5227 <context-group name="null">
5228 <context context-type="linenumber">1</context>
5229 </context-group>
5230 </trans-unit>
5231 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249">
5232 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source>
5233 <target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> gedempt.</target>
5234 <context-group name="null">
5235 <context context-type="linenumber">1</context>
5236 </context-group>
5237 </trans-unit>
5238 <trans-unit id="086eda792aeb1b0d131d633b50fdd1792f5f24c6">
5239 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted.</source>
5240 <target>Instantie <x id="INTERPOLATION" equiv-text="{{host}}"/> gedempt.</target>
5241 <context-group name="null">
5242 <context context-type="linenumber">1</context>
5243 </context-group>
5244 </trans-unit>
5245 <trans-unit id="bb72d6d1219e89d182e9fd09d853d83baf8d6499">
5246 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted by the instance.</source>
5247 <target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> gedempt door de instantie.</target>
5248 <context-group name="null">
5249 <context context-type="linenumber">1</context>
5250 </context-group>
5251 </trans-unit>
5252 <trans-unit id="8686834bc4afe42c1991c6c18f0bce174a0e17a6">
5253 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by the instance.</source>
5254 <target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> niet meer gedempt door de instantie.</target>
5255 <context-group name="null">
5256 <context context-type="linenumber">1</context>
5257 </context-group>
5258 </trans-unit>
5259 <trans-unit id="35d3509161861a610b0895bf084c781e56ba2830">
5260 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted by the instance.</source>
5261 <target>Instantie <x id="INTERPOLATION" equiv-text="{{host}}"/> gedempt door de instantie.</target>
5262 <context-group name="null">
5263 <context context-type="linenumber">1</context>
5264 </context-group>
5265 </trans-unit>
5266 <trans-unit id="978aeec5613fa97e8a5336d3599cebb23ee5a90f">
5267 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by the instance.</source>
5268 <target>Instantie <x id="INTERPOLATION" equiv-text="{{host}}"/> niet meer gedempt door de instantie.</target>
5269 <context-group name="null">
5270 <context context-type="linenumber">1</context>
5271 </context-group>
5272 </trans-unit>
5273 <trans-unit id="4a09bf8724e7659fbb5ec33647529cdef7614bdc">
5274 <source>Mute this account</source>
5275 <target>Demp dit account</target>
5276 <context-group name="null">
5277 <context context-type="linenumber">1</context>
5278 </context-group>
5279 </trans-unit>
5280 <trans-unit id="d666ca3261aef72b2ddcd649d7b32af488f59952">
5281 <source>Unmute this account</source>
5282 <target>Dempt dit account niet meer</target>
5283 <context-group name="null">
5284 <context context-type="linenumber">1</context>
5285 </context-group>
5286 </trans-unit>
5287 <trans-unit id="e17218983b1de76e5a920b04e1c2ecbdb6e3e06d">
5288 <source>Mute the instance</source>
5289 <target>Demp de instantie</target>
5290 <context-group name="null">
5291 <context context-type="linenumber">1</context>
5292 </context-group>
5293 </trans-unit>
5294 <trans-unit id="a23514d8aca2f8633622dda0e86b399dc576a2b9">
5295 <source>Unmute the instance</source>
5296 <target>Demp de instantie niet meer</target>
5297 <context-group name="null">
5298 <context context-type="linenumber">1</context>
5299 </context-group>
5300 </trans-unit>
5301 <trans-unit id="4e4107055b44eee44b6954c41120de1cb4d46432">
5302 <source>Mute this account by your instance</source>
5303 <target>Demp dit account door jouw instantie</target>
5304 <context-group name="null">
5305 <context context-type="linenumber">1</context>
5306 </context-group>
5307 </trans-unit>
5308 <trans-unit id="a51c59cb5ecb7004a6a8ddd2855b5c52266ad957">
5309 <source>Unmute this account by your instance</source>
5310 <target>Demp dit account niet meer door jouw instantie</target>
5311 <context-group name="null">
5312 <context context-type="linenumber">1</context>
5313 </context-group>
5314 </trans-unit>
5315 <trans-unit id="588073e831cec240d6bb0db0b133e45dab69f178">
5316 <source>Mute the instance by your instance</source>
5317 <target>Demp de instantie door jouw instantie</target>
5318 <context-group name="null">
5319 <context context-type="linenumber">1</context>
5320 </context-group>
5321 </trans-unit>
5322 <trans-unit id="676221cdabd4805901343976988c028dbf71b20a">
5323 <source>Unmute the instance by your instance</source>
5324 <target>Demp de instantie niet meer door jouw instantie</target>
5325 <context-group name="null">
5326 <context context-type="linenumber">1</context>
5327 </context-group>
5328 </trans-unit>
5329 <trans-unit id="0c0f5bbcd2386018ec057877f9d3c5c2c9880cac">
5330 <source>Request is too large for the server. Please contact you administrator if you want to increase the limit size.</source>
5331 <target>Verzoek te groot voor de server. Alstublieft bereikt de administrator als je de limietgrote wilt vergroten.</target>
5332 <context-group name="null">
5333 <context context-type="linenumber">1</context>
5334 </context-group>
5335 </trans-unit>
5336 <trans-unit id="58546fd4d14b2d9635ce3d28c216ac68587bb25b">
5337 <source>Too many attempts, please try again after <x id="INTERPOLATION" equiv-text="{{minutesLeft}}"/> minutes.</source>
5338 <target>Te vaak geprobeerd, probeer alstublieft weer na <x id="INTERPOLATION" equiv-text="{{minutesLeft}}"/> minuten.</target>
5339 <context-group name="null">
5340 <context context-type="linenumber">1</context>
5341 </context-group>
5342 </trans-unit>
5343 <trans-unit id="ab783a52f2df9ff7a20139cab0da6d0764f3cc5d">
5344 <source>Too many attempts, please try again later.</source>
5345 <target>Te vaak geprobeerd, probeer alstublieft later.</target>
5346 <context-group name="null">
5347 <context context-type="linenumber">1</context>
5348 </context-group>
5349 </trans-unit>
5350 <trans-unit id="0f286a597f0053c3578a52e044769c204ee516fc">
5351 <source>Server error. Please retry later.</source>
5352 <target>Serverfout. Probeer later alstublieft weer.</target>
5353 <context-group name="null">
5354 <context context-type="linenumber">1</context>
5355 </context-group>
5356 </trans-unit>
5357 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
5358 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
5359 <target>Abonneer op <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
5360 <context-group name="null">
5361 <context context-type="linenumber">1</context>
5362 </context-group>
5363 </trans-unit>
5364 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5365 <source>Subscribed</source>
5366 <target>Geabonneert</target>
5367 <context-group name="null">
5368 <context context-type="linenumber">1</context>
5369 </context-group>
5370 </trans-unit>
5371 <trans-unit id="3e7735fa326fcdc9e1188b6d9ff4b4329312fc26">
5372 <source>Unsubscribed from <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
5373 <target>Ongeabonneert van <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
5374 <context-group name="null">
5375 <context context-type="linenumber">1</context>
5376 </context-group>
5377 </trans-unit>
5378 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
5379 <source>Unsubscribed</source>
5380 <target>Ongeabonneert</target>
5381 <context-group name="null">
5382 <context context-type="linenumber">1</context>
5383 </context-group>
5384 </trans-unit>
5385 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf">
5386 <source>Moderator</source>
5387 <target>Beheerder</target>
5388 <context-group name="null">
5389 <context context-type="linenumber">1</context>
5390 </context-group>
5391 </trans-unit>
5392 <trans-unit id="d4195053fd38eacf6dee1fc507296928978cc8fb">
5393 <source>Only I can see this video</source>
5394 <target>Ik kan deze video alleen zien</target>
5395 <context-group name="null">
5396 <context context-type="linenumber">1</context>
5397 </context-group>
5398 </trans-unit>
5399 <trans-unit id="17b62592e5fcabb5235bb25c4883a827ab37cf70">
5400 <source>Only people with the private link can see this video</source>
5401 <target>Alleen mensen met de privélink kunnen deze video zien</target>
5402 <context-group name="null">
5403 <context context-type="linenumber">1</context>
5404 </context-group>
5405 </trans-unit>
5406 <trans-unit id="15be15cbdc6e960f57e801f457c19165ab39632b">
5407 <source>Anyone can see this video</source>
5408 <target>Iedereen kan deze video zien</target>
5409 <context-group name="null">
5410 <context context-type="linenumber">1</context>
5411 </context-group>
5412 </trans-unit>
5413 <trans-unit id="21565881ad1dff3c98738b9535b3515cec140609">
5414 <source>Welcome! Now please check your emails to verify your account and complete signup.</source>
5415 <target>Welkom! Check alstublieft nu jouw e-mails om jouw accont te verifieren en de inschrijving te voltooien</target>
5416 <context-group name="null">
5417 <context context-type="linenumber">1</context>
5418 </context-group>
5419 </trans-unit>
5420 <trans-unit id="14200e26888a07633c0f177020dce8f3ec7311a6">
5421 <source>You are now logged in as <x id="INTERPOLATION" equiv-text="{{username}}"/>!</source>
5422 <target>Je bent nu ingelogd als <x id="INTERPOLATION" equiv-text="{{username}}"/>!</target>
5423 <context-group name="null">
5424 <context context-type="linenumber">1</context>
5425 </context-group>
5426 </trans-unit>
5427 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb">
5428 <source>Video to import updated.</source>
5429 <target>Video naar import bijgewerkt.</target>
5430 <context-group name="null">
5431 <context context-type="linenumber">1</context>
5432 </context-group>
5433 </trans-unit>
5434 <trans-unit id="0e907e5a96537e464b192f8adce79ce6487cbb1c">
5435 <source>Your video was uploaded to your account and is private.</source>
5436 <target>Jouw video is geupload naar jouw account en is privé.
5437 </target>
5438 <context-group name="null">
5439 <context context-type="linenumber">1</context>
5440 </context-group>
5441 </trans-unit>
5442 <trans-unit id="24840228f2826b66252cfcaab9820b1c7e0da264">
5443 <source>But associated data (tags, description...) will be lost, are you sure you want to leave this page?</source>
5444 <target>Maar geassocieerde data(tags, beschrijving...) zullen verloren raken, weet je zeker dat je deze pagina wilt verlaten?</target>
5445 <context-group name="null">
5446 <context context-type="linenumber">1</context>
5447 </context-group>
5448 </trans-unit>
5449 <trans-unit id="5af84926d631326e548573ebf0f6dff07845aeb4">
5450 <source>Your video is not uploaded yet, are you sure you want to leave this page?</source>
5451 <target>Jouw video is nog niet geupload, weet je zeker dat je deze pagina wilt verlaten?</target>
5452 <context-group name="null">
5453 <context context-type="linenumber">1</context>
5454 </context-group>
5455 </trans-unit>
5456 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
5457 <source>Upload cancelled</source>
5458 <target>Upload geannuleerd</target>
5459 <context-group name="null">
5460 <context context-type="linenumber">1</context>
5461 </context-group>
5462 </trans-unit>
5463 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
5464 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
5465 <target>Jouw videoquotum is overschreden met deze video (videogrootte: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, gebruikt: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quotum: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
5466 <context-group name="null">
5467 <context context-type="linenumber">1</context>
5468 </context-group>
5469 </trans-unit>
5470 <trans-unit id="c980896ac8e08e9751545db1b7ef0e93fb8a52cd">
5471 <source>Your daily video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{quotaUsedDaily}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{quotaDaily}}"/>)</source>
5472 <target>Jouw dagelijkse videoquotum is overschreden met deze video (videogrootte: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, gebruikt: <x id="INTERPOLATION_1" equiv-text="{{quotaUsedDaily}}"/>, quotum: <x id="INTERPOLATION_2" equiv-text="{{quotaDaily}}"/>)</target>
5473 <context-group name="null">
5474 <context context-type="linenumber">1</context>
5475 </context-group>
5476 </trans-unit>
5477 <trans-unit id="972fc644f847cf84e4732ec012915c4cdaf865ce">
5478 <source>Video published.</source>
5479 <target>Video gepubliceerd.</target>
5480 <context-group name="null">
5481 <context context-type="linenumber">1</context>
5482 </context-group>
5483 </trans-unit>
5484 <trans-unit id="757e9c083c8f3d578bd74f055cc337c72417e187">
5485 <source>Video updated.</source>
5486 <target>Video geupdate.</target>
5487 <context-group name="null">
5488 <context context-type="linenumber">1</context>
5489 </context-group>
5490 </trans-unit>
5491 <trans-unit id="aeb61b334cac080733c3e03766165a346bbf42fd">
5492 <source> <x id="INTERPOLATION" equiv-text="{{totalReplies}}"/> replies will be deleted too.</source>
5493 <target> <x id="INTERPOLATION" equiv-text="{{totalReplies}}"/> reacties zullen ook worden verwijdert.</target>
5494 <context-group name="null">
5495 <context context-type="linenumber">1</context>
5496 </context-group>
5497 </trans-unit>
5498 <trans-unit id="73c33d602da89a33d353d686f36c2fff39f0aee3">
5499 <source>Video blacklisted.</source>
5500 <target>Video op de zwarte lijst.</target>
5501 <context-group name="null">
5502 <context context-type="linenumber">1</context>
5503 </context-group>
5504 </trans-unit>
5505 <trans-unit id="ef90545bc832876c0d7f9a10363c75137472bbb5">
5506 <source>Copied</source>
5507 <target>Gekopieerd</target>
5508 <context-group name="null">
5509 <context context-type="linenumber">1</context>
5510 </context-group>
5511 </trans-unit>
5512 <trans-unit id="fa2601e52cbf5725a13d33fe14458823b882ea50">
5513 <source>Video reported.</source>
5514 <target>Video gerapporteerd.</target>
5515 <context-group name="null">
5516 <context context-type="linenumber">1</context>
5517 </context-group>
5518 </trans-unit>
5519 <trans-unit id="aca77c42f255d4bc6e95c12c5d656070726c6c2f">
5520 <source>Start at <x id="INTERPOLATION" equiv-text="{{timestamp}}"/></source>
5521 <target>Start op <x id="INTERPOLATION" equiv-text="{{timestamp}}"/></target>
5522 <context-group name="null">
5523 <context context-type="linenumber">1</context>
5524 </context-group>
5525 </trans-unit>
5526 <trans-unit id="0e65067fdcc9d8725a41896cb1e229d1415a45f6">
5527 <source>Like the video</source>
5528 <target>Like de video</target>
5529 <context-group name="null">
5530 <context context-type="linenumber">1</context>
5531 </context-group>
5532 </trans-unit>
5533 <trans-unit id="1a999e06e1aca0a70cd7d0e3e5c2c63d0e1885c8">
5534 <source>Dislike the video</source>
5535 <target>Dislike de video</target>
5536 <context-group name="null">
5537 <context context-type="linenumber">1</context>
5538 </context-group>
5539 </trans-unit>
5540 <trans-unit id="f1abd89c9280323209e939fa9c30f6e5cda20c95">
5541 <source>Do you really want to delete this video?</source>
5542 <target>Weet je zeker dat je de video wil verwijderen?</target>
5543 <context-group name="null">
5544 <context context-type="linenumber">1</context>
5545 </context-group>
5546 </trans-unit>
5547 <trans-unit id="d5a4811e15319ad9354e1b62e9ca0131192b489e">
5548 <source><x id="INTERPOLATION" equiv-text="{{likesNumber}}"/> likes / <x id="INTERPOLATION_1" equiv-text="{{dislikesNumber}}"/> dislikes</source>
5549 <target><x id="INTERPOLATION" equiv-text="{{likesNumber}}"/> likes / <x id="INTERPOLATION_1" equiv-text="{{dislikesNumber}}"/> dislikes</target>
5550 <context-group name="null">
5551 <context context-type="linenumber">1</context>
5552 </context-group>
5553 </trans-unit>
5554 <trans-unit id="ed013c2c29216501c688e9cb5f3a1c9fd9147b71">
5555 <source>This video contains mature or explicit content. Are you sure you want to watch it?</source>
5556 <target>Deze video bevat volwassen of expliciete inhoud. Weet je zeker dat je hem wilt kijken?</target>
1324 <context-group name="null"> 5557 <context-group name="null">
1325 <context context-type="linenumber">1</context> 5558 <context context-type="linenumber">1</context>
1326 </context-group> 5559 </context-group>
1327 </trans-unit> 5560 </trans-unit>
1328 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674"> 5561 <trans-unit id="5ba3d522e4146eefcbd5c222247c1e2423d27cd8">
1329 <source>Display name must be at least 3 characters long.</source> 5562 <source>Mature or explicit content</source>
1330 <target>Je weergavenaam moet minstens 3 tekens lang zijn.</target> 5563 <target>Volwassen of expliciete content</target>
1331 <context-group name="null"> 5564 <context-group name="null">
1332 <context context-type="linenumber">1</context> 5565 <context context-type="linenumber">1</context>
1333 </context-group> 5566 </context-group>
1334 </trans-unit> 5567 </trans-unit>
1335 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9"> 5568 <trans-unit id="1b157e15c434469d91e56d027b78bf69c9983165">
1336 <source>Display name cannot be more than 120 characters long.</source> 5569 <source>Videos from your subscriptions</source>
1337 <target>Je weergavenaam kan niet langer dan 120 tekens zijn.</target> 5570 <target>Videos van jou abonnementen</target>
1338 <context-group name="null"> 5571 <context-group name="null">
1339 <context context-type="linenumber">1</context> 5572 <context context-type="linenumber">1</context>
1340 </context-group> 5573 </context-group>
diff --git a/client/src/locale/target/angular_oc.xml b/client/src/locale/target/angular_oc.xml
index c353ead7a..106de7d5e 100644
--- a/client/src/locale/target/angular_oc.xml
+++ b/client/src/locale/target/angular_oc.xml
@@ -227,6 +227,57 @@
227 <context context-type="linenumber">11</context> 227 <context context-type="linenumber">11</context>
228 </context-group> 228 </context-group>
229 </trans-unit> 229 </trans-unit>
230 <trans-unit id="f3e63578c50546530daf6050d2ba6f8226040f2c">
231 <source>You don't have notifications.</source>
232 <target>Avètz pas cap de notificacion.</target>
233 <context-group name="null">
234 <context context-type="linenumber">1</context>
235 </context-group>
236 </trans-unit>
237 <trans-unit id="f79d1d9ecaab3deb3d44e23017f8283a04d2a0f3">
238 <source>
239 <x id="INTERPOLATION" equiv-text="{{ notification.video.channel.displayName }}"/> published a <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>new video<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
240 </source>
241 <target>
242 <x id="INTERPOLATION" equiv-text="{{ notification.video.channel.displayName }}"/> a publicat una <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/>nòva vidèo<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
243 </target>
244 <context-group name="null">
245 <context context-type="linenumber">7</context>
246 </context-group>
247 </trans-unit>
248 <trans-unit id="23b7d6f08c5c3b8722ecd627c3d54f4950923156">
249 <source>
250 <x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/> commented your video <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
251 </source>
252 <target>
253 <x id="INTERPOLATION" equiv-text="{{ notification.comment.account.displayName }}"/> a comentat vòstra vidèo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION_1" equiv-text="{{ notification.comment.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>
254 </target>
255 <context-group name="null">
256 <context context-type="linenumber">23</context>
257 </context-group>
258 </trans-unit>
259 <trans-unit id="2d0ee93317d4daa301eee7fec775c21c2f7b5a4b">
260 <source>
261 Your video <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> has been published
262 </source>
263 <target>
264 Vòstra vidèo <x id="START_LINK" ctype="x-a" equiv-text="&lt;a&gt;"/><x id="INTERPOLATION" equiv-text="{{ notification.video.name }}"/><x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/> es publicada
265 </target>
266 <context-group name="null">
267 <context context-type="linenumber">27</context>
268 </context-group>
269 </trans-unit>
270 <trans-unit id="473117e02024f603dc2dbd24a0bf81f8722cf8dc">
271 <source>
272 <x id="START_TAG_DIV" ctype="x-div" equiv-text="&lt;div&gt;"/><x id="CLOSE_TAG_DIV" ctype="x-div" equiv-text="&lt;/div&gt;"/>
273 </source>
274 <target>
275 <x id="START_TAG_DIV" ctype="x-div" equiv-text="&lt;div&gt;"/><x id="CLOSE_TAG_DIV" ctype="x-div" equiv-text="&lt;/div&gt;"/>
276 </target>
277 <context-group name="null">
278 <context context-type="linenumber">57</context>
279 </context-group>
280 </trans-unit>
230 <trans-unit id="4b3963c6d0863118fe9e9e33447d12be3c2db081"> 281 <trans-unit id="4b3963c6d0863118fe9e9e33447d12be3c2db081">
231 <source>Unlisted</source> 282 <source>Unlisted</source>
232 <target>Pas listada</target> 283 <target>Pas listada</target>
@@ -434,6 +485,13 @@
434 <context context-type="linenumber">25</context> 485 <context context-type="linenumber">25</context>
435 </context-group> 486 </context-group>
436 </trans-unit> 487 </trans-unit>
488 <trans-unit id="c078d4901a5fac169665947cc7a6108b94dd80c7">
489 <source><x id="INTERPOLATION" equiv-text="{{ menuEntry.label }}"/></source>
490 <target><x id="INTERPOLATION" equiv-text="{{ menuEntry.label }}"/></target>
491 <context-group name="null">
492 <context context-type="linenumber">11</context>
493 </context-group>
494 </trans-unit>
437 <trans-unit id="12910217fdcdbca64bee06f511639b653d5428ea"> 495 <trans-unit id="12910217fdcdbca64bee06f511639b653d5428ea">
438 <source> 496 <source>
439 Login 497 Login
@@ -499,7 +557,7 @@
499 <source>Password</source> 557 <source>Password</source>
500 <target>Senhal</target> 558 <target>Senhal</target>
501 <context-group name="null"> 559 <context-group name="null">
502 <context context-type="linenumber">12</context> 560 <context context-type="linenumber">13</context>
503 </context-group> 561 </context-group>
504 </trans-unit> 562 </trans-unit>
505 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 563 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -513,7 +571,7 @@
513 <source>Login</source> 571 <source>Login</source>
514 <target>Connexion</target> 572 <target>Connexion</target>
515 <context-group name="null"> 573 <context-group name="null">
516 <context context-type="linenumber">38</context> 574 <context context-type="linenumber">36</context>
517 </context-group> 575 </context-group>
518 </trans-unit> 576 </trans-unit>
519 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 577 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -541,7 +599,7 @@
541 <source>Send me an email to reset my password</source> 599 <source>Send me an email to reset my password</source>
542 <target>Me mandar un corrièl per reïnicializar lo senhal</target> 600 <target>Me mandar un corrièl per reïnicializar lo senhal</target>
543 <context-group name="null"> 601 <context-group name="null">
544 <context context-type="linenumber">75</context> 602 <context context-type="linenumber">80</context>
545 </context-group> 603 </context-group>
546 </trans-unit> 604 </trans-unit>
547 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 605 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -610,7 +668,7 @@
610 <source>Signup</source> 668 <source>Signup</source>
611 <target>Inscripcion</target> 669 <target>Inscripcion</target>
612 <context-group name="null"> 670 <context-group name="null">
613 <context context-type="linenumber">88</context> 671 <context context-type="linenumber">78</context>
614 </context-group> 672 </context-group>
615 </trans-unit> 673 </trans-unit>
616 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 674 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -680,7 +738,18 @@
680 <source>Change the language</source> 738 <source>Change the language</source>
681 <target>Cambiar la lenga</target> 739 <target>Cambiar la lenga</target>
682 <context-group name="null"> 740 <context-group name="null">
683 <context context-type="linenumber">88</context> 741 <context context-type="linenumber">86</context>
742 </context-group>
743 </trans-unit>
744 <trans-unit id="1c98d728375e7bd5b166d1aeb29485ef8b5d6e28">
745 <source>
746 Help to translate PeerTube!
747 </source>
748 <target>
749 Ajudatz a traduire PeerTube !
750 </target>
751 <context-group name="null">
752 <context context-type="linenumber">8</context>
684 </context-group> 753 </context-group>
685 </trans-unit> 754 </trans-unit>
686 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 755 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -691,7 +760,7 @@
691 Mon perfil public 760 Mon perfil public
692 </target> 761 </target>
693 <context-group name="null"> 762 <context-group name="null">
694 <context context-type="linenumber">18</context> 763 <context context-type="linenumber">16</context>
695 </context-group> 764 </context-group>
696 </trans-unit> 765 </trans-unit>
697 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 766 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -702,7 +771,7 @@
702 Mon compte 771 Mon compte
703 </target> 772 </target>
704 <context-group name="null"> 773 <context-group name="null">
705 <context context-type="linenumber">22</context> 774 <context context-type="linenumber">20</context>
706 </context-group> 775 </context-group>
707 </trans-unit> 776 </trans-unit>
708 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 777 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -713,7 +782,7 @@
713 Mas vidèos 782 Mas vidèos
714 </target> 783 </target>
715 <context-group name="null"> 784 <context-group name="null">
716 <context context-type="linenumber">26</context> 785 <context context-type="linenumber">24</context>
717 </context-group> 786 </context-group>
718 </trans-unit> 787 </trans-unit>
719 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 788 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -724,14 +793,14 @@
724 Desconnexion 793 Desconnexion
725 </target> 794 </target>
726 <context-group name="null"> 795 <context-group name="null">
727 <context context-type="linenumber">30</context> 796 <context context-type="linenumber">28</context>
728 </context-group> 797 </context-group>
729 </trans-unit> 798 </trans-unit>
730 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 799 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
731 <source>Create an account</source> 800 <source>Create an account</source>
732 <target>Crear un compte</target> 801 <target>Crear un compte</target>
733 <context-group name="null"> 802 <context-group name="null">
734 <context context-type="linenumber">39</context> 803 <context context-type="linenumber">37</context>
735 </context-group> 804 </context-group>
736 </trans-unit> 805 </trans-unit>
737 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 806 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -745,49 +814,49 @@
745 <source>Subscriptions</source> 814 <source>Subscriptions</source>
746 <target>Abonaments</target> 815 <target>Abonaments</target>
747 <context-group name="null"> 816 <context-group name="null">
748 <context context-type="linenumber">47</context> 817 <context context-type="linenumber">45</context>
749 </context-group> 818 </context-group>
750 </trans-unit> 819 </trans-unit>
751 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 820 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
752 <source>Overview</source> 821 <source>Overview</source>
753 <target>Apercebut</target> 822 <target>Apercebut</target>
754 <context-group name="null"> 823 <context-group name="null">
755 <context context-type="linenumber">52</context> 824 <context context-type="linenumber">50</context>
756 </context-group> 825 </context-group>
757 </trans-unit> 826 </trans-unit>
758 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 827 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
759 <source>Trending</source> 828 <source>Trending</source>
760 <target>Tendéncias</target> 829 <target>Tendéncias</target>
761 <context-group name="null"> 830 <context-group name="null">
762 <context context-type="linenumber">57</context> 831 <context context-type="linenumber">55</context>
763 </context-group> 832 </context-group>
764 </trans-unit> 833 </trans-unit>
765 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 834 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
766 <source>Recently added</source> 835 <source>Recently added</source>
767 <target>Apondons recents</target> 836 <target>Apondons recents</target>
768 <context-group name="null"> 837 <context-group name="null">
769 <context context-type="linenumber">62</context> 838 <context context-type="linenumber">60</context>
770 </context-group> 839 </context-group>
771 </trans-unit> 840 </trans-unit>
772 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 841 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
773 <source>Local</source> 842 <source>Local</source>
774 <target>Localas</target> 843 <target>Localas</target>
775 <context-group name="null"> 844 <context-group name="null">
776 <context context-type="linenumber">67</context> 845 <context context-type="linenumber">65</context>
777 </context-group> 846 </context-group>
778 </trans-unit> 847 </trans-unit>
779 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 848 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
780 <source>More</source> 849 <source>More</source>
781 <target>Mai</target> 850 <target>Mai</target>
782 <context-group name="null"> 851 <context-group name="null">
783 <context context-type="linenumber">72</context> 852 <context context-type="linenumber">70</context>
784 </context-group> 853 </context-group>
785 </trans-unit> 854 </trans-unit>
786 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 855 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
787 <source>Administration</source> 856 <source>Administration</source>
788 <target>Administracion</target> 857 <target>Administracion</target>
789 <context-group name="null"> 858 <context-group name="null">
790 <context context-type="linenumber">76</context> 859 <context context-type="linenumber">74</context>
791 </context-group> 860 </context-group>
792 </trans-unit> 861 </trans-unit>
793 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 862 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -801,14 +870,42 @@
801 <source>Show keyboard shortcuts</source> 870 <source>Show keyboard shortcuts</source>
802 <target>Mostrar los acorchis clavièr</target> 871 <target>Mostrar los acorchis clavièr</target>
803 <context-group name="null"> 872 <context-group name="null">
804 <context context-type="linenumber">91</context> 873 <context context-type="linenumber">89</context>
805 </context-group> 874 </context-group>
806 </trans-unit> 875 </trans-unit>
807 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 876 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
808 <source>Toggle dark interface</source> 877 <source>Toggle dark interface</source>
809 <target>Passar a l’interfàcia escura</target> 878 <target>Passar a l’interfàcia escura</target>
810 <context-group name="null"> 879 <context-group name="null">
811 <context context-type="linenumber">94</context> 880 <context context-type="linenumber">92</context>
881 </context-group>
882 </trans-unit>
883 <trans-unit id="2dc8a0a3763cd5c456c84630fc335398c9b86771">
884 <source>View your notifications</source>
885 <target>Veire vòstras notificacions</target>
886 <context-group name="null">
887 <context context-type="linenumber">3</context>
888 </context-group>
889 </trans-unit>
890 <trans-unit id="8bcabdf6b16cad0313a86c7e940c5e3ad7f9f8ab">
891 <source>Notifications</source>
892 <target>Notificacions</target>
893 <context-group name="null">
894 <context context-type="linenumber">10</context>
895 </context-group>
896 </trans-unit>
897 <trans-unit id="341e026e3f317aa3164916cc63a059c961a78b81">
898 <source>Update your notification preferences</source>
899 <target>Actualizar vòstras preferéncias de notificacion</target>
900 <context-group name="null">
901 <context context-type="linenumber">15</context>
902 </context-group>
903 </trans-unit>
904 <trans-unit id="3d1b5c9cd76948c04fdb7bb3fe51b6c1242c1bd5">
905 <source>See all your notifications</source>
906 <target>Veire totas vòstras notificacions</target>
907 <context-group name="null">
908 <context context-type="linenumber">22</context>
812 </context-group> 909 </context-group>
813 </trans-unit> 910 </trans-unit>
814 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 911 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -913,14 +1010,14 @@
913 <source>Display unlisted and private videos</source> 1010 <source>Display unlisted and private videos</source>
914 <target>Mostrar las vidèos pas listadas e las privadas</target> 1011 <target>Mostrar las vidèos pas listadas e las privadas</target>
915 <context-group name="null"> 1012 <context-group name="null">
916 <context context-type="linenumber">11</context> 1013 <context context-type="linenumber">14</context>
917 </context-group> 1014 </context-group>
918 </trans-unit> 1015 </trans-unit>
919 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 1016 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
920 <source>No results.</source> 1017 <source>No results.</source>
921 <target>Cap de resultat</target> 1018 <target>Cap de resultat</target>
922 <context-group name="null"> 1019 <context-group name="null">
923 <context context-type="linenumber">17</context> 1020 <context context-type="linenumber">20</context>
924 </context-group> 1021 </context-group>
925 </trans-unit> 1022 </trans-unit>
926 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 1023 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -978,67 +1075,78 @@
978 <context context-type="linenumber">7</context> 1075 <context context-type="linenumber">7</context>
979 </context-group> 1076 </context-group>
980 </trans-unit> 1077 </trans-unit>
981 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 1078 <trans-unit id="5fea66be16da46ed7a0775e9a62b7b5e94b77473">
982 <source> 1079 <source>Contact <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> administrator</source>
983 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 1080 <target>Contactar l’administrator de <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/></target>
984</source>
985 <target>
986 A prepaus de l’instància <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/>
987</target>
988 <context-group name="null"> 1081 <context-group name="null">
989 <context context-type="linenumber">1</context> 1082 <context context-type="linenumber">3</context>
990 </context-group> 1083 </context-group>
991 </trans-unit> 1084 </trans-unit>
992 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 1085 <trans-unit id="533b2b9a76ee1335cb44c01f0bfd50d43e9400b0">
993 <source>Description</source> 1086 <source>Your name</source>
994 <target>Descripcion</target> 1087 <target>Vòstre nom</target>
995 <context-group name="null"> 1088 <context-group name="null">
996 <context context-type="linenumber">27</context> 1089 <context context-type="linenumber">11</context>
997 </context-group> 1090 </context-group>
998 </trans-unit> 1091 </trans-unit>
999 <trans-unit id="69580f2c2dbf4edf7096820ba8c393367352d774"> 1092 <trans-unit id="0b892c7805a1c5afc0b7c21c3449760860fe7f3d">
1000 <source>Terms</source> 1093 <source>Your email</source>
1001 <target>Tèrmes</target> 1094 <target>Vòstra adreça</target>
1002 <context-group name="null"> 1095 <context-group name="null">
1003 <context context-type="linenumber">44</context> 1096 <context context-type="linenumber">20</context>
1004 </context-group> 1097 </context-group>
1005 </trans-unit> 1098 </trans-unit>
1006 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 1099 <trans-unit id="d2815c9b510b8172d8cac4008b9709df69d636df">
1007 <source>User registration is allowed and</source> 1100 <source>Your message</source>
1008 <target>Las inscripcions son autorizadas e</target> 1101 <target>Vòstre messatge</target>
1009 <context-group name="null"> 1102 <context-group name="null">
1010 <context context-type="linenumber">25</context> 1103 <context context-type="linenumber">29</context>
1011 </context-group> 1104 </context-group>
1012 </trans-unit> 1105 </trans-unit>
1013 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e"> 1106 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
1014 <source> 1107 <source>
1015 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users. 1108 Cancel
1016 </source> 1109 </source>
1017 <target> 1110 <target>
1018 aquesta instància provesís un quòta de basa de <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> d’espaci per las vidèos de sos utilizaires. 1111 Anullar
1019 </target> 1112 </target>
1020 <context-group name="null"> 1113 <context-group name="null">
1021 <context context-type="linenumber">27</context> 1114 <context context-type="linenumber">26</context>
1022 </context-group> 1115 </context-group>
1023 </trans-unit> 1116 </trans-unit>
1024 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae"> 1117 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
1025 <source> 1118 <source>Submit</source>
1026 this instance provides unlimited space for the videos of its users. 1119 <target>Mandar</target>
1027 </source>
1028 <target>
1029 aquesta instància fornís un espaci sens limit per las vidèos de sos utilizaires.
1030 </target>
1031 <context-group name="null"> 1120 <context-group name="null">
1032 <context context-type="linenumber">31</context> 1121 <context context-type="linenumber">31</context>
1033 </context-group> 1122 </context-group>
1034 </trans-unit> 1123 </trans-unit>
1035 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1"> 1124 <trans-unit id="89e55a86cb300f06139ff398c9c8bb7376f78b07">
1036 <source> 1125 <source>About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance</source>
1037 User registration is currently not allowed. 1126 <target>A prepaus de l’instància <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/></target>
1038 </source>
1039 <target>Las inscriptions son pas pel moment possiblas</target>
1040 <context-group name="null"> 1127 <context-group name="null">
1041 <context context-type="linenumber">36</context> 1128 <context context-type="linenumber">4</context>
1129 </context-group>
1130 </trans-unit>
1131 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
1132 <source>Description</source>
1133 <target>Descripcion</target>
1134 <context-group name="null">
1135 <context context-type="linenumber">27</context>
1136 </context-group>
1137 </trans-unit>
1138 <trans-unit id="69580f2c2dbf4edf7096820ba8c393367352d774">
1139 <source>Terms</source>
1140 <target>Tèrmes</target>
1141 <context-group name="null">
1142 <context context-type="linenumber">39</context>
1143 </context-group>
1144 </trans-unit>
1145 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
1146 <source>User registration is allowed and</source>
1147 <target>Las inscripcions son autorizadas e</target>
1148 <context-group name="null">
1149 <context context-type="linenumber">29</context>
1042 </context-group> 1150 </context-group>
1043 </trans-unit> 1151 </trans-unit>
1044 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 1152 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1393,49 +1501,49 @@
1393 <source>Short description</source> 1501 <source>Short description</source>
1394 <target>Descripcion corta</target> 1502 <target>Descripcion corta</target>
1395 <context-group name="null"> 1503 <context-group name="null">
1396 <context context-type="linenumber">22</context> 1504 <context context-type="linenumber">21</context>
1397 </context-group> 1505 </context-group>
1398 </trans-unit> 1506 </trans-unit>
1399 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1507 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1400 <source>Default client route</source> 1508 <source>Default client route</source>
1401 <target>Rota del client per defaut</target> 1509 <target>Rota del client per defaut</target>
1402 <context-group name="null"> 1510 <context-group name="null">
1403 <context context-type="linenumber">55</context> 1511 <context context-type="linenumber">48</context>
1404 </context-group> 1512 </context-group>
1405 </trans-unit> 1513 </trans-unit>
1406 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1514 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1407 <source>Videos Overview</source> 1515 <source>Videos Overview</source>
1408 <target>Apercebuts de las vidèos</target> 1516 <target>Apercebuts de las vidèos</target>
1409 <context-group name="null"> 1517 <context-group name="null">
1410 <context context-type="linenumber">58</context> 1518 <context context-type="linenumber">51</context>
1411 </context-group> 1519 </context-group>
1412 </trans-unit> 1520 </trans-unit>
1413 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1521 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1414 <source>Videos Trending</source> 1522 <source>Videos Trending</source>
1415 <target>Vidèos a la mòda </target> 1523 <target>Vidèos a la mòda </target>
1416 <context-group name="null"> 1524 <context-group name="null">
1417 <context context-type="linenumber">59</context> 1525 <context context-type="linenumber">52</context>
1418 </context-group> 1526 </context-group>
1419 </trans-unit> 1527 </trans-unit>
1420 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1528 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1421 <source>Videos Recently Added</source> 1529 <source>Videos Recently Added</source>
1422 <target>Vidèos ajustadas recentament</target> 1530 <target>Vidèos ajustadas recentament</target>
1423 <context-group name="null"> 1531 <context-group name="null">
1424 <context context-type="linenumber">60</context> 1532 <context context-type="linenumber">53</context>
1425 </context-group> 1533 </context-group>
1426 </trans-unit> 1534 </trans-unit>
1427 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1535 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1428 <source>Local videos</source> 1536 <source>Local videos</source>
1429 <target>Vidèos localas</target> 1537 <target>Vidèos localas</target>
1430 <context-group name="null"> 1538 <context-group name="null">
1431 <context context-type="linenumber">61</context> 1539 <context context-type="linenumber">54</context>
1432 </context-group> 1540 </context-group>
1433 </trans-unit> 1541 </trans-unit>
1434 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1542 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1435 <source>Policy on videos containing sensitive content</source> 1543 <source>Policy on videos containing sensitive content</source>
1436 <target>Politica tocant las vidèos amb de contengut sensible</target> 1544 <target>Politica tocant las vidèos amb de contengut sensible</target>
1437 <context-group name="null"> 1545 <context-group name="null">
1438 <context context-type="linenumber">70</context> 1546 <context context-type="linenumber">61</context>
1439 </context-group> 1547 </context-group>
1440 </trans-unit> 1548 </trans-unit>
1441 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1549 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1470,23 +1578,44 @@
1470 <source>Signup enabled</source> 1578 <source>Signup enabled</source>
1471 <target>Inscripcions activadas</target> 1579 <target>Inscripcions activadas</target>
1472 <context-group name="null"> 1580 <context-group name="null">
1473 <context context-type="linenumber">93</context> 1581 <context context-type="linenumber">84</context>
1474 </context-group> 1582 </context-group>
1475 </trans-unit> 1583 </trans-unit>
1476 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1584 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1477 <source>Signup requires email verification</source> 1585 <source>Signup requires email verification</source>
1478 <target>L’inscripcion demanda una verificacion d’adreça electronica</target> 1586 <target>L’inscripcion demanda una verificacion d’adreça electronica</target>
1479 <context-group name="null"> 1587 <context-group name="null">
1480 <context context-type="linenumber">100</context> 1588 <context context-type="linenumber">91</context>
1481 </context-group> 1589 </context-group>
1482 </trans-unit> 1590 </trans-unit>
1483 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1591 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1484 <source>Signup limit</source> 1592 <source>Signup limit</source>
1485 <target>Limit d’inscripcions</target> 1593 <target>Limit d’inscripcions</target>
1486 <context-group name="null"> 1594 <context-group name="null">
1595 <context context-type="linenumber">96</context>
1596 </context-group>
1597 </trans-unit>
1598 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1599 <source>Users</source>
1600 <target>Utilizaires</target>
1601 <context-group name="null">
1487 <context context-type="linenumber">105</context> 1602 <context context-type="linenumber">105</context>
1488 </context-group> 1603 </context-group>
1489 </trans-unit> 1604 </trans-unit>
1605 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1606 <source>User default video quota</source>
1607 <target>Quòta per defaut per utilizaire</target>
1608 <context-group name="null">
1609 <context context-type="linenumber">109</context>
1610 </context-group>
1611 </trans-unit>
1612 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1613 <source>User default daily upload limit</source>
1614 <target>Quòta jornalièr de mandadís per defaut dels utilizaires </target>
1615 <context-group name="null">
1616 <context context-type="linenumber">121</context>
1617 </context-group>
1618 </trans-unit>
1490 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1619 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1491 <source>Import</source> 1620 <source>Import</source>
1492 <target>Importar</target> 1621 <target>Importar</target>
@@ -1498,49 +1627,28 @@
1498 <source>Video import with HTTP URL (i.e. YouTube) enabled</source> 1627 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1499 <target>Import vidèo amb URL HTTP (per exemple YouTube) activat</target> 1628 <target>Import vidèo amb URL HTTP (per exemple YouTube) activat</target>
1500 <context-group name="null"> 1629 <context-group name="null">
1501 <context context-type="linenumber">120</context> 1630 <context context-type="linenumber">141</context>
1502 </context-group> 1631 </context-group>
1503 </trans-unit> 1632 </trans-unit>
1504 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e"> 1633 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e">
1505 <source>Video import with a torrent file or a magnet URI enabled</source> 1634 <source>Video import with a torrent file or a magnet URI enabled</source>
1506 <target>Import de vidèos via un fichièr torretn o un magnet URI activat</target> 1635 <target>Import de vidèos via un fichièr torretn o un magnet URI activat</target>
1507 <context-group name="null"> 1636 <context-group name="null">
1508 <context context-type="linenumber">127</context> 1637 <context context-type="linenumber">148</context>
1509 </context-group> 1638 </context-group>
1510 </trans-unit> 1639 </trans-unit>
1511 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1640 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1512 <source>Administrator</source> 1641 <source>Administrator</source>
1513 <target>Administrator</target> 1642 <target>Administrator</target>
1514 <context-group name="null"> 1643 <context-group name="null">
1515 <context context-type="linenumber">131</context> 1644 <context context-type="linenumber">155</context>
1516 </context-group> 1645 </context-group>
1517 </trans-unit> 1646 </trans-unit>
1518 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1647 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1519 <source>Admin email</source> 1648 <source>Admin email</source>
1520 <target>Adreça de l’admin</target> 1649 <target>Adreça de l’admin</target>
1521 <context-group name="null"> 1650 <context-group name="null">
1522 <context context-type="linenumber">134</context> 1651 <context context-type="linenumber">158</context>
1523 </context-group>
1524 </trans-unit>
1525 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1526 <source>Users</source>
1527 <target>Utilizaires</target>
1528 <context-group name="null">
1529 <context context-type="linenumber">144</context>
1530 </context-group>
1531 </trans-unit>
1532 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1533 <source>User default video quota</source>
1534 <target>Quòta per defaut per utilizaire</target>
1535 <context-group name="null">
1536 <context context-type="linenumber">147</context>
1537 </context-group>
1538 </trans-unit>
1539 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1540 <source>User default daily upload limit</source>
1541 <target>Quòta jornalièr de mandadís per defaut dels utilizaires </target>
1542 <context-group name="null">
1543 <context context-type="linenumber">161</context>
1544 </context-group> 1652 </context-group>
1545 </trans-unit> 1653 </trans-unit>
1546 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1654 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1561,21 +1669,21 @@
1561 <source>Your Twitter username</source> 1669 <source>Your Twitter username</source>
1562 <target>Vòstre nom d’utilizaire Twitter</target> 1670 <target>Vòstre nom d’utilizaire Twitter</target>
1563 <context-group name="null"> 1671 <context-group name="null">
1564 <context context-type="linenumber">181</context> 1672 <context context-type="linenumber">184</context>
1565 </context-group> 1673 </context-group>
1566 </trans-unit> 1674 </trans-unit>
1567 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1675 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1568 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1676 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1569 <target>Indica lo compte Twitter del site o de la plataforma ont lo contengut foguèt publicat.</target> 1677 <target>Indica lo compte Twitter del site o de la plataforma ont lo contengut foguèt publicat.</target>
1570 <context-group name="null"> 1678 <context-group name="null">
1571 <context context-type="linenumber">184</context> 1679 <context context-type="linenumber">187</context>
1572 </context-group> 1680 </context-group>
1573 </trans-unit> 1681 </trans-unit>
1574 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1682 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1575 <source>Instance whitelisted by Twitter</source> 1683 <source>Instance whitelisted by Twitter</source>
1576 <target>Instàncias en lista blanca per Twitter</target> 1684 <target>Instàncias en lista blanca per Twitter</target>
1577 <context-group name="null"> 1685 <context-group name="null">
1578 <context context-type="linenumber">198</context> 1686 <context context-type="linenumber">199</context>
1579 </context-group> 1687 </context-group>
1580 </trans-unit> 1688 </trans-unit>
1581 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1689 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1589,35 +1697,35 @@
1589 <source>Transcoding</source> 1697 <source>Transcoding</source>
1590 <target>Transcodatge</target> 1698 <target>Transcodatge</target>
1591 <context-group name="null"> 1699 <context-group name="null">
1592 <context context-type="linenumber">210</context> 1700 <context context-type="linenumber">215</context>
1593 </context-group> 1701 </context-group>
1594 </trans-unit> 1702 </trans-unit>
1595 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1703 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1596 <source>Transcoding enabled</source> 1704 <source>Transcoding enabled</source>
1597 <target>Transcodatge activat</target> 1705 <target>Transcodatge activat</target>
1598 <context-group name="null"> 1706 <context-group name="null">
1599 <context context-type="linenumber">215</context> 1707 <context context-type="linenumber">221</context>
1600 </context-group> 1708 </context-group>
1601 </trans-unit> 1709 </trans-unit>
1602 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1710 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1603 <source>If you disable transcoding, many videos from your users will not work!</source> 1711 <source>If you disable transcoding, many videos from your users will not work!</source>
1604 <target>Se desactivatz lo transcodatge, un fum de vidèos de vòstres utilizaires foncionaràn pas !</target> 1712 <target>Se desactivatz lo transcodatge, un fum de vidèos de vòstres utilizaires foncionaràn pas !</target>
1605 <context-group name="null"> 1713 <context-group name="null">
1606 <context context-type="linenumber">216</context> 1714 <context context-type="linenumber">222</context>
1607 </context-group> 1715 </context-group>
1608 </trans-unit> 1716 </trans-unit>
1609 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1717 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1610 <source>Transcoding threads</source> 1718 <source>Transcoding threads</source>
1611 <target>Transcodatge dels threads</target> 1719 <target>Transcodatge dels threads</target>
1612 <context-group name="null"> 1720 <context-group name="null">
1613 <context context-type="linenumber">223</context> 1721 <context context-type="linenumber">237</context>
1614 </context-group> 1722 </context-group>
1615 </trans-unit> 1723 </trans-unit>
1616 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1724 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1617 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1725 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1618 <target>Resolucion <x id="INTERPOLATION" equiv-text="{{resolution}}"/> activada</target> 1726 <target>Resolucion <x id="INTERPOLATION" equiv-text="{{resolution}}"/> activada</target>
1619 <context-group name="null"> 1727 <context-group name="null">
1620 <context context-type="linenumber">239</context> 1728 <context context-type="linenumber">252</context>
1621 </context-group> 1729 </context-group>
1622 </trans-unit> 1730 </trans-unit>
1623 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1731 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1632,83 +1740,48 @@
1632 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1740 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1633 </target> 1741 </target>
1634 <context-group name="null"> 1742 <context-group name="null">
1635 <context context-type="linenumber">244</context> 1743 <context context-type="linenumber">260</context>
1636 </context-group> 1744 </context-group>
1637 </trans-unit> 1745 </trans-unit>
1638 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1746 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1639 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1747 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1640 <target>Qualques fichièrs son pas federats (apercebuts, legendas). Los recuperam de l’instància d’origina estant e los metèm en cache.</target> 1748 <target>Qualques fichièrs son pas federats (apercebuts, legendas). Los recuperam de l’instància d’origina estant e los metèm en cache.</target>
1641 <context-group name="null"> 1749 <context-group name="null">
1642 <context context-type="linenumber">249</context> 1750 <context context-type="linenumber">265</context>
1643 </context-group> 1751 </context-group>
1644 </trans-unit> 1752 </trans-unit>
1645 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1753 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1646 <source>Previews cache size</source> 1754 <source>Previews cache size</source>
1647 <target>Talha del cache d’apercebut</target> 1755 <target>Talha del cache d’apercebut</target>
1648 <context-group name="null"> 1756 <context-group name="null">
1649 <context context-type="linenumber">254</context> 1757 <context context-type="linenumber">271</context>
1650 </context-group> 1758 </context-group>
1651 </trans-unit> 1759 </trans-unit>
1652 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1760 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1653 <source>Video captions cache size</source> 1761 <source>Video captions cache size</source>
1654 <target>Talha del cache per las legendas de las vidèos</target> 1762 <target>Talha del cache per las legendas de las vidèos</target>
1655 <context-group name="null"> 1763 <context-group name="null">
1656 <context context-type="linenumber">265</context> 1764 <context context-type="linenumber">280</context>
1657 </context-group> 1765 </context-group>
1658 </trans-unit> 1766 </trans-unit>
1659 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1767 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1660 <source>Customizations</source> 1768 <source>Customizations</source>
1661 <target>Personalizacions</target> 1769 <target>Personalizacions</target>
1662 <context-group name="null"> 1770 <context-group name="null">
1663 <context context-type="linenumber">275</context> 1771 <context context-type="linenumber">289</context>
1664 </context-group> 1772 </context-group>
1665 </trans-unit> 1773 </trans-unit>
1666 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1774 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1667 <source>JavaScript</source> 1775 <source>JavaScript</source>
1668 <target>JavaScript</target> 1776 <target>JavaScript</target>
1669 <context-group name="null"> 1777 <context-group name="null">
1670 <context context-type="linenumber">278</context> 1778 <context context-type="linenumber">294</context>
1671 </context-group> 1779 </context-group>
1672 </trans-unit> 1780 </trans-unit>
1673 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1781 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1674 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1782 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1675 <target>Escrivètz dirèctament de JavaScript còdi.&lt;br /&gt;Exemple : &lt;pre&gt;console.log('mon instància es tròp crana');&lt;/pre&gt;</target> 1783 <target>Escrivètz dirèctament de JavaScript còdi.&lt;br /&gt;Exemple : &lt;pre&gt;console.log('mon instància es tròp crana');&lt;/pre&gt;</target>
1676 <context-group name="null"> 1784 <context-group name="null">
1677 <context context-type="linenumber">281</context>
1678 </context-group>
1679 </trans-unit>
1680 <trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5">
1681 <source>
1682 Write directly CSS code. Example:&lt;br /&gt;
1683 &lt;pre&gt;
1684 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1685 background-color: red;
1686 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1687 &lt;/pre&gt;
1688
1689 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1690 &lt;pre&gt;
1691 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1692 color: red;
1693 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1694 &lt;/pre&gt;
1695 </source>
1696 <target>
1697 Escrivètz dirèctament lo còdi CSS. Exemple :&lt;br /&gt;
1698 &lt;pre&gt;
1699 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1700 background-color: red;
1701 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1702 &lt;/pre&gt;
1703
1704 Prefixatz amb &lt;em&gt;#custom-css&lt;/em&gt; per subrecargar los estiles. Exemple :
1705 &lt;pre&gt;
1706 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1707 color: red;
1708 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1709 &lt;/pre&gt;
1710 </target>
1711 <context-group name="null">
1712 <context context-type="linenumber">297</context> 1785 <context context-type="linenumber">297</context>
1713 </context-group> 1786 </context-group>
1714 </trans-unit> 1787 </trans-unit>
@@ -1716,21 +1789,21 @@
1716 <source>Advanced configuration</source> 1789 <source>Advanced configuration</source>
1717 <target>Configuracion avançada</target> 1790 <target>Configuracion avançada</target>
1718 <context-group name="null"> 1791 <context-group name="null">
1719 <context context-type="linenumber">207</context> 1792 <context context-type="linenumber">212</context>
1720 </context-group> 1793 </context-group>
1721 </trans-unit> 1794 </trans-unit>
1722 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1795 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1723 <source>Update configuration</source> 1796 <source>Update configuration</source>
1724 <target>Actualizar la configuracion</target> 1797 <target>Actualizar la configuracion</target>
1725 <context-group name="null"> 1798 <context-group name="null">
1726 <context context-type="linenumber">325</context> 1799 <context context-type="linenumber">340</context>
1727 </context-group> 1800 </context-group>
1728 </trans-unit> 1801 </trans-unit>
1729 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1802 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1730 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1803 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1731 <target>Sembla que la configuracion es invalida. Mercés de cercar d’errors possiblas pels diferents onglets.</target> 1804 <target>Sembla que la configuracion es invalida. Mercés de cercar d’errors possiblas pels diferents onglets.</target>
1732 <context-group name="null"> 1805 <context-group name="null">
1733 <context context-type="linenumber">326</context> 1806 <context context-type="linenumber">341</context>
1734 </context-group> 1807 </context-group>
1735 </trans-unit> 1808 </trans-unit>
1736 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1809 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -2022,11 +2095,25 @@
2022 <context context-type="linenumber">133</context> 2095 <context context-type="linenumber">133</context>
2023 </context-group> 2096 </context-group>
2024 </trans-unit> 2097 </trans-unit>
2098 <trans-unit id="02ba1a65db92d1d0ab4ba380086e9be61891aaa5">
2099 <source>User's email must be verified to login</source>
2100 <target>Lo corrièl de l’utilizaire deu èsser verificat abans la connexion</target>
2101 <context-group name="null">
2102 <context context-type="linenumber">72</context>
2103 </context-group>
2104 </trans-unit>
2105 <trans-unit id="79cee9973620b2592ff2824c525aa8ed0b5e2b8b">
2106 <source>User's email is verified / User can login without email verification</source>
2107 <target>Lo corrièl de l’utilizaire es verificat / Pòt se connectar sens verificacion de l’adreça</target>
2108 <context-group name="null">
2109 <context context-type="linenumber">76</context>
2110 </context-group>
2111 </trans-unit>
2025 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee"> 2112 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee">
2026 <source>Ban reason:</source> 2113 <source>Ban reason:</source>
2027 <target>Rason del bandiment :</target> 2114 <target>Rason del bandiment :</target>
2028 <context-group name="null"> 2115 <context-group name="null">
2029 <context context-type="linenumber">92</context> 2116 <context context-type="linenumber">95</context>
2030 </context-group> 2117 </context-group>
2031 </trans-unit> 2118 </trans-unit>
2032 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 2119 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -2093,7 +2180,7 @@
2093 <source>Actions</source> 2180 <source>Actions</source>
2094 <target>Accions</target> 2181 <target>Accions</target>
2095 <context-group name="null"> 2182 <context-group name="null">
2096 <context context-type="linenumber">33</context> 2183 <context context-type="linenumber">35</context>
2097 </context-group> 2184 </context-group>
2098 </trans-unit> 2185 </trans-unit>
2099 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 2186 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -2128,14 +2215,14 @@
2128 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 2215 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2129 <target>Data <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 2216 <target>Data <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2130 <context-group name="null"> 2217 <context-group name="null">
2131 <context context-type="linenumber">10</context> 2218 <context context-type="linenumber">11</context>
2132 </context-group> 2219 </context-group>
2133 </trans-unit> 2220 </trans-unit>
2134 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f"> 2221 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
2135 <source>Blacklist reason:</source> 2222 <source>Blacklist reason:</source>
2136 <target>Rason de la mesa en lista negra :</target> 2223 <target>Rason de la mesa en lista negra :</target>
2137 <context-group name="null"> 2224 <context-group name="null">
2138 <context context-type="linenumber">41</context> 2225 <context context-type="linenumber">43</context>
2139 </context-group> 2226 </context-group>
2140 </trans-unit> 2227 </trans-unit>
2141 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 2228 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -2194,69 +2281,6 @@
2194 <context context-type="linenumber">23</context> 2281 <context context-type="linenumber">23</context>
2195 </context-group> 2282 </context-group>
2196 </trans-unit> 2283 </trans-unit>
2197 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2198 <source>My settings</source>
2199 <target>Mos paramètres</target>
2200 <context-group name="null">
2201 <context context-type="linenumber">3</context>
2202 </context-group>
2203 </trans-unit>
2204 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2205 <source>My library</source>
2206 <target>Ma bibliotèca</target>
2207 <context-group name="null">
2208 <context context-type="linenumber">7</context>
2209 </context-group>
2210 </trans-unit>
2211 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2212 <source>My channels</source>
2213 <target>Mas cadenas</target>
2214 <context-group name="null">
2215 <context context-type="linenumber">12</context>
2216 </context-group>
2217 </trans-unit>
2218 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2219 <source>My videos</source>
2220 <target>Mas vidèos</target>
2221 <context-group name="null">
2222 <context context-type="linenumber">14</context>
2223 </context-group>
2224 </trans-unit>
2225 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2226 <source>My subscriptions</source>
2227 <target>Mos abonaments</target>
2228 <context-group name="null">
2229 <context context-type="linenumber">16</context>
2230 </context-group>
2231 </trans-unit>
2232 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
2233 <source>My imports</source>
2234 <target>Mas importacions</target>
2235 <context-group name="null">
2236 <context context-type="linenumber">18</context>
2237 </context-group>
2238 </trans-unit>
2239 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
2240 <source>Misc</source>
2241 <target>Divèrs</target>
2242 <context-group name="null">
2243 <context context-type="linenumber">24</context>
2244 </context-group>
2245 </trans-unit>
2246 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2247 <source>Muted instances</source>
2248 <target>Instàncias mudas</target>
2249 <context-group name="null">
2250 <context context-type="linenumber">2</context>
2251 </context-group>
2252 </trans-unit>
2253 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
2254 <source>Ownership changes</source>
2255 <target>Cambiaments de proprietats</target>
2256 <context-group name="null">
2257 <context context-type="linenumber">33</context>
2258 </context-group>
2259 </trans-unit>
2260 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 2284 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
2261 <source>Video quota:</source> 2285 <source>Video quota:</source>
2262 <target>Quòta vidèo :</target> 2286 <target>Quòta vidèo :</target>
@@ -2268,21 +2292,21 @@
2268 <source>Profile</source> 2292 <source>Profile</source>
2269 <target>Perfil</target> 2293 <target>Perfil</target>
2270 <context-group name="null"> 2294 <context-group name="null">
2271 <context context-type="linenumber">8</context> 2295 <context context-type="linenumber">7</context>
2272 </context-group> 2296 </context-group>
2273 </trans-unit> 2297 </trans-unit>
2274 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 2298 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
2275 <source>Video settings</source> 2299 <source>Video settings</source>
2276 <target>Paramètres vidèo</target> 2300 <target>Paramètres vidèo</target>
2277 <context-group name="null"> 2301 <context-group name="null">
2278 <context context-type="linenumber">15</context> 2302 <context context-type="linenumber">16</context>
2279 </context-group> 2303 </context-group>
2280 </trans-unit> 2304 </trans-unit>
2281 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 2305 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
2282 <source>Danger zone</source> 2306 <source>Danger zone</source>
2283 <target>Zòna perilhosa</target> 2307 <target>Zòna perilhosa</target>
2284 <context-group name="null"> 2308 <context-group name="null">
2285 <context context-type="linenumber">18</context> 2309 <context context-type="linenumber">19</context>
2286 </context-group> 2310 </context-group>
2287 </trans-unit> 2311 </trans-unit>
2288 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 2312 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -2310,13 +2334,6 @@
2310 <context context-type="linenumber">35</context> 2334 <context context-type="linenumber">35</context>
2311 </context-group> 2335 </context-group>
2312 </trans-unit> 2336 </trans-unit>
2313 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
2314 <source>Submit</source>
2315 <target>Mandar</target>
2316 <context-group name="null">
2317 <context context-type="linenumber">24</context>
2318 </context-group>
2319 </trans-unit>
2320 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 2337 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
2321 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 2338 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2322 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> vistas</target> 2339 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> vistas</target>
@@ -2475,6 +2492,13 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
2475 <context context-type="linenumber">47</context> 2492 <context context-type="linenumber">47</context>
2476 </context-group> 2493 </context-group>
2477 </trans-unit> 2494 </trans-unit>
2495 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2496 <source>Muted instances</source>
2497 <target>Instàncias mudas</target>
2498 <context-group name="null">
2499 <context context-type="linenumber">2</context>
2500 </context-group>
2501 </trans-unit>
2478 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 2502 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
2479 <source>Change password</source> 2503 <source>Change password</source>
2480 <target>Cambiar lo senhal</target> 2504 <target>Cambiar lo senhal</target>
@@ -2573,6 +2597,13 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
2573 <context context-type="linenumber">4</context> 2597 <context context-type="linenumber">4</context>
2574 </context-group> 2598 </context-group>
2575 </trans-unit> 2599 </trans-unit>
2600 <trans-unit id="847dffd493abbb2a5c71f3313f0eb730dd88a355">
2601 <source>Web</source>
2602 <target>Site web</target>
2603 <context-group name="null">
2604 <context context-type="linenumber">3</context>
2605 </context-group>
2606 </trans-unit>
2576 <trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd"> 2607 <trans-unit id="e242e3e8608a3c4a944327eb3d5c221dc6e4e3cd">
2577 <source> 2608 <source>
2578 Sorry, but we couldn't find the page you were looking for. 2609 Sorry, but we couldn't find the page you were looking for.
@@ -2680,6 +2711,13 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
2680 <context context-type="linenumber">159</context> 2711 <context context-type="linenumber">159</context>
2681 </context-group> 2712 </context-group>
2682 </trans-unit> 2713 </trans-unit>
2714 <trans-unit id="385811ab5a5c3e96e0db46c9ce1fc3147d8cd4c7">
2715 <source>Sorry, but something went wrong</source>
2716 <target>O planhèm, quicòm a trucat</target>
2717 <context-group name="null">
2718 <context context-type="linenumber">49</context>
2719 </context-group>
2720 </trans-unit>
2683 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2"> 2721 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2">
2684 <source> 2722 <source>
2685 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video. 2723 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video.
@@ -2716,14 +2754,14 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
2716 <source>Publish will be available when upload is finished</source> 2754 <source>Publish will be available when upload is finished</source>
2717 <target>La publicacion serà possibla un còp lo mandadís acabat</target> 2755 <target>La publicacion serà possibla un còp lo mandadís acabat</target>
2718 <context-group name="null"> 2756 <context-group name="null">
2719 <context context-type="linenumber">53</context> 2757 <context context-type="linenumber">58</context>
2720 </context-group> 2758 </context-group>
2721 </trans-unit> 2759 </trans-unit>
2722 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 2760 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2723 <source>Publish</source> 2761 <source>Publish</source>
2724 <target>Publicar</target> 2762 <target>Publicar</target>
2725 <context-group name="null"> 2763 <context-group name="null">
2726 <context context-type="linenumber">60</context> 2764 <context context-type="linenumber">65</context>
2727 </context-group> 2765 </context-group>
2728 </trans-unit> 2766 </trans-unit>
2729 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 2767 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -2906,14 +2944,14 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
2906 <source>Wait transcoding before publishing the video</source> 2944 <source>Wait transcoding before publishing the video</source>
2907 <target>Esperar lo transcodatge abans de publicar la vidèo</target> 2945 <target>Esperar lo transcodatge abans de publicar la vidèo</target>
2908 <context-group name="null"> 2946 <context-group name="null">
2909 <context context-type="linenumber">130</context> 2947 <context context-type="linenumber">131</context>
2910 </context-group> 2948 </context-group>
2911 </trans-unit> 2949 </trans-unit>
2912 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 2950 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2913 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 2951 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
2914 <target>Se decidissètz d’esperar pas lo transcodatge abans de publicar la vidèo, serà pas legibla fins a la fin del transcodatge.</target> 2952 <target>Se decidissètz d’esperar pas lo transcodatge abans de publicar la vidèo, serà pas legibla fins a la fin del transcodatge.</target>
2915 <context-group name="null"> 2953 <context-group name="null">
2916 <context context-type="linenumber">131</context> 2954 <context context-type="linenumber">132</context>
2917 </context-group> 2955 </context-group>
2918 </trans-unit> 2956 </trans-unit>
2919 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2957 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2927,49 +2965,49 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
2927 <source>Add another caption</source> 2965 <source>Add another caption</source>
2928 <target>Ajustar una legenda mai</target> 2966 <target>Ajustar una legenda mai</target>
2929 <context-group name="null"> 2967 <context-group name="null">
2930 <context context-type="linenumber">146</context> 2968 <context context-type="linenumber">147</context>
2931 </context-group> 2969 </context-group>
2932 </trans-unit> 2970 </trans-unit>
2933 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 2971 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2934 <source>See the subtitle file</source> 2972 <source>See the subtitle file</source>
2935 <target>Veire lo fichièr de sostítols</target> 2973 <target>Veire lo fichièr de sostítols</target>
2936 <context-group name="null"> 2974 <context-group name="null">
2937 <context context-type="linenumber">155</context> 2975 <context context-type="linenumber">156</context>
2938 </context-group> 2976 </context-group>
2939 </trans-unit> 2977 </trans-unit>
2940 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee"> 2978 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee">
2941 <source>Already uploaded ✔</source> 2979 <source>Already uploaded ✔</source>
2942 <target>Ja enviada ✔</target> 2980 <target>Ja enviada ✔</target>
2943 <context-group name="null"> 2981 <context-group name="null">
2944 <context context-type="linenumber">159</context> 2982 <context context-type="linenumber">160</context>
2945 </context-group> 2983 </context-group>
2946 </trans-unit> 2984 </trans-unit>
2947 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad"> 2985 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad">
2948 <source>Will be created on update</source> 2986 <source>Will be created on update</source>
2949 <target>Serà creada en actualizar</target> 2987 <target>Serà creada en actualizar</target>
2950 <context-group name="null"> 2988 <context-group name="null">
2951 <context context-type="linenumber">167</context> 2989 <context context-type="linenumber">168</context>
2952 </context-group> 2990 </context-group>
2953 </trans-unit> 2991 </trans-unit>
2954 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 2992 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2955 <source>Cancel create</source> 2993 <source>Cancel create</source>
2956 <target>Anullar la creacion</target> 2994 <target>Anullar la creacion</target>
2957 <context-group name="null"> 2995 <context-group name="null">
2958 <context context-type="linenumber">169</context> 2996 <context context-type="linenumber">170</context>
2959 </context-group> 2997 </context-group>
2960 </trans-unit> 2998 </trans-unit>
2961 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393"> 2999 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393">
2962 <source>Will be deleted on update</source> 3000 <source>Will be deleted on update</source>
2963 <target>Serà suprimida en actualizar</target> 3001 <target>Serà suprimida en actualizar</target>
2964 <context-group name="null"> 3002 <context-group name="null">
2965 <context context-type="linenumber">175</context> 3003 <context context-type="linenumber">176</context>
2966 </context-group> 3004 </context-group>
2967 </trans-unit> 3005 </trans-unit>
2968 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 3006 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2969 <source>Cancel deletion</source> 3007 <source>Cancel deletion</source>
2970 <target>Anullar la supression</target> 3008 <target>Anullar la supression</target>
2971 <context-group name="null"> 3009 <context-group name="null">
2972 <context context-type="linenumber">177</context> 3010 <context context-type="linenumber">178</context>
2973 </context-group> 3011 </context-group>
2974 </trans-unit> 3012 </trans-unit>
2975 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0"> 3013 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0">
@@ -2980,28 +3018,28 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
2980 Encara cap de legendas. 3018 Encara cap de legendas.
2981 </target> 3019 </target>
2982 <context-group name="null"> 3020 <context-group name="null">
2983 <context context-type="linenumber">182</context> 3021 <context context-type="linenumber">183</context>
2984 </context-group> 3022 </context-group>
2985 </trans-unit> 3023 </trans-unit>
2986 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 3024 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2987 <source>Captions</source> 3025 <source>Captions</source>
2988 <target>Legendas</target> 3026 <target>Legendas</target>
2989 <context-group name="null"> 3027 <context-group name="null">
2990 <context context-type="linenumber">139</context> 3028 <context context-type="linenumber">140</context>
2991 </context-group> 3029 </context-group>
2992 </trans-unit> 3030 </trans-unit>
2993 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 3031 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
2994 <source>Upload thumbnail</source> 3032 <source>Upload thumbnail</source>
2995 <target>Enviar una vinheta d’apercebut</target> 3033 <target>Enviar una vinheta d’apercebut</target>
2996 <context-group name="null"> 3034 <context-group name="null">
2997 <context context-type="linenumber">195</context> 3035 <context context-type="linenumber">196</context>
2998 </context-group> 3036 </context-group>
2999 </trans-unit> 3037 </trans-unit>
3000 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 3038 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
3001 <source>Upload preview</source> 3039 <source>Upload preview</source>
3002 <target>Enviar un apercebut</target> 3040 <target>Enviar un apercebut</target>
3003 <context-group name="null"> 3041 <context-group name="null">
3004 <context context-type="linenumber">202</context> 3042 <context context-type="linenumber">203</context>
3005 </context-group> 3043 </context-group>
3006 </trans-unit> 3044 </trans-unit>
3007 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 3045 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -3015,14 +3053,14 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
3015 <source>Short text to tell people how they can support you (membership platform...).</source> 3053 <source>Short text to tell people how they can support you (membership platform...).</source>
3016 <target>Pichon tèxte per explicar al monde cossí pòdon vos sosténer (plataforma pels sòcis...).</target> 3054 <target>Pichon tèxte per explicar al monde cossí pòdon vos sosténer (plataforma pels sòcis...).</target>
3017 <context-group name="null"> 3055 <context-group name="null">
3018 <context context-type="linenumber">209</context> 3056 <context context-type="linenumber">210</context>
3019 </context-group> 3057 </context-group>
3020 </trans-unit> 3058 </trans-unit>
3021 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 3059 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
3022 <source>Advanced settings</source> 3060 <source>Advanced settings</source>
3023 <target>Paramètres avançats</target> 3061 <target>Paramètres avançats</target>
3024 <context-group name="null"> 3062 <context-group name="null">
3025 <context context-type="linenumber">190</context> 3063 <context context-type="linenumber">191</context>
3026 </context-group> 3064 </context-group>
3027 </trans-unit> 3065 </trans-unit>
3028 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 3066 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -3089,17 +3127,6 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
3089 <context context-type="linenumber">3</context> 3127 <context context-type="linenumber">3</context>
3090 </context-group> 3128 </context-group>
3091 </trans-unit> 3129 </trans-unit>
3092 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
3093 <source>
3094 Cancel
3095 </source>
3096 <target>
3097 Anullar
3098 </target>
3099 <context-group name="null">
3100 <context context-type="linenumber">19</context>
3101 </context-group>
3102 </trans-unit>
3103 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 3130 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
3104 <source>Share</source> 3131 <source>Share</source>
3105 <target>Partejar</target> 3132 <target>Partejar</target>
@@ -3486,13 +3513,6 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
3486 <context context-type="linenumber">14</context> 3513 <context context-type="linenumber">14</context>
3487 </context-group> 3514 </context-group>
3488 </trans-unit> 3515 </trans-unit>
3489 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
3490 <source>Error getting about from server</source>
3491 <target>Error en recuperar las informacions de la seccion «A prepaus» del servidor</target>
3492 <context-group name="null">
3493 <context context-type="linenumber">1</context>
3494 </context-group>
3495 </trans-unit>
3496 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 3516 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
3497 <source>No description</source> 3517 <source>No description</source>
3498 <target>Cap de descripcion</target> 3518 <target>Cap de descripcion</target>
@@ -3514,13 +3534,6 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
3514 <context context-type="linenumber">1</context> 3534 <context context-type="linenumber">1</context>
3515 </context-group> 3535 </context-group>
3516 </trans-unit> 3536 </trans-unit>
3517 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
3518 <source>Error</source>
3519 <target>Error</target>
3520 <context-group name="null">
3521 <context context-type="linenumber">1</context>
3522 </context-group>
3523 </trans-unit>
3524 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6"> 3537 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
3525 <source>240p</source> 3538 <source>240p</source>
3526 <target>240p</target> 3539 <target>240p</target>
@@ -3563,13 +3576,6 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
3563 <context context-type="linenumber">1</context> 3576 <context context-type="linenumber">1</context>
3564 </context-group> 3577 </context-group>
3565 </trans-unit> 3578 </trans-unit>
3566 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
3567 <source>Success</source>
3568 <target>Succès</target>
3569 <context-group name="null">
3570 <context context-type="linenumber">1</context>
3571 </context-group>
3572 </trans-unit>
3573 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 3579 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
3574 <source>Configuration updated.</source> 3580 <source>Configuration updated.</source>
3575 <target>Configuracion actualizada.</target> 3581 <target>Configuracion actualizada.</target>
@@ -3836,6 +3842,13 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
3836 <context context-type="linenumber">1</context> 3842 <context context-type="linenumber">1</context>
3837 </context-group> 3843 </context-group>
3838 </trans-unit> 3844 </trans-unit>
3845 <trans-unit id="910ed85f550272401b134a40d019ab3359fe883f">
3846 <source>Set Email as Verified</source>
3847 <target>Passar l’adreça coma verificada</target>
3848 <context-group name="null">
3849 <context context-type="linenumber">1</context>
3850 </context-group>
3851 </trans-unit>
3839 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf"> 3852 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf">
3840 <source>You cannot ban root.</source> 3853 <source>You cannot ban root.</source>
3841 <target>Podètz pas fòrabandir lo root.</target> 3854 <target>Podètz pas fòrabandir lo root.</target>
@@ -3878,6 +3891,13 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
3878 <context context-type="linenumber">1</context> 3891 <context context-type="linenumber">1</context>
3879 </context-group> 3892 </context-group>
3880 </trans-unit> 3893 </trans-unit>
3894 <trans-unit id="f4a8f2ef1fbfc19e1e049e69f63c40063c0d0650">
3895 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users email set as verified.</source>
3896 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> adreças d’utilizaires passadas coma verificadas.</target>
3897 <context-group name="null">
3898 <context context-type="linenumber">1</context>
3899 </context-group>
3900 </trans-unit>
3881 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de"> 3901 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de">
3882 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source> 3902 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source>
3883 <target>Compte <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> pas mai mut.</target> 3903 <target>Compte <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> pas mai mut.</target>
@@ -3941,6 +3961,13 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
3941 <context context-type="linenumber">1</context> 3961 <context context-type="linenumber">1</context>
3942 </context-group> 3962 </context-group>
3943 </trans-unit> 3963 </trans-unit>
3964 <trans-unit id="a0f04081717f5f00c0a2c723903c3a2d4c296401">
3965 <source>Preferences saved</source>
3966 <target>Preferéncias salvagardadas</target>
3967 <context-group name="null">
3968 <context context-type="linenumber">1</context>
3969 </context-group>
3970 </trans-unit>
3944 <trans-unit id="db4ff52375f6a25ad0472e92754c8c265ae47c6b"> 3971 <trans-unit id="db4ff52375f6a25ad0472e92754c8c265ae47c6b">
3945 <source>Profile updated.</source> 3972 <source>Profile updated.</source>
3946 <target>Perfil actualizat</target> 3973 <target>Perfil actualizat</target>
@@ -3990,23 +4017,16 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
3990 <context context-type="linenumber">1</context> 4017 <context context-type="linenumber">1</context>
3991 </context-group> 4018 </context-group>
3992 </trans-unit> 4019 </trans-unit>
3993 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 4020 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
3994 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 4021 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
3995 <target>Volètz vertadièrament suprimir <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> ? Aquò suprimarà tanben totas las vidèos enviadas a la cadena.</target> 4022 <target>Cadena vidèo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> suprimida.</target>
3996 <context-group name="null">
3997 <context context-type="linenumber">1</context>
3998 </context-group>
3999 </trans-unit>
4000 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
4001 <source>Please type the name of the video channel to confirm</source>
4002 <target>Tornatz picar lo nom de la cadena per confirmar</target>
4003 <context-group name="null"> 4023 <context-group name="null">
4004 <context context-type="linenumber">1</context> 4024 <context context-type="linenumber">1</context>
4005 </context-group> 4025 </context-group>
4006 </trans-unit> 4026 </trans-unit>
4007 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 4027 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
4008 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 4028 <source>My videos</source>
4009 <target>Cadena vidèo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> suprimida.</target> 4029 <target>Mas vidèos</target>
4010 <context-group name="null"> 4030 <context-group name="null">
4011 <context context-type="linenumber">1</context> 4031 <context context-type="linenumber">1</context>
4012 </context-group> 4032 </context-group>
@@ -4081,16 +4101,58 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
4081 <context context-type="linenumber">1</context> 4101 <context context-type="linenumber">1</context>
4082 </context-group> 4102 </context-group>
4083 </trans-unit> 4103 </trans-unit>
4084 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 4104 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
4085 <source>Channels</source> 4105 <source>My library</source>
4086 <target>Cadenas</target> 4106 <target>Ma bibliotèca</target>
4087 <context-group name="null"> 4107 <context-group name="null">
4088 <context context-type="linenumber">1</context> 4108 <context context-type="linenumber">1</context>
4089 </context-group> 4109 </context-group>
4090 </trans-unit> 4110 </trans-unit>
4091 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d"> 4111 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
4092 <source>Video imports</source> 4112 <source>My channels</source>
4093 <target>Imports vidèo</target> 4113 <target>Mas cadenas</target>
4114 <context-group name="null">
4115 <context context-type="linenumber">1</context>
4116 </context-group>
4117 </trans-unit>
4118 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
4119 <source>My subscriptions</source>
4120 <target>Mos abonaments</target>
4121 <context-group name="null">
4122 <context context-type="linenumber">1</context>
4123 </context-group>
4124 </trans-unit>
4125 <trans-unit id="4f953496ca94b4f83af049ff715172df2729fb79">
4126 <source>My history</source>
4127 <target>Mon istoric</target>
4128 <context-group name="null">
4129 <context context-type="linenumber">1</context>
4130 </context-group>
4131 </trans-unit>
4132 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
4133 <source>Misc</source>
4134 <target>Divèrs</target>
4135 <context-group name="null">
4136 <context context-type="linenumber">1</context>
4137 </context-group>
4138 </trans-unit>
4139 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
4140 <source>Ownership changes</source>
4141 <target>Cambiaments de proprietats</target>
4142 <context-group name="null">
4143 <context context-type="linenumber">1</context>
4144 </context-group>
4145 </trans-unit>
4146 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
4147 <source>My settings</source>
4148 <target>Mos paramètres</target>
4149 <context-group name="null">
4150 <context context-type="linenumber">1</context>
4151 </context-group>
4152 </trans-unit>
4153 <trans-unit id="0e2434e7d84145c4e8a930ccc4c26c3cb2887e0d">
4154 <source>My notifications</source>
4155 <target>Mas notificacions</target>
4094 <context-group name="null"> 4156 <context-group name="null">
4095 <context context-type="linenumber">1</context> 4157 <context context-type="linenumber">1</context>
4096 </context-group> 4158 </context-group>
@@ -4216,6 +4278,13 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
4216 <context context-type="linenumber">1</context> 4278 <context context-type="linenumber">1</context>
4217 </context-group> 4279 </context-group>
4218 </trans-unit> 4280 </trans-unit>
4281 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
4282 <source>Error</source>
4283 <target>Error</target>
4284 <context-group name="null">
4285 <context context-type="linenumber">1</context>
4286 </context-group>
4287 </trans-unit>
4219 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 4288 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
4220 <source>You need to reconnect.</source> 4289 <source>You need to reconnect.</source>
4221 <target>Vos cal vos reconnectar.</target> 4290 <target>Vos cal vos reconnectar.</target>
@@ -4237,6 +4306,20 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
4237 <context context-type="linenumber">1</context> 4306 <context context-type="linenumber">1</context>
4238 </context-group> 4307 </context-group>
4239 </trans-unit> 4308 </trans-unit>
4309 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4310 <source>Info</source>
4311 <target>Info</target>
4312 <context-group name="null">
4313 <context context-type="linenumber">1</context>
4314 </context-group>
4315 </trans-unit>
4316 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
4317 <source>Success</source>
4318 <target>Succès</target>
4319 <context-group name="null">
4320 <context context-type="linenumber">1</context>
4321 </context-group>
4322 </trans-unit>
4240 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 4323 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
4241 <source>Incorrect username or password.</source> 4324 <source>Incorrect username or password.</source>
4242 <target>Nom d’utilizaire o senhal incorrècte.</target> 4325 <target>Nom d’utilizaire o senhal incorrècte.</target>
@@ -4454,58 +4537,58 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
4454 <context context-type="linenumber">1</context> 4537 <context context-type="linenumber">1</context>
4455 </context-group> 4538 </context-group>
4456 </trans-unit> 4539 </trans-unit>
4457 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 4540 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4458 <source>Username is required.</source> 4541 <source>Email is required.</source>
4459 <target>Lo nom d’utilizaire es requesit.</target> 4542 <target>L’adreça electronica es requesida.</target>
4460 <context-group name="null"> 4543 <context-group name="null">
4461 <context context-type="linenumber">1</context> 4544 <context context-type="linenumber">1</context>
4462 </context-group> 4545 </context-group>
4463 </trans-unit> 4546 </trans-unit>
4464 <trans-unit id="4eb39d69b74d7a56652ec84fa6826994ee26c0e5"> 4547 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4465 <source>Password is required.</source> 4548 <source>Email must be valid.</source>
4466 <target>Lo senhal es requesit.</target> 4549 <target>L’adreça electronica deu èsser valida.</target>
4467 <context-group name="null"> 4550 <context-group name="null">
4468 <context context-type="linenumber">1</context> 4551 <context context-type="linenumber">1</context>
4469 </context-group> 4552 </context-group>
4470 </trans-unit> 4553 </trans-unit>
4471 <trans-unit id="c90872a06666a51c2957c4b29724e68df5c67154"> 4554 <trans-unit id="ac451f128840b34804ea69c820dc3566f476fb33">
4472 <source>Confirmation of the password is required.</source> 4555 <source>Your name is required.</source>
4473 <target>La confirmacion del senhal es requesida.</target> 4556 <target>Vòstre nom es requesit</target>
4474 <context-group name="null"> 4557 <context-group name="null">
4475 <context context-type="linenumber">1</context> 4558 <context context-type="linenumber">1</context>
4476 </context-group> 4559 </context-group>
4477 </trans-unit> 4560 </trans-unit>
4478 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea"> 4561 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
4479 <source>Username must be at least 3 characters long.</source> 4562 <source>Username is required.</source>
4480 <target>Lo nom d’utilizaire deu conténer almens 3 caractèrs.</target> 4563 <target>Lo nom d’utilizaire es requesit.</target>
4481 <context-group name="null"> 4564 <context-group name="null">
4482 <context context-type="linenumber">1</context> 4565 <context context-type="linenumber">1</context>
4483 </context-group> 4566 </context-group>
4484 </trans-unit> 4567 </trans-unit>
4485 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef"> 4568 <trans-unit id="4eb39d69b74d7a56652ec84fa6826994ee26c0e5">
4486 <source>Username cannot be more than 20 characters long.</source> 4569 <source>Password is required.</source>
4487 <target>Lo nom d’utilizaire pòt pas conténer mai de 20 caractèrs.</target> 4570 <target>Lo senhal es requesit.</target>
4488 <context-group name="null"> 4571 <context-group name="null">
4489 <context context-type="linenumber">1</context> 4572 <context context-type="linenumber">1</context>
4490 </context-group> 4573 </context-group>
4491 </trans-unit> 4574 </trans-unit>
4492 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9"> 4575 <trans-unit id="c90872a06666a51c2957c4b29724e68df5c67154">
4493 <source>Username should be only lowercase alphanumeric characters.</source> 4576 <source>Confirmation of the password is required.</source>
4494 <target>Lo nom d’utilizaire deu èsser alfanumeric e en minuscula. </target> 4577 <target>La confirmacion del senhal es requesida.</target>
4495 <context-group name="null"> 4578 <context-group name="null">
4496 <context context-type="linenumber">1</context> 4579 <context context-type="linenumber">1</context>
4497 </context-group> 4580 </context-group>
4498 </trans-unit> 4581 </trans-unit>
4499 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0"> 4582 <trans-unit id="6330d25a3bc6f55dfd5177da6e681d1d3b1a2b1a">
4500 <source>Email is required.</source> 4583 <source>Username must be at least 1 character long.</source>
4501 <target>L’adreça electronica es requesida.</target> 4584 <target>Lo nom d’utilizaire deu almens conténer 1 caractèr.</target>
4502 <context-group name="null"> 4585 <context-group name="null">
4503 <context context-type="linenumber">1</context> 4586 <context context-type="linenumber">1</context>
4504 </context-group> 4587 </context-group>
4505 </trans-unit> 4588 </trans-unit>
4506 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1"> 4589 <trans-unit id="aaaf3d00c35f809eebc7fd68a3f7b8b0230b197a">
4507 <source>Email must be valid.</source> 4590 <source>Username cannot be more than 50 characters long.</source>
4508 <target>L’adreça electronica deu èsser valida.</target> 4591 <target>Lo nom d’utilizaire pòt pas conténer mai de 50 caractèrs.</target>
4509 <context-group name="null"> 4592 <context-group name="null">
4510 <context context-type="linenumber">1</context> 4593 <context context-type="linenumber">1</context>
4511 </context-group> 4594 </context-group>
@@ -4573,16 +4656,16 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
4573 <context context-type="linenumber">1</context> 4656 <context context-type="linenumber">1</context>
4574 </context-group> 4657 </context-group>
4575 </trans-unit> 4658 </trans-unit>
4576 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674"> 4659 <trans-unit id="085b2d6f79819a72a2b56cada4ef5085ba51d90c">
4577 <source>Display name must be at least 3 characters long.</source> 4660 <source>Display name must be at least 1 character long.</source>
4578 <target>L’escais-nom deu almens conténer 3 caractèrs.</target> 4661 <target>Lo nom public deu almens conténer 1 caractèr.</target>
4579 <context-group name="null"> 4662 <context-group name="null">
4580 <context context-type="linenumber">1</context> 4663 <context context-type="linenumber">1</context>
4581 </context-group> 4664 </context-group>
4582 </trans-unit> 4665 </trans-unit>
4583 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9"> 4666 <trans-unit id="5a920575b8e1067f5b11c66a4a36d3ced87756f1">
4584 <source>Display name cannot be more than 120 characters long.</source> 4667 <source>Display name cannot be more than 50 characters long.</source>
4585 <target>L’escais-nom pòt pas conténer mai de 120 caractèrs.</target> 4668 <target>Lo nom public pòt pas conténer mai de 50 caractèrs.</target>
4586 <context-group name="null"> 4669 <context-group name="null">
4587 <context context-type="linenumber">1</context> 4670 <context context-type="linenumber">1</context>
4588 </context-group> 4671 </context-group>
@@ -4636,13 +4719,6 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
4636 <context context-type="linenumber">1</context> 4719 <context context-type="linenumber">1</context>
4637 </context-group> 4720 </context-group>
4638 </trans-unit> 4721 </trans-unit>
4639 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
4640 <source>Report reason cannot be more than 300 characters long.</source>
4641 <target>La rason del senhalament pòt pas conténer mai de 300 caractèrs.</target>
4642 <context-group name="null">
4643 <context context-type="linenumber">1</context>
4644 </context-group>
4645 </trans-unit>
4646 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118"> 4722 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
4647 <source>Moderation comment is required.</source> 4723 <source>Moderation comment is required.</source>
4648 <target>Lo comentari de moderacion es requesit.</target> 4724 <target>Lo comentari de moderacion es requesit.</target>
@@ -4657,13 +4733,6 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
4657 <context context-type="linenumber">1</context> 4733 <context context-type="linenumber">1</context>
4658 </context-group> 4734 </context-group>
4659 </trans-unit> 4735 </trans-unit>
4660 <trans-unit id="89d0b662dde0871cf17244e79b2cb62cd517e44f">
4661 <source>Moderation comment cannot be more than 300 characters long.</source>
4662 <target>Lo comentari de moderacion pòt pas conténer mai de 300 caractèrs.</target>
4663 <context-group name="null">
4664 <context context-type="linenumber">1</context>
4665 </context-group>
4666 </trans-unit>
4667 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6"> 4736 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
4668 <source>The channel is required.</source> 4737 <source>The channel is required.</source>
4669 <target>La cadena es requesida.</target> 4738 <target>La cadena es requesida.</target>
@@ -4720,23 +4789,16 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
4720 <context context-type="linenumber">1</context> 4789 <context context-type="linenumber">1</context>
4721 </context-group> 4790 </context-group>
4722 </trans-unit> 4791 </trans-unit>
4723 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069"> 4792 <trans-unit id="b8b59b6284a14fc71268cf722ed98c62c5af4a76">
4724 <source>Name must be at least 3 characters long.</source> 4793 <source>Name must be at least 1 character long.</source>
4725 <target>Lo nom deu almens conténer 3 caractèrs.</target> 4794 <target>Lo nom deu almens conténer 1 caractèr.</target>
4726 <context-group name="null">
4727 <context context-type="linenumber">1</context>
4728 </context-group>
4729 </trans-unit>
4730 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482">
4731 <source>Name cannot be more than 20 characters long.</source>
4732 <target>Lo nom pòt pas conténer mai de 20 caractèrs.</target>
4733 <context-group name="null"> 4795 <context-group name="null">
4734 <context context-type="linenumber">1</context> 4796 <context context-type="linenumber">1</context>
4735 </context-group> 4797 </context-group>
4736 </trans-unit> 4798 </trans-unit>
4737 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9"> 4799 <trans-unit id="e14cd37d29f13eac7384c339e4f1df58d96e4e3d">
4738 <source>Name should be only lowercase alphanumeric characters.</source> 4800 <source>Name cannot be more than 50 characters long.</source>
4739 <target>Lo nom deu èsser alfanumeric e en minuscula</target> 4801 <target>Lo nom pòt pas conténer mai de 50 caractèrs.</target>
4740 <context-group name="null"> 4802 <context-group name="null">
4741 <context context-type="linenumber">1</context> 4803 <context context-type="linenumber">1</context>
4742 </context-group> 4804 </context-group>
@@ -5420,6 +5482,13 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
5420 <context context-type="linenumber">1</context> 5482 <context context-type="linenumber">1</context>
5421 </context-group> 5483 </context-group>
5422 </trans-unit> 5484 </trans-unit>
5485 <trans-unit id="534202c90c6dcadd2989fc72c5030d5483e26096">
5486 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> email set as verified</source>
5487 <target>L’adreça a <x id="INTERPOLATION" equiv-text="{{username}}"/> es passada coma verificada</target>
5488 <context-group name="null">
5489 <context context-type="linenumber">1</context>
5490 </context-group>
5491 </trans-unit>
5423 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249"> 5492 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249">
5424 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source> 5493 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source>
5425 <target>Lo compte <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> es mut.</target> 5494 <target>Lo compte <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> es mut.</target>
@@ -5546,13 +5615,6 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
5546 <context context-type="linenumber">1</context> 5615 <context context-type="linenumber">1</context>
5547 </context-group> 5616 </context-group>
5548 </trans-unit> 5617 </trans-unit>
5549 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5550 <source>Subscribed</source>
5551 <target>Abonat</target>
5552 <context-group name="null">
5553 <context context-type="linenumber">1</context>
5554 </context-group>
5555 </trans-unit>
5556 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded"> 5618 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
5557 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source> 5619 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
5558 <target>S’abonèt a <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target> 5620 <target>S’abonèt a <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
@@ -5560,9 +5622,9 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
5560 <context context-type="linenumber">1</context> 5622 <context context-type="linenumber">1</context>
5561 </context-group> 5623 </context-group>
5562 </trans-unit> 5624 </trans-unit>
5563 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471"> 5625 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5564 <source>Unsubscribed</source> 5626 <source>Subscribed</source>
5565 <target>Pas mai abonat</target> 5627 <target>Abonat</target>
5566 <context-group name="null"> 5628 <context-group name="null">
5567 <context context-type="linenumber">1</context> 5629 <context context-type="linenumber">1</context>
5568 </context-group> 5630 </context-group>
@@ -5574,6 +5636,13 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
5574 <context context-type="linenumber">1</context> 5636 <context context-type="linenumber">1</context>
5575 </context-group> 5637 </context-group>
5576 </trans-unit> 5638 </trans-unit>
5639 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
5640 <source>Unsubscribed</source>
5641 <target>Pas mai abonat</target>
5642 <context-group name="null">
5643 <context context-type="linenumber">1</context>
5644 </context-group>
5645 </trans-unit>
5577 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf"> 5646 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf">
5578 <source>Moderator</source> 5647 <source>Moderator</source>
5579 <target>Moderator</target> 5648 <target>Moderator</target>
@@ -5602,6 +5671,20 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
5602 <context context-type="linenumber">1</context> 5671 <context context-type="linenumber">1</context>
5603 </context-group> 5672 </context-group>
5604 </trans-unit> 5673 </trans-unit>
5674 <trans-unit id="21565881ad1dff3c98738b9535b3515cec140609">
5675 <source>Welcome! Now please check your emails to verify your account and complete signup.</source>
5676 <target>La benvenguda ! Ara volgatz ben verificar vòstres corrièls per confirmar vòstre compte e acabar l’inscripcion.</target>
5677 <context-group name="null">
5678 <context context-type="linenumber">1</context>
5679 </context-group>
5680 </trans-unit>
5681 <trans-unit id="14200e26888a07633c0f177020dce8f3ec7311a6">
5682 <source>You are now logged in as <x id="INTERPOLATION" equiv-text="{{username}}"/>!</source>
5683 <target>Sètz ara connectat coma <x id="INTERPOLATION" equiv-text="{{username}}"/> !</target>
5684 <context-group name="null">
5685 <context context-type="linenumber">1</context>
5686 </context-group>
5687 </trans-unit>
5605 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb"> 5688 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb">
5606 <source>Video to import updated.</source> 5689 <source>Video to import updated.</source>
5607 <target>Vidèo d’importar actualizada</target> 5690 <target>Vidèo d’importar actualizada</target>
@@ -5630,13 +5713,6 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
5630 <context context-type="linenumber">1</context> 5713 <context context-type="linenumber">1</context>
5631 </context-group> 5714 </context-group>
5632 </trans-unit> 5715 </trans-unit>
5633 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
5634 <source>Info</source>
5635 <target>Info</target>
5636 <context-group name="null">
5637 <context context-type="linenumber">1</context>
5638 </context-group>
5639 </trans-unit>
5640 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 5716 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
5641 <source>Upload cancelled</source> 5717 <source>Upload cancelled</source>
5642 <target>Mandadís anullat</target> 5718 <target>Mandadís anullat</target>
@@ -5644,13 +5720,6 @@ Quand enviaretz una vidèo dins aquesta cadena, lo camp vidèo sosten serà auto
5644 <context context-type="linenumber">1</context> 5720 <context context-type="linenumber">1</context>
5645 </context-group> 5721 </context-group>
5646 </trans-unit> 5722 </trans-unit>
5647 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa">
5648 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
5649 <target>O planhèm mas PeerTube pòt pas gerir de vidèos de mai de 8 Go</target>
5650 <context-group name="null">
5651 <context context-type="linenumber">1</context>
5652 </context-group>
5653 </trans-unit>
5654 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee"> 5723 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
5655 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source> 5724 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
5656 <target>Vòstre quòta de vidèo es excedit amb aquesta vidèo (talha vidèo : <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, utilizat : <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quòta : <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target> 5725 <target>Vòstre quòta de vidèo es excedit amb aquesta vidèo (talha vidèo : <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, utilizat : <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quòta : <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
diff --git a/client/src/locale/target/angular_pl_PL.xml b/client/src/locale/target/angular_pl_PL.xml
index fd6e03469..6d5a06e53 100644
--- a/client/src/locale/target/angular_pl_PL.xml
+++ b/client/src/locale/target/angular_pl_PL.xml
@@ -342,7 +342,7 @@
342 <source>Password</source> 342 <source>Password</source>
343 <target>Hasło</target> 343 <target>Hasło</target>
344 <context-group name="null"> 344 <context-group name="null">
345 <context context-type="linenumber">12</context> 345 <context context-type="linenumber">13</context>
346 </context-group> 346 </context-group>
347 </trans-unit> 347 </trans-unit>
348 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 348 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -356,7 +356,7 @@
356 <source>Login</source> 356 <source>Login</source>
357 <target>Zaloguj siÄ™</target> 357 <target>Zaloguj siÄ™</target>
358 <context-group name="null"> 358 <context-group name="null">
359 <context context-type="linenumber">38</context> 359 <context context-type="linenumber">36</context>
360 </context-group> 360 </context-group>
361 </trans-unit> 361 </trans-unit>
362 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 362 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -384,7 +384,7 @@
384 <source>Send me an email to reset my password</source> 384 <source>Send me an email to reset my password</source>
385 <target>Wyślij mi wiadomość e-mail przywracającą hasło</target> 385 <target>Wyślij mi wiadomość e-mail przywracającą hasło</target>
386 <context-group name="null"> 386 <context-group name="null">
387 <context context-type="linenumber">75</context> 387 <context context-type="linenumber">80</context>
388 </context-group> 388 </context-group>
389 </trans-unit> 389 </trans-unit>
390 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 390 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -448,7 +448,7 @@
448 <source>Signup</source> 448 <source>Signup</source>
449 <target>Zarejestruj siÄ™</target> 449 <target>Zarejestruj siÄ™</target>
450 <context-group name="null"> 450 <context-group name="null">
451 <context context-type="linenumber">88</context> 451 <context context-type="linenumber">78</context>
452 </context-group> 452 </context-group>
453 </trans-unit> 453 </trans-unit>
454 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a"> 454 <trans-unit id="9167c6d3c4c3b74373cf1e90997e4966844ded1a">
@@ -498,7 +498,7 @@
498 <source>Change the language</source> 498 <source>Change the language</source>
499 <target>Zmień język</target> 499 <target>Zmień język</target>
500 <context-group name="null"> 500 <context-group name="null">
501 <context context-type="linenumber">88</context> 501 <context context-type="linenumber">86</context>
502 </context-group> 502 </context-group>
503 </trans-unit> 503 </trans-unit>
504 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 504 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -509,7 +509,7 @@
509 Mój profil publiczny 509 Mój profil publiczny
510 </target> 510 </target>
511 <context-group name="null"> 511 <context-group name="null">
512 <context context-type="linenumber">18</context> 512 <context context-type="linenumber">16</context>
513 </context-group> 513 </context-group>
514 </trans-unit> 514 </trans-unit>
515 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 515 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -520,7 +520,7 @@
520 Moje konto 520 Moje konto
521 </target> 521 </target>
522 <context-group name="null"> 522 <context-group name="null">
523 <context context-type="linenumber">22</context> 523 <context context-type="linenumber">20</context>
524 </context-group> 524 </context-group>
525 </trans-unit> 525 </trans-unit>
526 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 526 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -531,7 +531,7 @@
531 Moje filmy 531 Moje filmy
532 </target> 532 </target>
533 <context-group name="null"> 533 <context-group name="null">
534 <context context-type="linenumber">26</context> 534 <context context-type="linenumber">24</context>
535 </context-group> 535 </context-group>
536 </trans-unit> 536 </trans-unit>
537 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 537 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -542,14 +542,14 @@
542 Wyloguj siÄ™ 542 Wyloguj siÄ™
543 </target> 543 </target>
544 <context-group name="null"> 544 <context-group name="null">
545 <context context-type="linenumber">30</context> 545 <context context-type="linenumber">28</context>
546 </context-group> 546 </context-group>
547 </trans-unit> 547 </trans-unit>
548 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 548 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
549 <source>Create an account</source> 549 <source>Create an account</source>
550 <target>Utwórz konto</target> 550 <target>Utwórz konto</target>
551 <context-group name="null"> 551 <context-group name="null">
552 <context context-type="linenumber">39</context> 552 <context context-type="linenumber">37</context>
553 </context-group> 553 </context-group>
554 </trans-unit> 554 </trans-unit>
555 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 555 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -563,49 +563,49 @@
563 <source>Subscriptions</source> 563 <source>Subscriptions</source>
564 <target>Subskrybcje</target> 564 <target>Subskrybcje</target>
565 <context-group name="null"> 565 <context-group name="null">
566 <context context-type="linenumber">47</context> 566 <context context-type="linenumber">45</context>
567 </context-group> 567 </context-group>
568 </trans-unit> 568 </trans-unit>
569 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 569 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
570 <source>Overview</source> 570 <source>Overview</source>
571 <target>PrzeglÄ…d</target> 571 <target>PrzeglÄ…d</target>
572 <context-group name="null"> 572 <context-group name="null">
573 <context context-type="linenumber">52</context> 573 <context context-type="linenumber">50</context>
574 </context-group> 574 </context-group>
575 </trans-unit> 575 </trans-unit>
576 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 576 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
577 <source>Trending</source> 577 <source>Trending</source>
578 <target>Na czasie</target> 578 <target>Na czasie</target>
579 <context-group name="null"> 579 <context-group name="null">
580 <context context-type="linenumber">57</context> 580 <context context-type="linenumber">55</context>
581 </context-group> 581 </context-group>
582 </trans-unit> 582 </trans-unit>
583 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 583 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
584 <source>Recently added</source> 584 <source>Recently added</source>
585 <target>Ostatnio dodane</target> 585 <target>Ostatnio dodane</target>
586 <context-group name="null"> 586 <context-group name="null">
587 <context context-type="linenumber">62</context> 587 <context context-type="linenumber">60</context>
588 </context-group> 588 </context-group>
589 </trans-unit> 589 </trans-unit>
590 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 590 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
591 <source>Local</source> 591 <source>Local</source>
592 <target>Lokalne</target> 592 <target>Lokalne</target>
593 <context-group name="null"> 593 <context-group name="null">
594 <context context-type="linenumber">67</context> 594 <context context-type="linenumber">65</context>
595 </context-group> 595 </context-group>
596 </trans-unit> 596 </trans-unit>
597 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 597 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
598 <source>More</source> 598 <source>More</source>
599 <target>Więcej</target> 599 <target>Więcej</target>
600 <context-group name="null"> 600 <context-group name="null">
601 <context context-type="linenumber">72</context> 601 <context context-type="linenumber">70</context>
602 </context-group> 602 </context-group>
603 </trans-unit> 603 </trans-unit>
604 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 604 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
605 <source>Administration</source> 605 <source>Administration</source>
606 <target>Administracja</target> 606 <target>Administracja</target>
607 <context-group name="null"> 607 <context-group name="null">
608 <context context-type="linenumber">76</context> 608 <context context-type="linenumber">74</context>
609 </context-group> 609 </context-group>
610 </trans-unit> 610 </trans-unit>
611 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 611 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -619,7 +619,7 @@
619 <source>Toggle dark interface</source> 619 <source>Toggle dark interface</source>
620 <target>Przełącz ciemny interfejs</target> 620 <target>Przełącz ciemny interfejs</target>
621 <context-group name="null"> 621 <context-group name="null">
622 <context context-type="linenumber">94</context> 622 <context context-type="linenumber">92</context>
623 </context-group> 623 </context-group>
624 </trans-unit> 624 </trans-unit>
625 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 625 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -724,7 +724,7 @@
724 <source>No results.</source> 724 <source>No results.</source>
725 <target>Brak wyników.</target> 725 <target>Brak wyników.</target>
726 <context-group name="null"> 726 <context-group name="null">
727 <context context-type="linenumber">17</context> 727 <context context-type="linenumber">20</context>
728 </context-group> 728 </context-group>
729 </trans-unit> 729 </trans-unit>
730 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 730 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -771,15 +771,22 @@
771 <context context-type="linenumber">7</context> 771 <context context-type="linenumber">7</context>
772 </context-group> 772 </context-group>
773 </trans-unit> 773 </trans-unit>
774 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 774 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
775 <source> 775 <source>
776 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 776 Cancel
777</source> 777 </source>
778 <target> 778 <target>
779 O instancji <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> 779 Anuluj
780</target> 780 </target>
781 <context-group name="null"> 781 <context-group name="null">
782 <context context-type="linenumber">1</context> 782 <context context-type="linenumber">26</context>
783 </context-group>
784 </trans-unit>
785 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
786 <source>Submit</source>
787 <target>Wyślij</target>
788 <context-group name="null">
789 <context context-type="linenumber">31</context>
783 </context-group> 790 </context-group>
784 </trans-unit> 791 </trans-unit>
785 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 792 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -793,47 +800,14 @@
793 <source>Terms</source> 800 <source>Terms</source>
794 <target>Zasady</target> 801 <target>Zasady</target>
795 <context-group name="null"> 802 <context-group name="null">
796 <context context-type="linenumber">44</context> 803 <context context-type="linenumber">39</context>
797 </context-group> 804 </context-group>
798 </trans-unit> 805 </trans-unit>
799 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 806 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
800 <source>User registration is allowed and</source> 807 <source>User registration is allowed and</source>
801 <target>Rejestracja użytkowników jest dozwolona i</target> 808 <target>Rejestracja użytkowników jest dozwolona i</target>
802 <context-group name="null"> 809 <context-group name="null">
803 <context context-type="linenumber">25</context> 810 <context context-type="linenumber">29</context>
804 </context-group>
805 </trans-unit>
806 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
807 <source>
808 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
809 </source>
810 <target>
811 ta instancja oferuje podstawową powierzchnię <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> na filmy swoich użytkowników.
812 </target>
813 <context-group name="null">
814 <context context-type="linenumber">27</context>
815 </context-group>
816 </trans-unit>
817 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
818 <source>
819 this instance provides unlimited space for the videos of its users.
820 </source>
821 <target>
822 ta instancja oferuje nieograniczoną powierzchnię na filmy dla swoich użytkowników.
823 </target>
824 <context-group name="null">
825 <context context-type="linenumber">31</context>
826 </context-group>
827 </trans-unit>
828 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
829 <source>
830 User registration is currently not allowed.
831 </source>
832 <target>
833 Rejestracja użytkowników nie jest obecnie dozwolona.
834 </target>
835 <context-group name="null">
836 <context context-type="linenumber">36</context>
837 </context-group> 811 </context-group>
838 </trans-unit> 812 </trans-unit>
839 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 813 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1118,47 +1092,47 @@
1118 <source>Short description</source> 1092 <source>Short description</source>
1119 <target>Krótki opis</target> 1093 <target>Krótki opis</target>
1120 <context-group name="null"> 1094 <context-group name="null">
1121 <context context-type="linenumber">22</context> 1095 <context context-type="linenumber">21</context>
1122 </context-group> 1096 </context-group>
1123 </trans-unit> 1097 </trans-unit>
1124 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1098 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1125 <source>Default client route</source><target>Default client route</target><context-group name="null"> 1099 <source>Default client route</source><target>Default client route</target><context-group name="null">
1126 <context context-type="linenumber">55</context> 1100 <context context-type="linenumber">48</context>
1127 </context-group> 1101 </context-group>
1128 </trans-unit> 1102 </trans-unit>
1129 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1103 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1130 <source>Videos Overview</source> 1104 <source>Videos Overview</source>
1131 <target>Przegląd Filmów</target> 1105 <target>Przegląd Filmów</target>
1132 <context-group name="null"> 1106 <context-group name="null">
1133 <context context-type="linenumber">58</context> 1107 <context context-type="linenumber">51</context>
1134 </context-group> 1108 </context-group>
1135 </trans-unit> 1109 </trans-unit>
1136 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1110 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1137 <source>Videos Trending</source> 1111 <source>Videos Trending</source>
1138 <target>Filmy na czasie</target> 1112 <target>Filmy na czasie</target>
1139 <context-group name="null"> 1113 <context-group name="null">
1140 <context context-type="linenumber">59</context> 1114 <context context-type="linenumber">52</context>
1141 </context-group> 1115 </context-group>
1142 </trans-unit> 1116 </trans-unit>
1143 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1117 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1144 <source>Videos Recently Added</source> 1118 <source>Videos Recently Added</source>
1145 <target>Ostatnio dodane filmy</target> 1119 <target>Ostatnio dodane filmy</target>
1146 <context-group name="null"> 1120 <context-group name="null">
1147 <context context-type="linenumber">60</context> 1121 <context context-type="linenumber">53</context>
1148 </context-group> 1122 </context-group>
1149 </trans-unit> 1123 </trans-unit>
1150 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1124 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1151 <source>Local videos</source> 1125 <source>Local videos</source>
1152 <target>Lokalne filmy</target> 1126 <target>Lokalne filmy</target>
1153 <context-group name="null"> 1127 <context-group name="null">
1154 <context context-type="linenumber">61</context> 1128 <context context-type="linenumber">54</context>
1155 </context-group> 1129 </context-group>
1156 </trans-unit> 1130 </trans-unit>
1157 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1131 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1158 <source>Policy on videos containing sensitive content</source> 1132 <source>Policy on videos containing sensitive content</source>
1159 <target>Polityka dotycząca filmów zawierających wrażliwą zawartość</target> 1133 <target>Polityka dotycząca filmów zawierających wrażliwą zawartość</target>
1160 <context-group name="null"> 1134 <context-group name="null">
1161 <context context-type="linenumber">70</context> 1135 <context context-type="linenumber">61</context>
1162 </context-group> 1136 </context-group>
1163 </trans-unit> 1137 </trans-unit>
1164 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1138 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1193,23 +1167,44 @@
1193 <source>Signup enabled</source> 1167 <source>Signup enabled</source>
1194 <target>Wymagana rejestracja</target> 1168 <target>Wymagana rejestracja</target>
1195 <context-group name="null"> 1169 <context-group name="null">
1196 <context context-type="linenumber">93</context> 1170 <context context-type="linenumber">84</context>
1197 </context-group> 1171 </context-group>
1198 </trans-unit> 1172 </trans-unit>
1199 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1173 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1200 <source>Signup requires email verification</source> 1174 <source>Signup requires email verification</source>
1201 <target>Rejestracja wymaga weryfikacji emaila</target> 1175 <target>Rejestracja wymaga weryfikacji emaila</target>
1202 <context-group name="null"> 1176 <context-group name="null">
1203 <context context-type="linenumber">100</context> 1177 <context context-type="linenumber">91</context>
1204 </context-group> 1178 </context-group>
1205 </trans-unit> 1179 </trans-unit>
1206 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1180 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1207 <source>Signup limit</source> 1181 <source>Signup limit</source>
1208 <target>Limit rejestracji</target> 1182 <target>Limit rejestracji</target>
1209 <context-group name="null"> 1183 <context-group name="null">
1184 <context context-type="linenumber">96</context>
1185 </context-group>
1186 </trans-unit>
1187 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1188 <source>Users</source>
1189 <target>Użytkownicy</target>
1190 <context-group name="null">
1210 <context context-type="linenumber">105</context> 1191 <context context-type="linenumber">105</context>
1211 </context-group> 1192 </context-group>
1212 </trans-unit> 1193 </trans-unit>
1194 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1195 <source>User default video quota</source>
1196 <target>Domyślna powierzchnia na filmy dla użytkownika</target>
1197 <context-group name="null">
1198 <context context-type="linenumber">109</context>
1199 </context-group>
1200 </trans-unit>
1201 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1202 <source>User default daily upload limit</source>
1203 <target>Domyślny limit dziennego wysyłania przez użytkownika</target>
1204 <context-group name="null">
1205 <context context-type="linenumber">121</context>
1206 </context-group>
1207 </trans-unit>
1213 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1208 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1214 <source>Import</source> 1209 <source>Import</source>
1215 <target>Importuj</target> 1210 <target>Importuj</target>
@@ -1221,35 +1216,14 @@
1221 <source>Administrator</source> 1216 <source>Administrator</source>
1222 <target>Administrator</target> 1217 <target>Administrator</target>
1223 <context-group name="null"> 1218 <context-group name="null">
1224 <context context-type="linenumber">131</context> 1219 <context context-type="linenumber">155</context>
1225 </context-group> 1220 </context-group>
1226 </trans-unit> 1221 </trans-unit>
1227 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1222 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1228 <source>Admin email</source> 1223 <source>Admin email</source>
1229 <target>E-mail administratora</target> 1224 <target>E-mail administratora</target>
1230 <context-group name="null"> 1225 <context-group name="null">
1231 <context context-type="linenumber">134</context> 1226 <context context-type="linenumber">158</context>
1232 </context-group>
1233 </trans-unit>
1234 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1235 <source>Users</source>
1236 <target>Użytkownicy</target>
1237 <context-group name="null">
1238 <context context-type="linenumber">144</context>
1239 </context-group>
1240 </trans-unit>
1241 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1242 <source>User default video quota</source>
1243 <target>Domyślna powierzchnia na filmy dla użytkownika</target>
1244 <context-group name="null">
1245 <context context-type="linenumber">147</context>
1246 </context-group>
1247 </trans-unit>
1248 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1249 <source>User default daily upload limit</source>
1250 <target>Domyślny limit dziennego wysyłania przez użytkownika</target>
1251 <context-group name="null">
1252 <context context-type="linenumber">161</context>
1253 </context-group> 1227 </context-group>
1254 </trans-unit> 1228 </trans-unit>
1255 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1229 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1270,21 +1244,21 @@
1270 <source>Your Twitter username</source> 1244 <source>Your Twitter username</source>
1271 <target>Twoja nazwa użytkownika na Twitterze</target> 1245 <target>Twoja nazwa użytkownika na Twitterze</target>
1272 <context-group name="null"> 1246 <context-group name="null">
1273 <context context-type="linenumber">181</context> 1247 <context context-type="linenumber">184</context>
1274 </context-group> 1248 </context-group>
1275 </trans-unit> 1249 </trans-unit>
1276 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1250 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1277 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1251 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1278 <target>Oznacza konto Twittera dla strony lub platformy na której została opublikowana zawartość.</target> 1252 <target>Oznacza konto Twittera dla strony lub platformy na której została opublikowana zawartość.</target>
1279 <context-group name="null"> 1253 <context-group name="null">
1280 <context context-type="linenumber">184</context> 1254 <context context-type="linenumber">187</context>
1281 </context-group> 1255 </context-group>
1282 </trans-unit> 1256 </trans-unit>
1283 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1257 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1284 <source>Instance whitelisted by Twitter</source> 1258 <source>Instance whitelisted by Twitter</source>
1285 <target>Instancja jest na białej liście Twittera</target> 1259 <target>Instancja jest na białej liście Twittera</target>
1286 <context-group name="null"> 1260 <context-group name="null">
1287 <context context-type="linenumber">198</context> 1261 <context context-type="linenumber">199</context>
1288 </context-group> 1262 </context-group>
1289 </trans-unit> 1263 </trans-unit>
1290 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1264 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1298,35 +1272,35 @@
1298 <source>Transcoding</source> 1272 <source>Transcoding</source>
1299 <target>Transkodowanie</target> 1273 <target>Transkodowanie</target>
1300 <context-group name="null"> 1274 <context-group name="null">
1301 <context context-type="linenumber">210</context> 1275 <context context-type="linenumber">215</context>
1302 </context-group> 1276 </context-group>
1303 </trans-unit> 1277 </trans-unit>
1304 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1278 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1305 <source>Transcoding enabled</source> 1279 <source>Transcoding enabled</source>
1306 <target>Transkodowanie jest włączone</target> 1280 <target>Transkodowanie jest włączone</target>
1307 <context-group name="null"> 1281 <context-group name="null">
1308 <context context-type="linenumber">215</context> 1282 <context context-type="linenumber">221</context>
1309 </context-group> 1283 </context-group>
1310 </trans-unit> 1284 </trans-unit>
1311 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1285 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1312 <source>If you disable transcoding, many videos from your users will not work!</source> 1286 <source>If you disable transcoding, many videos from your users will not work!</source>
1313 <target>Jeżeli wyłączysz transkodowanie, wiele filmów od użytkowników może nie działać!</target> 1287 <target>Jeżeli wyłączysz transkodowanie, wiele filmów od użytkowników może nie działać!</target>
1314 <context-group name="null"> 1288 <context-group name="null">
1315 <context context-type="linenumber">216</context> 1289 <context context-type="linenumber">222</context>
1316 </context-group> 1290 </context-group>
1317 </trans-unit> 1291 </trans-unit>
1318 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1292 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1319 <source>Transcoding threads</source> 1293 <source>Transcoding threads</source>
1320 <target>WÄ…tki transkodowania</target> 1294 <target>WÄ…tki transkodowania</target>
1321 <context-group name="null"> 1295 <context-group name="null">
1322 <context context-type="linenumber">223</context> 1296 <context context-type="linenumber">237</context>
1323 </context-group> 1297 </context-group>
1324 </trans-unit> 1298 </trans-unit>
1325 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1299 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1326 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1300 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1327 <target>Włączono rozdzielczość <x id="INTERPOLATION" equiv-text="{{resolution}}"/></target> 1301 <target>Włączono rozdzielczość <x id="INTERPOLATION" equiv-text="{{resolution}}"/></target>
1328 <context-group name="null"> 1302 <context-group name="null">
1329 <context context-type="linenumber">239</context> 1303 <context context-type="linenumber">252</context>
1330 </context-group> 1304 </context-group>
1331 </trans-unit> 1305 </trans-unit>
1332 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1306 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1341,56 +1315,56 @@
1341 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1315 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1342 </target> 1316 </target>
1343 <context-group name="null"> 1317 <context-group name="null">
1344 <context context-type="linenumber">244</context> 1318 <context context-type="linenumber">260</context>
1345 </context-group> 1319 </context-group>
1346 </trans-unit> 1320 </trans-unit>
1347 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1321 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1348 <source>Previews cache size</source> 1322 <source>Previews cache size</source>
1349 <target>Rozmiar pamięci podręcznej podglądu</target> 1323 <target>Rozmiar pamięci podręcznej podglądu</target>
1350 <context-group name="null"> 1324 <context-group name="null">
1351 <context context-type="linenumber">254</context> 1325 <context context-type="linenumber">271</context>
1352 </context-group> 1326 </context-group>
1353 </trans-unit> 1327 </trans-unit>
1354 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1328 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1355 <source>Customizations</source> 1329 <source>Customizations</source>
1356 <target>Dostosowywanie</target> 1330 <target>Dostosowywanie</target>
1357 <context-group name="null"> 1331 <context-group name="null">
1358 <context context-type="linenumber">275</context> 1332 <context context-type="linenumber">289</context>
1359 </context-group> 1333 </context-group>
1360 </trans-unit> 1334 </trans-unit>
1361 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1335 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1362 <source>JavaScript</source> 1336 <source>JavaScript</source>
1363 <target>JavaScript</target> 1337 <target>JavaScript</target>
1364 <context-group name="null"> 1338 <context-group name="null">
1365 <context context-type="linenumber">278</context> 1339 <context context-type="linenumber">294</context>
1366 </context-group> 1340 </context-group>
1367 </trans-unit> 1341 </trans-unit>
1368 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1342 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1369 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1343 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1370 <target>Wprowadź kod JavaScript.&lt;br /&gt;Przykład: &lt;pre&gt;console.log('moja instancja jest świetna');&lt;/pre&gt;</target> 1344 <target>Wprowadź kod JavaScript.&lt;br /&gt;Przykład: &lt;pre&gt;console.log('moja instancja jest świetna');&lt;/pre&gt;</target>
1371 <context-group name="null"> 1345 <context-group name="null">
1372 <context context-type="linenumber">281</context> 1346 <context context-type="linenumber">297</context>
1373 </context-group> 1347 </context-group>
1374 </trans-unit> 1348 </trans-unit>
1375 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab"> 1349 <trans-unit id="6c44844ebdb7352c433b7734feaa65f01bb594ab">
1376 <source>Advanced configuration</source> 1350 <source>Advanced configuration</source>
1377 <target>Zaawansowana konfiguracja</target> 1351 <target>Zaawansowana konfiguracja</target>
1378 <context-group name="null"> 1352 <context-group name="null">
1379 <context context-type="linenumber">207</context> 1353 <context context-type="linenumber">212</context>
1380 </context-group> 1354 </context-group>
1381 </trans-unit> 1355 </trans-unit>
1382 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1356 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1383 <source>Update configuration</source> 1357 <source>Update configuration</source>
1384 <target>Aktualizuj konfiguracjÄ™</target> 1358 <target>Aktualizuj konfiguracjÄ™</target>
1385 <context-group name="null"> 1359 <context-group name="null">
1386 <context context-type="linenumber">325</context> 1360 <context context-type="linenumber">340</context>
1387 </context-group> 1361 </context-group>
1388 </trans-unit> 1362 </trans-unit>
1389 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1363 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1390 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1364 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1391 <target>Wygląda na to, że konfiguracja jest nieprawidłowa. Poszukaj możliwych błędów w innych kartach.</target> 1365 <target>Wygląda na to, że konfiguracja jest nieprawidłowa. Poszukaj możliwych błędów w innych kartach.</target>
1392 <context-group name="null"> 1366 <context-group name="null">
1393 <context context-type="linenumber">326</context> 1367 <context context-type="linenumber">341</context>
1394 </context-group> 1368 </context-group>
1395 </trans-unit> 1369 </trans-unit>
1396 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1370 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1601,6 +1575,10 @@
1601 Transcoding is enabled on server. The video quota only take in account <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>original<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> video. <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> 1575 Transcoding is enabled on server. The video quota only take in account <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>original<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> video. <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>
1602 At most, this user could use ~ <x id="INTERPOLATION" equiv-text="{{ computeQuotaWithTranscoding() | bytes: 0 }}"/>. 1576 At most, this user could use ~ <x id="INTERPOLATION" equiv-text="{{ computeQuotaWithTranscoding() | bytes: 0 }}"/>.
1603 </source> 1577 </source>
1578 <target>
1579 Transcoding is enabled on server. The video quota only take in account <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/>original<x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/strong&gt;"/> video. <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>
1580 At most, this user could use ~ <x id="INTERPOLATION" equiv-text="{{ computeQuotaWithTranscoding() | bytes: 0 }}"/>.
1581 </target>
1604 <context-group name="null"> 1582 <context-group name="null">
1605 <context context-type="linenumber">65</context> 1583 <context context-type="linenumber">65</context>
1606 </context-group> 1584 </context-group>
@@ -1665,7 +1643,7 @@
1665 <source>Actions</source> 1643 <source>Actions</source>
1666 <target>Akcje</target> 1644 <target>Akcje</target>
1667 <context-group name="null"> 1645 <context-group name="null">
1668 <context context-type="linenumber">33</context> 1646 <context context-type="linenumber">35</context>
1669 </context-group> 1647 </context-group>
1670 </trans-unit> 1648 </trans-unit>
1671 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 1649 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -1679,7 +1657,7 @@
1679 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 1657 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
1680 <target>Data <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 1658 <target>Data <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
1681 <context-group name="null"> 1659 <context-group name="null">
1682 <context context-type="linenumber">10</context> 1660 <context context-type="linenumber">11</context>
1683 </context-group> 1661 </context-group>
1684 </trans-unit> 1662 </trans-unit>
1685 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 1663 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -1696,48 +1674,6 @@
1696 <context context-type="linenumber">7</context> 1674 <context context-type="linenumber">7</context>
1697 </context-group> 1675 </context-group>
1698 </trans-unit> 1676 </trans-unit>
1699 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
1700 <source>My settings</source>
1701 <target>Moje ustawienia</target>
1702 <context-group name="null">
1703 <context context-type="linenumber">3</context>
1704 </context-group>
1705 </trans-unit>
1706 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
1707 <source>My library</source>
1708 <target>Moja biblioteka</target>
1709 <context-group name="null">
1710 <context context-type="linenumber">7</context>
1711 </context-group>
1712 </trans-unit>
1713 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
1714 <source>My channels</source>
1715 <target>Moje kanały</target>
1716 <context-group name="null">
1717 <context context-type="linenumber">12</context>
1718 </context-group>
1719 </trans-unit>
1720 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
1721 <source>My videos</source>
1722 <target>Moje filmy</target>
1723 <context-group name="null">
1724 <context context-type="linenumber">14</context>
1725 </context-group>
1726 </trans-unit>
1727 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
1728 <source>My subscriptions</source>
1729 <target>Moje subskrybcje</target>
1730 <context-group name="null">
1731 <context context-type="linenumber">16</context>
1732 </context-group>
1733 </trans-unit>
1734 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
1735 <source>My imports</source>
1736 <target>Moje importy</target>
1737 <context-group name="null">
1738 <context context-type="linenumber">18</context>
1739 </context-group>
1740 </trans-unit>
1741 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 1677 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
1742 <source>Video quota:</source> 1678 <source>Video quota:</source>
1743 <target>Powierzchnia na filmy:</target> 1679 <target>Powierzchnia na filmy:</target>
@@ -1749,14 +1685,14 @@
1749 <source>Profile</source> 1685 <source>Profile</source>
1750 <target>Profil</target> 1686 <target>Profil</target>
1751 <context-group name="null"> 1687 <context-group name="null">
1752 <context context-type="linenumber">8</context> 1688 <context context-type="linenumber">7</context>
1753 </context-group> 1689 </context-group>
1754 </trans-unit> 1690 </trans-unit>
1755 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 1691 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
1756 <source>Video settings</source> 1692 <source>Video settings</source>
1757 <target>Ustawienia wideo</target> 1693 <target>Ustawienia wideo</target>
1758 <context-group name="null"> 1694 <context-group name="null">
1759 <context context-type="linenumber">15</context> 1695 <context context-type="linenumber">16</context>
1760 </context-group> 1696 </context-group>
1761 </trans-unit> 1697 </trans-unit>
1762 <trans-unit id="a5433ae2324496bea9537caa5e8a2719d8e958d8"> 1698 <trans-unit id="a5433ae2324496bea9537caa5e8a2719d8e958d8">
@@ -1770,13 +1706,6 @@
1770 <context context-type="linenumber">35</context> 1706 <context context-type="linenumber">35</context>
1771 </context-group> 1707 </context-group>
1772 </trans-unit> 1708 </trans-unit>
1773 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
1774 <source>Submit</source>
1775 <target>Wyślij</target>
1776 <context-group name="null">
1777 <context context-type="linenumber">24</context>
1778 </context-group>
1779 </trans-unit>
1780 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 1709 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
1781 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 1710 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
1782 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> wyświetlenia</target> 1711 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> wyświetlenia</target>
@@ -2008,14 +1937,14 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2008 <source>Publish will be available when upload is finished</source> 1937 <source>Publish will be available when upload is finished</source>
2009 <target>Opublikuj automatycznie po ukończeniu wysyłania</target> 1938 <target>Opublikuj automatycznie po ukończeniu wysyłania</target>
2010 <context-group name="null"> 1939 <context-group name="null">
2011 <context context-type="linenumber">53</context> 1940 <context context-type="linenumber">58</context>
2012 </context-group> 1941 </context-group>
2013 </trans-unit> 1942 </trans-unit>
2014 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 1943 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2015 <source>Publish</source> 1944 <source>Publish</source>
2016 <target>Opublikuj</target> 1945 <target>Opublikuj</target>
2017 <context-group name="null"> 1946 <context-group name="null">
2018 <context context-type="linenumber">60</context> 1947 <context context-type="linenumber">65</context>
2019 </context-group> 1948 </context-group>
2020 </trans-unit> 1949 </trans-unit>
2021 <trans-unit id="1b518e7f8c067fa55ea797bb1b35b4a2d31dccbc"> 1950 <trans-unit id="1b518e7f8c067fa55ea797bb1b35b4a2d31dccbc">
@@ -2127,7 +2056,7 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2127 <source>Wait transcoding before publishing the video</source> 2056 <source>Wait transcoding before publishing the video</source>
2128 <target>Poczekaj na transkodowanie przed opublikowaniem filmu</target> 2057 <target>Poczekaj na transkodowanie przed opublikowaniem filmu</target>
2129 <context-group name="null"> 2058 <context-group name="null">
2130 <context context-type="linenumber">130</context> 2059 <context context-type="linenumber">131</context>
2131 </context-group> 2060 </context-group>
2132 </trans-unit> 2061 </trans-unit>
2133 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2062 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2141,14 +2070,14 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2141 <source>Upload thumbnail</source> 2070 <source>Upload thumbnail</source>
2142 <target>Wyślij miniaturę</target> 2071 <target>Wyślij miniaturę</target>
2143 <context-group name="null"> 2072 <context-group name="null">
2144 <context context-type="linenumber">195</context> 2073 <context context-type="linenumber">196</context>
2145 </context-group> 2074 </context-group>
2146 </trans-unit> 2075 </trans-unit>
2147 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 2076 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
2148 <source>Upload preview</source> 2077 <source>Upload preview</source>
2149 <target>Podgląd wysyłania</target> 2078 <target>Podgląd wysyłania</target>
2150 <context-group name="null"> 2079 <context-group name="null">
2151 <context context-type="linenumber">202</context> 2080 <context context-type="linenumber">203</context>
2152 </context-group> 2081 </context-group>
2153 </trans-unit> 2082 </trans-unit>
2154 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 2083 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -2162,14 +2091,14 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2162 <source>Short text to tell people how they can support you (membership platform...).</source> 2091 <source>Short text to tell people how they can support you (membership platform...).</source>
2163 <target>Krótki tekst informujący innych, jak mogą Cię wesprzeć (platforma członkowska…).</target> 2092 <target>Krótki tekst informujący innych, jak mogą Cię wesprzeć (platforma członkowska…).</target>
2164 <context-group name="null"> 2093 <context-group name="null">
2165 <context context-type="linenumber">209</context> 2094 <context context-type="linenumber">210</context>
2166 </context-group> 2095 </context-group>
2167 </trans-unit> 2096 </trans-unit>
2168 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 2097 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
2169 <source>Advanced settings</source> 2098 <source>Advanced settings</source>
2170 <target>Ustawienia zaawansowane</target> 2099 <target>Ustawienia zaawansowane</target>
2171 <context-group name="null"> 2100 <context-group name="null">
2172 <context context-type="linenumber">190</context> 2101 <context context-type="linenumber">191</context>
2173 </context-group> 2102 </context-group>
2174 </trans-unit> 2103 </trans-unit>
2175 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 2104 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -2236,17 +2165,6 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2236 <context context-type="linenumber">3</context> 2165 <context context-type="linenumber">3</context>
2237 </context-group> 2166 </context-group>
2238 </trans-unit> 2167 </trans-unit>
2239 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
2240 <source>
2241 Cancel
2242 </source>
2243 <target>
2244 Anuluj
2245 </target>
2246 <context-group name="null">
2247 <context context-type="linenumber">19</context>
2248 </context-group>
2249 </trans-unit>
2250 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 2168 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
2251 <source>Share</source> 2169 <source>Share</source>
2252 <target>Udostępnij</target> 2170 <target>Udostępnij</target>
@@ -2522,13 +2440,6 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2522 <context context-type="linenumber">14</context> 2440 <context context-type="linenumber">14</context>
2523 </context-group> 2441 </context-group>
2524 </trans-unit> 2442 </trans-unit>
2525 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
2526 <source>Error getting about from server</source>
2527 <target>BÅ‚Ä…d podczas uzyskiwania informacji z serwera</target>
2528 <context-group name="null">
2529 <context context-type="linenumber">1</context>
2530 </context-group>
2531 </trans-unit>
2532 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 2443 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
2533 <source>No description</source> 2444 <source>No description</source>
2534 <target>Brak opisu</target> 2445 <target>Brak opisu</target>
@@ -2550,13 +2461,6 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2550 <context context-type="linenumber">1</context> 2461 <context context-type="linenumber">1</context>
2551 </context-group> 2462 </context-group>
2552 </trans-unit> 2463 </trans-unit>
2553 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
2554 <source>Error</source>
2555 <target>BÅ‚Ä…d</target>
2556 <context-group name="null">
2557 <context context-type="linenumber">1</context>
2558 </context-group>
2559 </trans-unit>
2560 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6"> 2464 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
2561 <source>240p</source> 2465 <source>240p</source>
2562 <target>240p</target> 2466 <target>240p</target>
@@ -2592,13 +2496,6 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2592 <context context-type="linenumber">1</context> 2496 <context context-type="linenumber">1</context>
2593 </context-group> 2497 </context-group>
2594 </trans-unit> 2498 </trans-unit>
2595 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
2596 <source>Success</source>
2597 <target>Pomyślnie</target>
2598 <context-group name="null">
2599 <context context-type="linenumber">1</context>
2600 </context-group>
2601 </trans-unit>
2602 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 2499 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
2603 <source>Configuration updated.</source> 2500 <source>Configuration updated.</source>
2604 <target>Zaktualizowano konfiguracjÄ™.</target> 2501 <target>Zaktualizowano konfiguracjÄ™.</target>
@@ -2844,23 +2741,16 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2844 <context context-type="linenumber">1</context> 2741 <context context-type="linenumber">1</context>
2845 </context-group> 2742 </context-group>
2846 </trans-unit> 2743 </trans-unit>
2847 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 2744 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
2848 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 2745 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
2849 <target>Czy na pewno chcesz usunąć <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? Skutkuje to usunięciem wszystkich filmów wysłanych na ten kanał.</target> 2746 <target>Usunięto kanał wideo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>.</target>
2850 <context-group name="null">
2851 <context context-type="linenumber">1</context>
2852 </context-group>
2853 </trans-unit>
2854 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
2855 <source>Please type the name of the video channel to confirm</source>
2856 <target>Wprowadź nazwę kanału wideo, aby potwierdzić</target>
2857 <context-group name="null"> 2747 <context-group name="null">
2858 <context context-type="linenumber">1</context> 2748 <context context-type="linenumber">1</context>
2859 </context-group> 2749 </context-group>
2860 </trans-unit> 2750 </trans-unit>
2861 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 2751 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2862 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 2752 <source>My videos</source>
2863 <target>Usunięto kanał wideo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>.</target> 2753 <target>Moje filmy</target>
2864 <context-group name="null"> 2754 <context-group name="null">
2865 <context context-type="linenumber">1</context> 2755 <context context-type="linenumber">1</context>
2866 </context-group> 2756 </context-group>
@@ -2921,9 +2811,30 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2921 <context context-type="linenumber">1</context> 2811 <context context-type="linenumber">1</context>
2922 </context-group> 2812 </context-group>
2923 </trans-unit> 2813 </trans-unit>
2924 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 2814 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2925 <source>Channels</source> 2815 <source>My library</source>
2926 <target>Kanały</target> 2816 <target>Moja biblioteka</target>
2817 <context-group name="null">
2818 <context context-type="linenumber">1</context>
2819 </context-group>
2820 </trans-unit>
2821 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2822 <source>My channels</source>
2823 <target>Moje kanały</target>
2824 <context-group name="null">
2825 <context context-type="linenumber">1</context>
2826 </context-group>
2827 </trans-unit>
2828 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2829 <source>My subscriptions</source>
2830 <target>Moje subskrybcje</target>
2831 <context-group name="null">
2832 <context context-type="linenumber">1</context>
2833 </context-group>
2834 </trans-unit>
2835 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2836 <source>My settings</source>
2837 <target>Moje ustawienia</target>
2927 <context-group name="null"> 2838 <context-group name="null">
2928 <context context-type="linenumber">1</context> 2839 <context context-type="linenumber">1</context>
2929 </context-group> 2840 </context-group>
@@ -2951,6 +2862,13 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2951 <context context-type="linenumber">1</context> 2862 <context context-type="linenumber">1</context>
2952 </context-group> 2863 </context-group>
2953 </trans-unit> 2864 </trans-unit>
2865 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
2866 <source>Error</source>
2867 <target>BÅ‚Ä…d</target>
2868 <context-group name="null">
2869 <context context-type="linenumber">1</context>
2870 </context-group>
2871 </trans-unit>
2954 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 2872 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
2955 <source>You need to reconnect.</source> 2873 <source>You need to reconnect.</source>
2956 <target>Musisz połączyć się ponownie.</target> 2874 <target>Musisz połączyć się ponownie.</target>
@@ -2965,6 +2883,20 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
2965 <context context-type="linenumber">1</context> 2883 <context context-type="linenumber">1</context>
2966 </context-group> 2884 </context-group>
2967 </trans-unit> 2885 </trans-unit>
2886 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
2887 <source>Info</source>
2888 <target>Informacja</target>
2889 <context-group name="null">
2890 <context context-type="linenumber">1</context>
2891 </context-group>
2892 </trans-unit>
2893 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
2894 <source>Success</source>
2895 <target>Pomyślnie</target>
2896 <context-group name="null">
2897 <context context-type="linenumber">1</context>
2898 </context-group>
2899 </trans-unit>
2968 <trans-unit id="b0f24b7136e551a0deba831f1525711245b31a26"> 2900 <trans-unit id="b0f24b7136e551a0deba831f1525711245b31a26">
2969 <source>Your password has been successfully reset!</source> 2901 <source>Your password has been successfully reset!</source>
2970 <target>Pomyślnie zresetowano hasło!</target> 2902 <target>Pomyślnie zresetowano hasło!</target>
@@ -3126,6 +3058,20 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
3126 <context context-type="linenumber">1</context> 3058 <context context-type="linenumber">1</context>
3127 </context-group> 3059 </context-group>
3128 </trans-unit> 3060 </trans-unit>
3061 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
3062 <source>Email is required.</source>
3063 <target>Adres e-mail jest wymagany.</target>
3064 <context-group name="null">
3065 <context context-type="linenumber">1</context>
3066 </context-group>
3067 </trans-unit>
3068 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
3069 <source>Email must be valid.</source>
3070 <target>Adres e-mail musi być prawidłowy.</target>
3071 <context-group name="null">
3072 <context context-type="linenumber">1</context>
3073 </context-group>
3074 </trans-unit>
3129 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 3075 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
3130 <source>Username is required.</source> 3076 <source>Username is required.</source>
3131 <target>Nazwa użytkownika jest wymagana.</target> 3077 <target>Nazwa użytkownika jest wymagana.</target>
@@ -3147,41 +3093,6 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
3147 <context context-type="linenumber">1</context> 3093 <context context-type="linenumber">1</context>
3148 </context-group> 3094 </context-group>
3149 </trans-unit> 3095 </trans-unit>
3150 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
3151 <source>Username must be at least 3 characters long.</source>
3152 <target>Nazwa użytkownika musi zawierać przynajmniej 3 znaki.</target>
3153 <context-group name="null">
3154 <context context-type="linenumber">1</context>
3155 </context-group>
3156 </trans-unit>
3157 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
3158 <source>Username cannot be more than 20 characters long.</source>
3159 <target>Nazwa użytkownika nie może być dłuższa niż 20 znaków.</target>
3160 <context-group name="null">
3161 <context context-type="linenumber">1</context>
3162 </context-group>
3163 </trans-unit>
3164 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
3165 <source>Username should be only lowercase alphanumeric characters.</source>
3166 <target>Nazwa użytkownika może zawierać tylko małe znaki alfanumeryczne.</target>
3167 <context-group name="null">
3168 <context context-type="linenumber">1</context>
3169 </context-group>
3170 </trans-unit>
3171 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
3172 <source>Email is required.</source>
3173 <target>Adres e-mail jest wymagany.</target>
3174 <context-group name="null">
3175 <context context-type="linenumber">1</context>
3176 </context-group>
3177 </trans-unit>
3178 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
3179 <source>Email must be valid.</source>
3180 <target>Adres e-mail musi być prawidłowy.</target>
3181 <context-group name="null">
3182 <context context-type="linenumber">1</context>
3183 </context-group>
3184 </trans-unit>
3185 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 3096 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
3186 <source>Password must be at least 6 characters long.</source> 3097 <source>Password must be at least 6 characters long.</source>
3187 <target>Hasło musi składać się z przynajmniej 6 znaków.</target> 3098 <target>Hasło musi składać się z przynajmniej 6 znaków.</target>
@@ -3231,20 +3142,6 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
3231 <context context-type="linenumber">1</context> 3142 <context context-type="linenumber">1</context>
3232 </context-group> 3143 </context-group>
3233 </trans-unit> 3144 </trans-unit>
3234 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
3235 <source>Display name must be at least 3 characters long.</source>
3236 <target>Nazwa wyświetlana musi zawierać przynajmniej 3 znaki.</target>
3237 <context-group name="null">
3238 <context context-type="linenumber">1</context>
3239 </context-group>
3240 </trans-unit>
3241 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
3242 <source>Display name cannot be more than 120 characters long.</source>
3243 <target>Nazwa wyświetlana nie może zawierać więcej niż 120 znaków.</target>
3244 <context-group name="null">
3245 <context context-type="linenumber">1</context>
3246 </context-group>
3247 </trans-unit>
3248 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 3145 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
3249 <source>Description must be at least 3 characters long.</source> 3146 <source>Description must be at least 3 characters long.</source>
3250 <target>Opis musi zawierać przynajmniej 3 znaki.</target> 3147 <target>Opis musi zawierać przynajmniej 3 znaki.</target>
@@ -3266,13 +3163,6 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
3266 <context context-type="linenumber">1</context> 3163 <context context-type="linenumber">1</context>
3267 </context-group> 3164 </context-group>
3268 </trans-unit> 3165 </trans-unit>
3269 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
3270 <source>Report reason cannot be more than 300 characters long.</source>
3271 <target>Przyczyna zgłoszenia nie może zawierać więcej niż 300 znaków.</target>
3272 <context-group name="null">
3273 <context context-type="linenumber">1</context>
3274 </context-group>
3275 </trans-unit>
3276 <trans-unit id="bd7fc070c728dc6dbf3959d49fe5bb27ce15d294"> 3166 <trans-unit id="bd7fc070c728dc6dbf3959d49fe5bb27ce15d294">
3277 <source>The username is required.</source> 3167 <source>The username is required.</source>
3278 <target>Nazwa użytkownika jest wymagana.</target> 3168 <target>Nazwa użytkownika jest wymagana.</target>
@@ -3287,27 +3177,6 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
3287 <context context-type="linenumber">1</context> 3177 <context context-type="linenumber">1</context>
3288 </context-group> 3178 </context-group>
3289 </trans-unit> 3179 </trans-unit>
3290 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069">
3291 <source>Name must be at least 3 characters long.</source>
3292 <target>Nazwa musi zawierać przynajmniej 3 znaki.</target>
3293 <context-group name="null">
3294 <context context-type="linenumber">1</context>
3295 </context-group>
3296 </trans-unit>
3297 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482">
3298 <source>Name cannot be more than 20 characters long.</source>
3299 <target>Nazwa nie może być dłuższa niż 20 znaków.</target>
3300 <context-group name="null">
3301 <context context-type="linenumber">1</context>
3302 </context-group>
3303 </trans-unit>
3304 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9">
3305 <source>Name should be only lowercase alphanumeric characters.</source>
3306 <target>Nazwa może zawierać tylko małe znaki alfanumeryczne.</target>
3307 <context-group name="null">
3308 <context context-type="linenumber">1</context>
3309 </context-group>
3310 </trans-unit>
3311 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 3180 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
3312 <source>Support text must be at least 3 characters long.</source> 3181 <source>Support text must be at least 3 characters long.</source>
3313 <target>Tekst o wsparciu musi zawierać przynajmniej 3 znaki.</target> 3182 <target>Tekst o wsparciu musi zawierać przynajmniej 3 znaki.</target>
@@ -3999,13 +3868,6 @@ Jeżeli umieścisz film na ten kanał, pole informujące o możliwości wsparcia
3999 <context context-type="linenumber">1</context> 3868 <context context-type="linenumber">1</context>
4000 </context-group> 3869 </context-group>
4001 </trans-unit> 3870 </trans-unit>
4002 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4003 <source>Info</source>
4004 <target>Informacja</target>
4005 <context-group name="null">
4006 <context context-type="linenumber">1</context>
4007 </context-group>
4008 </trans-unit>
4009 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 3871 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
4010 <source>Upload cancelled</source> 3872 <source>Upload cancelled</source>
4011 <target>Anulowano wysyłanie</target> 3873 <target>Anulowano wysyłanie</target>
diff --git a/client/src/locale/target/angular_pt_BR.xml b/client/src/locale/target/angular_pt_BR.xml
index 71aeac8d5..0227115e3 100644
--- a/client/src/locale/target/angular_pt_BR.xml
+++ b/client/src/locale/target/angular_pt_BR.xml
@@ -370,7 +370,7 @@
370 <source>Password</source> 370 <source>Password</source>
371 <target>Senha</target> 371 <target>Senha</target>
372 <context-group name="null"> 372 <context-group name="null">
373 <context context-type="linenumber">12</context> 373 <context context-type="linenumber">13</context>
374 </context-group> 374 </context-group>
375 </trans-unit> 375 </trans-unit>
376 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 376 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -384,7 +384,7 @@
384 <source>Login</source> 384 <source>Login</source>
385 <target>Entrar</target> 385 <target>Entrar</target>
386 <context-group name="null"> 386 <context-group name="null">
387 <context context-type="linenumber">38</context> 387 <context context-type="linenumber">36</context>
388 </context-group> 388 </context-group>
389 </trans-unit> 389 </trans-unit>
390 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 390 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -412,7 +412,7 @@
412 <source>Send me an email to reset my password</source> 412 <source>Send me an email to reset my password</source>
413 <target>Me envie um e-mail para redefinir minha senha</target> 413 <target>Me envie um e-mail para redefinir minha senha</target>
414 <context-group name="null"> 414 <context-group name="null">
415 <context context-type="linenumber">75</context> 415 <context context-type="linenumber">80</context>
416 </context-group> 416 </context-group>
417 </trans-unit> 417 </trans-unit>
418 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 418 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -476,7 +476,7 @@
476 <source>Signup</source> 476 <source>Signup</source>
477 <target>Inscrever-se</target> 477 <target>Inscrever-se</target>
478 <context-group name="null"> 478 <context-group name="null">
479 <context context-type="linenumber">88</context> 479 <context context-type="linenumber">78</context>
480 </context-group> 480 </context-group>
481 </trans-unit> 481 </trans-unit>
482 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 482 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -533,7 +533,7 @@
533 <source>Change the language</source> 533 <source>Change the language</source>
534 <target>Alterar o idioma</target> 534 <target>Alterar o idioma</target>
535 <context-group name="null"> 535 <context-group name="null">
536 <context context-type="linenumber">88</context> 536 <context context-type="linenumber">86</context>
537 </context-group> 537 </context-group>
538 </trans-unit> 538 </trans-unit>
539 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 539 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -544,7 +544,7 @@
544 Meu perfil público 544 Meu perfil público
545 </target> 545 </target>
546 <context-group name="null"> 546 <context-group name="null">
547 <context context-type="linenumber">18</context> 547 <context context-type="linenumber">16</context>
548 </context-group> 548 </context-group>
549 </trans-unit> 549 </trans-unit>
550 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 550 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -555,7 +555,7 @@
555 Minha conta 555 Minha conta
556 </target> 556 </target>
557 <context-group name="null"> 557 <context-group name="null">
558 <context context-type="linenumber">22</context> 558 <context context-type="linenumber">20</context>
559 </context-group> 559 </context-group>
560 </trans-unit> 560 </trans-unit>
561 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 561 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -566,7 +566,7 @@
566 Meus vídeos 566 Meus vídeos
567 </target> 567 </target>
568 <context-group name="null"> 568 <context-group name="null">
569 <context context-type="linenumber">26</context> 569 <context context-type="linenumber">24</context>
570 </context-group> 570 </context-group>
571 </trans-unit> 571 </trans-unit>
572 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 572 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -577,14 +577,14 @@
577 Sair 577 Sair
578 </target> 578 </target>
579 <context-group name="null"> 579 <context-group name="null">
580 <context context-type="linenumber">30</context> 580 <context context-type="linenumber">28</context>
581 </context-group> 581 </context-group>
582 </trans-unit> 582 </trans-unit>
583 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 583 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
584 <source>Create an account</source> 584 <source>Create an account</source>
585 <target>Criar uma conta</target> 585 <target>Criar uma conta</target>
586 <context-group name="null"> 586 <context-group name="null">
587 <context context-type="linenumber">39</context> 587 <context context-type="linenumber">37</context>
588 </context-group> 588 </context-group>
589 </trans-unit> 589 </trans-unit>
590 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 590 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -598,49 +598,49 @@
598 <source>Subscriptions</source> 598 <source>Subscriptions</source>
599 <target>Inscrições</target> 599 <target>Inscrições</target>
600 <context-group name="null"> 600 <context-group name="null">
601 <context context-type="linenumber">47</context> 601 <context context-type="linenumber">45</context>
602 </context-group> 602 </context-group>
603 </trans-unit> 603 </trans-unit>
604 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 604 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
605 <source>Overview</source> 605 <source>Overview</source>
606 <target>Visão geral</target> 606 <target>Visão geral</target>
607 <context-group name="null"> 607 <context-group name="null">
608 <context context-type="linenumber">52</context> 608 <context context-type="linenumber">50</context>
609 </context-group> 609 </context-group>
610 </trans-unit> 610 </trans-unit>
611 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 611 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
612 <source>Trending</source> 612 <source>Trending</source>
613 <target>Tendências</target> 613 <target>Tendências</target>
614 <context-group name="null"> 614 <context-group name="null">
615 <context context-type="linenumber">57</context> 615 <context context-type="linenumber">55</context>
616 </context-group> 616 </context-group>
617 </trans-unit> 617 </trans-unit>
618 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 618 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
619 <source>Recently added</source> 619 <source>Recently added</source>
620 <target>Adicionado recentemente</target> 620 <target>Adicionado recentemente</target>
621 <context-group name="null"> 621 <context-group name="null">
622 <context context-type="linenumber">62</context> 622 <context context-type="linenumber">60</context>
623 </context-group> 623 </context-group>
624 </trans-unit> 624 </trans-unit>
625 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 625 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
626 <source>Local</source> 626 <source>Local</source>
627 <target>Local</target> 627 <target>Local</target>
628 <context-group name="null"> 628 <context-group name="null">
629 <context context-type="linenumber">67</context> 629 <context context-type="linenumber">65</context>
630 </context-group> 630 </context-group>
631 </trans-unit> 631 </trans-unit>
632 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 632 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
633 <source>More</source> 633 <source>More</source>
634 <target>Mais</target> 634 <target>Mais</target>
635 <context-group name="null"> 635 <context-group name="null">
636 <context context-type="linenumber">72</context> 636 <context context-type="linenumber">70</context>
637 </context-group> 637 </context-group>
638 </trans-unit> 638 </trans-unit>
639 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 639 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
640 <source>Administration</source> 640 <source>Administration</source>
641 <target>Administração</target> 641 <target>Administração</target>
642 <context-group name="null"> 642 <context-group name="null">
643 <context context-type="linenumber">76</context> 643 <context context-type="linenumber">74</context>
644 </context-group> 644 </context-group>
645 </trans-unit> 645 </trans-unit>
646 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 646 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -654,7 +654,7 @@
654 <source>Toggle dark interface</source> 654 <source>Toggle dark interface</source>
655 <target>Alternar interface escura</target> 655 <target>Alternar interface escura</target>
656 <context-group name="null"> 656 <context-group name="null">
657 <context context-type="linenumber">94</context> 657 <context context-type="linenumber">92</context>
658 </context-group> 658 </context-group>
659 </trans-unit> 659 </trans-unit>
660 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 660 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -759,7 +759,7 @@
759 <source>No results.</source> 759 <source>No results.</source>
760 <target>Nenhum resultado.</target> 760 <target>Nenhum resultado.</target>
761 <context-group name="null"> 761 <context-group name="null">
762 <context context-type="linenumber">17</context> 762 <context context-type="linenumber">20</context>
763 </context-group> 763 </context-group>
764 </trans-unit> 764 </trans-unit>
765 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 765 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -806,15 +806,22 @@
806 <context context-type="linenumber">7</context> 806 <context context-type="linenumber">7</context>
807 </context-group> 807 </context-group>
808 </trans-unit> 808 </trans-unit>
809 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 809 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
810 <source> 810 <source>
811 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 811 Cancel
812</source> 812 </source>
813 <target> 813 <target>
814 Sobre a instância <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> 814 Cancelar
815</target> 815 </target>
816 <context-group name="null"> 816 <context-group name="null">
817 <context context-type="linenumber">1</context> 817 <context context-type="linenumber">26</context>
818 </context-group>
819 </trans-unit>
820 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
821 <source>Submit</source>
822 <target>Enviar</target>
823 <context-group name="null">
824 <context context-type="linenumber">31</context>
818 </context-group> 825 </context-group>
819 </trans-unit> 826 </trans-unit>
820 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 827 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -828,47 +835,14 @@
828 <source>Terms</source> 835 <source>Terms</source>
829 <target>Termos</target> 836 <target>Termos</target>
830 <context-group name="null"> 837 <context-group name="null">
831 <context context-type="linenumber">44</context> 838 <context context-type="linenumber">39</context>
832 </context-group> 839 </context-group>
833 </trans-unit> 840 </trans-unit>
834 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 841 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
835 <source>User registration is allowed and</source> 842 <source>User registration is allowed and</source>
836 <target>Registro de usuários não está permitida e</target> 843 <target>Registro de usuários não está permitida e</target>
837 <context-group name="null"> 844 <context-group name="null">
838 <context context-type="linenumber">25</context> 845 <context context-type="linenumber">29</context>
839 </context-group>
840 </trans-unit>
841 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
842 <source>
843 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
844 </source>
845 <target>
846 esta instância fornece uma cota base de <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> espaço para os vídeos de seus usuários.
847 </target>
848 <context-group name="null">
849 <context context-type="linenumber">27</context>
850 </context-group>
851 </trans-unit>
852 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
853 <source>
854 this instance provides unlimited space for the videos of its users.
855 </source>
856 <target>
857 esta instância fornece espaço ilimitado para os vídeos de seus usuários.
858 </target>
859 <context-group name="null">
860 <context context-type="linenumber">31</context>
861 </context-group>
862 </trans-unit>
863 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
864 <source>
865 User registration is currently not allowed.
866 </source>
867 <target>
868 Registro de usuários atualmente não está permitido.
869 </target>
870 <context-group name="null">
871 <context context-type="linenumber">36</context>
872 </context-group> 846 </context-group>
873 </trans-unit> 847 </trans-unit>
874 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 848 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1177,49 +1151,49 @@
1177 <source>Short description</source> 1151 <source>Short description</source>
1178 <target>Descrição curta</target> 1152 <target>Descrição curta</target>
1179 <context-group name="null"> 1153 <context-group name="null">
1180 <context context-type="linenumber">22</context> 1154 <context context-type="linenumber">21</context>
1181 </context-group> 1155 </context-group>
1182 </trans-unit> 1156 </trans-unit>
1183 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1157 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1184 <source>Default client route</source> 1158 <source>Default client route</source>
1185 <target>Rota padrão do cliente</target> 1159 <target>Rota padrão do cliente</target>
1186 <context-group name="null"> 1160 <context-group name="null">
1187 <context context-type="linenumber">55</context> 1161 <context context-type="linenumber">48</context>
1188 </context-group> 1162 </context-group>
1189 </trans-unit> 1163 </trans-unit>
1190 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1164 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1191 <source>Videos Overview</source> 1165 <source>Videos Overview</source>
1192 <target>Visão geral dos vídeos</target> 1166 <target>Visão geral dos vídeos</target>
1193 <context-group name="null"> 1167 <context-group name="null">
1194 <context context-type="linenumber">58</context> 1168 <context context-type="linenumber">51</context>
1195 </context-group> 1169 </context-group>
1196 </trans-unit> 1170 </trans-unit>
1197 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1171 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1198 <source>Videos Trending</source> 1172 <source>Videos Trending</source>
1199 <target>Vídeos em Tendência</target> 1173 <target>Vídeos em Tendência</target>
1200 <context-group name="null"> 1174 <context-group name="null">
1201 <context context-type="linenumber">59</context> 1175 <context context-type="linenumber">52</context>
1202 </context-group> 1176 </context-group>
1203 </trans-unit> 1177 </trans-unit>
1204 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1178 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1205 <source>Videos Recently Added</source> 1179 <source>Videos Recently Added</source>
1206 <target>Vídeos Adicionados Recentemente</target> 1180 <target>Vídeos Adicionados Recentemente</target>
1207 <context-group name="null"> 1181 <context-group name="null">
1208 <context context-type="linenumber">60</context> 1182 <context context-type="linenumber">53</context>
1209 </context-group> 1183 </context-group>
1210 </trans-unit> 1184 </trans-unit>
1211 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1185 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1212 <source>Local videos</source> 1186 <source>Local videos</source>
1213 <target>Vídeos locais</target> 1187 <target>Vídeos locais</target>
1214 <context-group name="null"> 1188 <context-group name="null">
1215 <context context-type="linenumber">61</context> 1189 <context context-type="linenumber">54</context>
1216 </context-group> 1190 </context-group>
1217 </trans-unit> 1191 </trans-unit>
1218 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1192 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1219 <source>Policy on videos containing sensitive content</source> 1193 <source>Policy on videos containing sensitive content</source>
1220 <target>Política sobre vídeos que possuem conteúdo sensível</target> 1194 <target>Política sobre vídeos que possuem conteúdo sensível</target>
1221 <context-group name="null"> 1195 <context-group name="null">
1222 <context context-type="linenumber">70</context> 1196 <context context-type="linenumber">61</context>
1223 </context-group> 1197 </context-group>
1224 </trans-unit> 1198 </trans-unit>
1225 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1199 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1254,23 +1228,44 @@
1254 <source>Signup enabled</source> 1228 <source>Signup enabled</source>
1255 <target>Inscrição permitida</target> 1229 <target>Inscrição permitida</target>
1256 <context-group name="null"> 1230 <context-group name="null">
1257 <context context-type="linenumber">93</context> 1231 <context context-type="linenumber">84</context>
1258 </context-group> 1232 </context-group>
1259 </trans-unit> 1233 </trans-unit>
1260 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1234 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1261 <source>Signup requires email verification</source> 1235 <source>Signup requires email verification</source>
1262 <target>Inscrição requer verificação de email</target> 1236 <target>Inscrição requer verificação de email</target>
1263 <context-group name="null"> 1237 <context-group name="null">
1264 <context context-type="linenumber">100</context> 1238 <context context-type="linenumber">91</context>
1265 </context-group> 1239 </context-group>
1266 </trans-unit> 1240 </trans-unit>
1267 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1241 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1268 <source>Signup limit</source> 1242 <source>Signup limit</source>
1269 <target>Limite de inscrições</target> 1243 <target>Limite de inscrições</target>
1270 <context-group name="null"> 1244 <context-group name="null">
1245 <context context-type="linenumber">96</context>
1246 </context-group>
1247 </trans-unit>
1248 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1249 <source>Users</source>
1250 <target>Usuários</target>
1251 <context-group name="null">
1271 <context context-type="linenumber">105</context> 1252 <context context-type="linenumber">105</context>
1272 </context-group> 1253 </context-group>
1273 </trans-unit> 1254 </trans-unit>
1255 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1256 <source>User default video quota</source>
1257 <target>Cota padrão de vídeos do usuário</target>
1258 <context-group name="null">
1259 <context context-type="linenumber">109</context>
1260 </context-group>
1261 </trans-unit>
1262 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1263 <source>User default daily upload limit</source>
1264 <target>Padrão de limite diário de upload</target>
1265 <context-group name="null">
1266 <context context-type="linenumber">121</context>
1267 </context-group>
1268 </trans-unit>
1274 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1269 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1275 <source>Import</source> 1270 <source>Import</source>
1276 <target>Importar</target> 1271 <target>Importar</target>
@@ -1282,42 +1277,21 @@
1282 <source>Video import with a torrent file or a magnet URI enabled</source> 1277 <source>Video import with a torrent file or a magnet URI enabled</source>
1283 <target>Importação de vídeo com um arquivo torrent ou URI magnética habilitada</target> 1278 <target>Importação de vídeo com um arquivo torrent ou URI magnética habilitada</target>
1284 <context-group name="null"> 1279 <context-group name="null">
1285 <context context-type="linenumber">127</context> 1280 <context context-type="linenumber">148</context>
1286 </context-group> 1281 </context-group>
1287 </trans-unit> 1282 </trans-unit>
1288 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1283 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1289 <source>Administrator</source> 1284 <source>Administrator</source>
1290 <target>Administrador</target> 1285 <target>Administrador</target>
1291 <context-group name="null"> 1286 <context-group name="null">
1292 <context context-type="linenumber">131</context> 1287 <context context-type="linenumber">155</context>
1293 </context-group> 1288 </context-group>
1294 </trans-unit> 1289 </trans-unit>
1295 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1290 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1296 <source>Admin email</source> 1291 <source>Admin email</source>
1297 <target>Email de administrador</target> 1292 <target>Email de administrador</target>
1298 <context-group name="null"> 1293 <context-group name="null">
1299 <context context-type="linenumber">134</context> 1294 <context context-type="linenumber">158</context>
1300 </context-group>
1301 </trans-unit>
1302 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1303 <source>Users</source>
1304 <target>Usuários</target>
1305 <context-group name="null">
1306 <context context-type="linenumber">144</context>
1307 </context-group>
1308 </trans-unit>
1309 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1310 <source>User default video quota</source>
1311 <target>Cota padrão de vídeos do usuário</target>
1312 <context-group name="null">
1313 <context context-type="linenumber">147</context>
1314 </context-group>
1315 </trans-unit>
1316 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1317 <source>User default daily upload limit</source>
1318 <target>Padrão de limite diário de upload</target>
1319 <context-group name="null">
1320 <context context-type="linenumber">161</context>
1321 </context-group> 1295 </context-group>
1322 </trans-unit> 1296 </trans-unit>
1323 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1297 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1338,21 +1312,21 @@
1338 <source>Your Twitter username</source> 1312 <source>Your Twitter username</source>
1339 <target>Seu nome de usuário no Twitter</target> 1313 <target>Seu nome de usuário no Twitter</target>
1340 <context-group name="null"> 1314 <context-group name="null">
1341 <context context-type="linenumber">181</context> 1315 <context context-type="linenumber">184</context>
1342 </context-group> 1316 </context-group>
1343 </trans-unit> 1317 </trans-unit>
1344 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1318 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1345 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1319 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1346 <target>Indica a conta Twitter do sítio web ou plataforma em que o conteúdo foi publicado.</target> 1320 <target>Indica a conta Twitter do sítio web ou plataforma em que o conteúdo foi publicado.</target>
1347 <context-group name="null"> 1321 <context-group name="null">
1348 <context context-type="linenumber">184</context> 1322 <context context-type="linenumber">187</context>
1349 </context-group> 1323 </context-group>
1350 </trans-unit> 1324 </trans-unit>
1351 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1325 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1352 <source>Instance whitelisted by Twitter</source> 1326 <source>Instance whitelisted by Twitter</source>
1353 <target>Instância listada como permitida pelo Twitter</target> 1327 <target>Instância listada como permitida pelo Twitter</target>
1354 <context-group name="null"> 1328 <context-group name="null">
1355 <context context-type="linenumber">198</context> 1329 <context context-type="linenumber">199</context>
1356 </context-group> 1330 </context-group>
1357 </trans-unit> 1331 </trans-unit>
1358 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1332 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1366,35 +1340,35 @@
1366 <source>Transcoding</source> 1340 <source>Transcoding</source>
1367 <target>Transcodificação</target> 1341 <target>Transcodificação</target>
1368 <context-group name="null"> 1342 <context-group name="null">
1369 <context context-type="linenumber">210</context> 1343 <context context-type="linenumber">215</context>
1370 </context-group> 1344 </context-group>
1371 </trans-unit> 1345 </trans-unit>
1372 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1346 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1373 <source>Transcoding enabled</source> 1347 <source>Transcoding enabled</source>
1374 <target>Transcodificação ativada</target> 1348 <target>Transcodificação ativada</target>
1375 <context-group name="null"> 1349 <context-group name="null">
1376 <context context-type="linenumber">215</context> 1350 <context context-type="linenumber">221</context>
1377 </context-group> 1351 </context-group>
1378 </trans-unit> 1352 </trans-unit>
1379 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1353 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1380 <source>If you disable transcoding, many videos from your users will not work!</source> 1354 <source>If you disable transcoding, many videos from your users will not work!</source>
1381 <target>Se você desativar a transcodificação, muitos vídeos dos seus usuários não funcionarão!</target> 1355 <target>Se você desativar a transcodificação, muitos vídeos dos seus usuários não funcionarão!</target>
1382 <context-group name="null"> 1356 <context-group name="null">
1383 <context context-type="linenumber">216</context> 1357 <context context-type="linenumber">222</context>
1384 </context-group> 1358 </context-group>
1385 </trans-unit> 1359 </trans-unit>
1386 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1360 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1387 <source>Transcoding threads</source> 1361 <source>Transcoding threads</source>
1388 <target>Threads de transcodificação</target> 1362 <target>Threads de transcodificação</target>
1389 <context-group name="null"> 1363 <context-group name="null">
1390 <context context-type="linenumber">223</context> 1364 <context context-type="linenumber">237</context>
1391 </context-group> 1365 </context-group>
1392 </trans-unit> 1366 </trans-unit>
1393 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1367 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1394 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1368 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1395 <target>Resolução <x id="INTERPOLATION" equiv-text="{{resolution}}"/> habilitada</target> 1369 <target>Resolução <x id="INTERPOLATION" equiv-text="{{resolution}}"/> habilitada</target>
1396 <context-group name="null"> 1370 <context-group name="null">
1397 <context context-type="linenumber">239</context> 1371 <context context-type="linenumber">252</context>
1398 </context-group> 1372 </context-group>
1399 </trans-unit> 1373 </trans-unit>
1400 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1374 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1409,83 +1383,48 @@
1409 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1383 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1410 </target> 1384 </target>
1411 <context-group name="null"> 1385 <context-group name="null">
1412 <context context-type="linenumber">244</context> 1386 <context context-type="linenumber">260</context>
1413 </context-group> 1387 </context-group>
1414 </trans-unit> 1388 </trans-unit>
1415 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1389 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1416 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1390 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1417 <target>Alguns arquivos não são federados (pré-visualizações, legendas ocultas). Nós as obtivemos diretamente da instância de origem e a colocamos em cache.</target> 1391 <target>Alguns arquivos não são federados (pré-visualizações, legendas ocultas). Nós as obtivemos diretamente da instância de origem e a colocamos em cache.</target>
1418 <context-group name="null"> 1392 <context-group name="null">
1419 <context context-type="linenumber">249</context> 1393 <context context-type="linenumber">265</context>
1420 </context-group> 1394 </context-group>
1421 </trans-unit> 1395 </trans-unit>
1422 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1396 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1423 <source>Previews cache size</source> 1397 <source>Previews cache size</source>
1424 <target>Tamanho do cache de pré-visualizações</target> 1398 <target>Tamanho do cache de pré-visualizações</target>
1425 <context-group name="null"> 1399 <context-group name="null">
1426 <context context-type="linenumber">254</context> 1400 <context context-type="linenumber">271</context>
1427 </context-group> 1401 </context-group>
1428 </trans-unit> 1402 </trans-unit>
1429 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1403 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1430 <source>Video captions cache size</source> 1404 <source>Video captions cache size</source>
1431 <target>Tamanho do cache de legendas ocultas de vídeos</target> 1405 <target>Tamanho do cache de legendas ocultas de vídeos</target>
1432 <context-group name="null"> 1406 <context-group name="null">
1433 <context context-type="linenumber">265</context> 1407 <context context-type="linenumber">280</context>
1434 </context-group> 1408 </context-group>
1435 </trans-unit> 1409 </trans-unit>
1436 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1410 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1437 <source>Customizations</source> 1411 <source>Customizations</source>
1438 <target>Personalizações</target> 1412 <target>Personalizações</target>
1439 <context-group name="null"> 1413 <context-group name="null">
1440 <context context-type="linenumber">275</context> 1414 <context context-type="linenumber">289</context>
1441 </context-group> 1415 </context-group>
1442 </trans-unit> 1416 </trans-unit>
1443 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1417 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1444 <source>JavaScript</source> 1418 <source>JavaScript</source>
1445 <target>JavaScript</target> 1419 <target>JavaScript</target>
1446 <context-group name="null"> 1420 <context-group name="null">
1447 <context context-type="linenumber">278</context> 1421 <context context-type="linenumber">294</context>
1448 </context-group> 1422 </context-group>
1449 </trans-unit> 1423 </trans-unit>
1450 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1424 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1451 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1425 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1452 <target>Escreva diretamente código JavaScript.&lt;br /&gt;Exemplo: &lt;pre&gt;console.log('minha instância é demais');&lt;/pre&gt;</target> 1426 <target>Escreva diretamente código JavaScript.&lt;br /&gt;Exemplo: &lt;pre&gt;console.log('minha instância é demais');&lt;/pre&gt;</target>
1453 <context-group name="null"> 1427 <context-group name="null">
1454 <context context-type="linenumber">281</context>
1455 </context-group>
1456 </trans-unit>
1457 <trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5">
1458 <source>
1459 Write directly CSS code. Example:&lt;br /&gt;
1460 &lt;pre&gt;
1461 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1462 background-color: red;
1463 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1464 &lt;/pre&gt;
1465
1466 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1467 &lt;pre&gt;
1468 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1469 color: red;
1470 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1471 &lt;/pre&gt;
1472 </source>
1473 <target>
1474 Escreva código CSS diretamente. Exemplo:&lt;br /&gt;
1475 &lt;pre&gt;
1476 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1477 background-color: red;
1478 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1479 &lt;/pre&gt;
1480
1481 Preceda com &lt;em&gt;#custom-css&lt;/em&gt; para sobrescrever estilos. Exemplo:
1482 &lt;pre&gt;
1483 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1484 color: red;
1485 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1486 &lt;/pre&gt;
1487 </target>
1488 <context-group name="null">
1489 <context context-type="linenumber">297</context> 1428 <context context-type="linenumber">297</context>
1490 </context-group> 1429 </context-group>
1491 </trans-unit> 1430 </trans-unit>
@@ -1493,21 +1432,21 @@
1493 <source>Advanced configuration</source> 1432 <source>Advanced configuration</source>
1494 <target>Configurações avançadas</target> 1433 <target>Configurações avançadas</target>
1495 <context-group name="null"> 1434 <context-group name="null">
1496 <context context-type="linenumber">207</context> 1435 <context context-type="linenumber">212</context>
1497 </context-group> 1436 </context-group>
1498 </trans-unit> 1437 </trans-unit>
1499 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1438 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1500 <source>Update configuration</source> 1439 <source>Update configuration</source>
1501 <target>Atualizar configuração</target> 1440 <target>Atualizar configuração</target>
1502 <context-group name="null"> 1441 <context-group name="null">
1503 <context context-type="linenumber">325</context> 1442 <context context-type="linenumber">340</context>
1504 </context-group> 1443 </context-group>
1505 </trans-unit> 1444 </trans-unit>
1506 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1445 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1507 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1446 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1508 <target>Aparentemente a configuração está valida. Por favor procure potenciais erros nas diferentes abas.</target> 1447 <target>Aparentemente a configuração está valida. Por favor procure potenciais erros nas diferentes abas.</target>
1509 <context-group name="null"> 1448 <context-group name="null">
1510 <context context-type="linenumber">326</context> 1449 <context context-type="linenumber">341</context>
1511 </context-group> 1450 </context-group>
1512 </trans-unit> 1451 </trans-unit>
1513 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1452 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1761,7 +1700,7 @@
1761 <source>Ban reason:</source> 1700 <source>Ban reason:</source>
1762 <target>Motivo do banimento:</target> 1701 <target>Motivo do banimento:</target>
1763 <context-group name="null"> 1702 <context-group name="null">
1764 <context context-type="linenumber">92</context> 1703 <context context-type="linenumber">95</context>
1765 </context-group> 1704 </context-group>
1766 </trans-unit> 1705 </trans-unit>
1767 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 1706 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -1828,7 +1767,7 @@
1828 <source>Actions</source> 1767 <source>Actions</source>
1829 <target>Ações</target> 1768 <target>Ações</target>
1830 <context-group name="null"> 1769 <context-group name="null">
1831 <context context-type="linenumber">33</context> 1770 <context context-type="linenumber">35</context>
1832 </context-group> 1771 </context-group>
1833 </trans-unit> 1772 </trans-unit>
1834 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 1773 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -1863,14 +1802,14 @@
1863 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 1802 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
1864 <target>Data <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 1803 <target>Data <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
1865 <context-group name="null"> 1804 <context-group name="null">
1866 <context context-type="linenumber">10</context> 1805 <context context-type="linenumber">11</context>
1867 </context-group> 1806 </context-group>
1868 </trans-unit> 1807 </trans-unit>
1869 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f"> 1808 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
1870 <source>Blacklist reason:</source> 1809 <source>Blacklist reason:</source>
1871 <target>Motivo da lista negra:</target> 1810 <target>Motivo da lista negra:</target>
1872 <context-group name="null"> 1811 <context-group name="null">
1873 <context context-type="linenumber">41</context> 1812 <context context-type="linenumber">43</context>
1874 </context-group> 1813 </context-group>
1875 </trans-unit> 1814 </trans-unit>
1876 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 1815 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -1894,55 +1833,6 @@
1894 <context context-type="linenumber">7</context> 1833 <context context-type="linenumber">7</context>
1895 </context-group> 1834 </context-group>
1896 </trans-unit> 1835 </trans-unit>
1897 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
1898 <source>My settings</source>
1899 <target>Minhas configurações</target>
1900 <context-group name="null">
1901 <context context-type="linenumber">3</context>
1902 </context-group>
1903 </trans-unit>
1904 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
1905 <source>My library</source>
1906 <target>Minha biblioteca</target>
1907 <context-group name="null">
1908 <context context-type="linenumber">7</context>
1909 </context-group>
1910 </trans-unit>
1911 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
1912 <source>My channels</source>
1913 <target>Meus canais</target>
1914 <context-group name="null">
1915 <context context-type="linenumber">12</context>
1916 </context-group>
1917 </trans-unit>
1918 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
1919 <source>My videos</source>
1920 <target>Meus vídeos</target>
1921 <context-group name="null">
1922 <context context-type="linenumber">14</context>
1923 </context-group>
1924 </trans-unit>
1925 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
1926 <source>My subscriptions</source>
1927 <target>Minhas inscrições</target>
1928 <context-group name="null">
1929 <context context-type="linenumber">16</context>
1930 </context-group>
1931 </trans-unit>
1932 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
1933 <source>My imports</source>
1934 <target>Minhas importações</target>
1935 <context-group name="null">
1936 <context context-type="linenumber">18</context>
1937 </context-group>
1938 </trans-unit>
1939 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
1940 <source>Ownership changes</source>
1941 <target>Mudanças de dono</target>
1942 <context-group name="null">
1943 <context context-type="linenumber">33</context>
1944 </context-group>
1945 </trans-unit>
1946 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 1836 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
1947 <source>Video quota:</source> 1837 <source>Video quota:</source>
1948 <target>Cota de vídeo:</target> 1838 <target>Cota de vídeo:</target>
@@ -1954,21 +1844,21 @@
1954 <source>Profile</source> 1844 <source>Profile</source>
1955 <target>Perfil</target> 1845 <target>Perfil</target>
1956 <context-group name="null"> 1846 <context-group name="null">
1957 <context context-type="linenumber">8</context> 1847 <context context-type="linenumber">7</context>
1958 </context-group> 1848 </context-group>
1959 </trans-unit> 1849 </trans-unit>
1960 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 1850 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
1961 <source>Video settings</source> 1851 <source>Video settings</source>
1962 <target>Configurações de vídeo</target> 1852 <target>Configurações de vídeo</target>
1963 <context-group name="null"> 1853 <context-group name="null">
1964 <context context-type="linenumber">15</context> 1854 <context context-type="linenumber">16</context>
1965 </context-group> 1855 </context-group>
1966 </trans-unit> 1856 </trans-unit>
1967 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 1857 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
1968 <source>Danger zone</source> 1858 <source>Danger zone</source>
1969 <target>Zona perigosa</target> 1859 <target>Zona perigosa</target>
1970 <context-group name="null"> 1860 <context-group name="null">
1971 <context context-type="linenumber">18</context> 1861 <context context-type="linenumber">19</context>
1972 </context-group> 1862 </context-group>
1973 </trans-unit> 1863 </trans-unit>
1974 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 1864 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -1996,13 +1886,6 @@
1996 <context context-type="linenumber">35</context> 1886 <context context-type="linenumber">35</context>
1997 </context-group> 1887 </context-group>
1998 </trans-unit> 1888 </trans-unit>
1999 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
2000 <source>Submit</source>
2001 <target>Enviar</target>
2002 <context-group name="null">
2003 <context context-type="linenumber">24</context>
2004 </context-group>
2005 </trans-unit>
2006 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 1889 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
2007 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 1890 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2008 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> visualizações</target> 1891 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> visualizações</target>
@@ -2162,6 +2045,13 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
2162 <context context-type="linenumber">30</context> 2045 <context context-type="linenumber">30</context>
2163 </context-group> 2046 </context-group>
2164 </trans-unit> 2047 </trans-unit>
2048 <trans-unit id="0dd390d056411e1709ec97ec51c46d78600e3f7b">
2049 <source>Current password</source>
2050 <target>Senha atual</target>
2051 <context-group name="null">
2052 <context context-type="linenumber">7</context>
2053 </context-group>
2054 </trans-unit>
2165 <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229"> 2055 <trans-unit id="e70e209561583f360b1e9cefd2cbb1fe434b6229">
2166 <source>New password</source> 2056 <source>New password</source>
2167 <target>Nova senha</target> 2057 <target>Nova senha</target>
@@ -2368,14 +2258,14 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
2368 <source>Publish will be available when upload is finished</source> 2258 <source>Publish will be available when upload is finished</source>
2369 <target>A publicação estará disponível quando o envio terminar</target> 2259 <target>A publicação estará disponível quando o envio terminar</target>
2370 <context-group name="null"> 2260 <context-group name="null">
2371 <context context-type="linenumber">53</context> 2261 <context context-type="linenumber">58</context>
2372 </context-group> 2262 </context-group>
2373 </trans-unit> 2263 </trans-unit>
2374 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 2264 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2375 <source>Publish</source> 2265 <source>Publish</source>
2376 <target>Publicar</target> 2266 <target>Publicar</target>
2377 <context-group name="null"> 2267 <context-group name="null">
2378 <context context-type="linenumber">60</context> 2268 <context context-type="linenumber">65</context>
2379 </context-group> 2269 </context-group>
2380 </trans-unit> 2270 </trans-unit>
2381 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 2271 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -2537,14 +2427,14 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
2537 <source>Wait transcoding before publishing the video</source> 2427 <source>Wait transcoding before publishing the video</source>
2538 <target>Aguarde a transcodificação antes de publicar o vídeo</target> 2428 <target>Aguarde a transcodificação antes de publicar o vídeo</target>
2539 <context-group name="null"> 2429 <context-group name="null">
2540 <context context-type="linenumber">130</context> 2430 <context context-type="linenumber">131</context>
2541 </context-group> 2431 </context-group>
2542 </trans-unit> 2432 </trans-unit>
2543 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 2433 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2544 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 2434 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
2545 <target>Se você decidir não aguardar a transcodificação antes de publicar o vídeo, ele poderá não ser reproduzido até que a transcodificação termine.</target> 2435 <target>Se você decidir não aguardar a transcodificação antes de publicar o vídeo, ele poderá não ser reproduzido até que a transcodificação termine.</target>
2546 <context-group name="null"> 2436 <context-group name="null">
2547 <context context-type="linenumber">131</context> 2437 <context context-type="linenumber">132</context>
2548 </context-group> 2438 </context-group>
2549 </trans-unit> 2439 </trans-unit>
2550 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2440 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2558,49 +2448,49 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
2558 <source>Add another caption</source> 2448 <source>Add another caption</source>
2559 <target>Adicionar outra legenda oculta</target> 2449 <target>Adicionar outra legenda oculta</target>
2560 <context-group name="null"> 2450 <context-group name="null">
2561 <context context-type="linenumber">146</context> 2451 <context context-type="linenumber">147</context>
2562 </context-group> 2452 </context-group>
2563 </trans-unit> 2453 </trans-unit>
2564 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 2454 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2565 <source>See the subtitle file</source> 2455 <source>See the subtitle file</source>
2566 <target>Veja o arquivo de legenda</target> 2456 <target>Veja o arquivo de legenda</target>
2567 <context-group name="null"> 2457 <context-group name="null">
2568 <context context-type="linenumber">155</context> 2458 <context context-type="linenumber">156</context>
2569 </context-group> 2459 </context-group>
2570 </trans-unit> 2460 </trans-unit>
2571 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 2461 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2572 <source>Cancel create</source> 2462 <source>Cancel create</source>
2573 <target>Cancelar criação</target> 2463 <target>Cancelar criação</target>
2574 <context-group name="null"> 2464 <context-group name="null">
2575 <context context-type="linenumber">169</context> 2465 <context context-type="linenumber">170</context>
2576 </context-group> 2466 </context-group>
2577 </trans-unit> 2467 </trans-unit>
2578 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 2468 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2579 <source>Cancel deletion</source> 2469 <source>Cancel deletion</source>
2580 <target>Cancelar exclusão</target> 2470 <target>Cancelar exclusão</target>
2581 <context-group name="null"> 2471 <context-group name="null">
2582 <context context-type="linenumber">177</context> 2472 <context context-type="linenumber">178</context>
2583 </context-group> 2473 </context-group>
2584 </trans-unit> 2474 </trans-unit>
2585 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 2475 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2586 <source>Captions</source> 2476 <source>Captions</source>
2587 <target>Legendas ocultas</target> 2477 <target>Legendas ocultas</target>
2588 <context-group name="null"> 2478 <context-group name="null">
2589 <context context-type="linenumber">139</context> 2479 <context context-type="linenumber">140</context>
2590 </context-group> 2480 </context-group>
2591 </trans-unit> 2481 </trans-unit>
2592 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 2482 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
2593 <source>Upload thumbnail</source> 2483 <source>Upload thumbnail</source>
2594 <target>Enviar miniatura</target> 2484 <target>Enviar miniatura</target>
2595 <context-group name="null"> 2485 <context-group name="null">
2596 <context context-type="linenumber">195</context> 2486 <context context-type="linenumber">196</context>
2597 </context-group> 2487 </context-group>
2598 </trans-unit> 2488 </trans-unit>
2599 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 2489 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
2600 <source>Upload preview</source> 2490 <source>Upload preview</source>
2601 <target>Enviar pré-visualização</target> 2491 <target>Enviar pré-visualização</target>
2602 <context-group name="null"> 2492 <context-group name="null">
2603 <context context-type="linenumber">202</context> 2493 <context context-type="linenumber">203</context>
2604 </context-group> 2494 </context-group>
2605 </trans-unit> 2495 </trans-unit>
2606 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 2496 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -2614,14 +2504,14 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
2614 <source>Short text to tell people how they can support you (membership platform...).</source> 2504 <source>Short text to tell people how they can support you (membership platform...).</source>
2615 <target>Texto curto para dizer às pessoas como elas podem apoiar você (plataforma de membros, etc.).</target> 2505 <target>Texto curto para dizer às pessoas como elas podem apoiar você (plataforma de membros, etc.).</target>
2616 <context-group name="null"> 2506 <context-group name="null">
2617 <context context-type="linenumber">209</context> 2507 <context context-type="linenumber">210</context>
2618 </context-group> 2508 </context-group>
2619 </trans-unit> 2509 </trans-unit>
2620 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 2510 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
2621 <source>Advanced settings</source> 2511 <source>Advanced settings</source>
2622 <target>Configurações avançadas</target> 2512 <target>Configurações avançadas</target>
2623 <context-group name="null"> 2513 <context-group name="null">
2624 <context context-type="linenumber">190</context> 2514 <context context-type="linenumber">191</context>
2625 </context-group> 2515 </context-group>
2626 </trans-unit> 2516 </trans-unit>
2627 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 2517 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -2688,17 +2578,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
2688 <context context-type="linenumber">3</context> 2578 <context context-type="linenumber">3</context>
2689 </context-group> 2579 </context-group>
2690 </trans-unit> 2580 </trans-unit>
2691 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
2692 <source>
2693 Cancel
2694 </source>
2695 <target>
2696 Cancelar
2697 </target>
2698 <context-group name="null">
2699 <context context-type="linenumber">19</context>
2700 </context-group>
2701 </trans-unit>
2702 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 2581 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
2703 <source>Share</source> 2582 <source>Share</source>
2704 <target>Compartilhar</target> 2583 <target>Compartilhar</target>
@@ -3034,13 +2913,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3034 <context context-type="linenumber">14</context> 2913 <context context-type="linenumber">14</context>
3035 </context-group> 2914 </context-group>
3036 </trans-unit> 2915 </trans-unit>
3037 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
3038 <source>Error getting about from server</source>
3039 <target>Erro ao obter detalhes do servidor</target>
3040 <context-group name="null">
3041 <context context-type="linenumber">1</context>
3042 </context-group>
3043 </trans-unit>
3044 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 2916 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
3045 <source>No description</source> 2917 <source>No description</source>
3046 <target>Nenhuma descrição</target> 2918 <target>Nenhuma descrição</target>
@@ -3062,20 +2934,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3062 <context context-type="linenumber">1</context> 2934 <context context-type="linenumber">1</context>
3063 </context-group> 2935 </context-group>
3064 </trans-unit> 2936 </trans-unit>
3065 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
3066 <source>Error</source>
3067 <target>Erro</target>
3068 <context-group name="null">
3069 <context context-type="linenumber">1</context>
3070 </context-group>
3071 </trans-unit>
3072 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
3073 <source>Success</source>
3074 <target>Sucesso</target>
3075 <context-group name="null">
3076 <context context-type="linenumber">1</context>
3077 </context-group>
3078 </trans-unit>
3079 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 2937 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
3080 <source>Configuration updated.</source> 2938 <source>Configuration updated.</source>
3081 <target>Configuração atualizada.</target> 2939 <target>Configuração atualizada.</target>
@@ -3328,23 +3186,16 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3328 <context context-type="linenumber">1</context> 3186 <context context-type="linenumber">1</context>
3329 </context-group> 3187 </context-group>
3330 </trans-unit> 3188 </trans-unit>
3331 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 3189 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
3332 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 3190 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
3333 <target>Você realmente deseja excluir <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? Isso também excluirá todos os vídeos enviados neste canal.</target> 3191 <target>Canal de vídeo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> excluído.</target>
3334 <context-group name="null">
3335 <context context-type="linenumber">1</context>
3336 </context-group>
3337 </trans-unit>
3338 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
3339 <source>Please type the name of the video channel to confirm</source>
3340 <target>Por favor, digite o nome do canal de vídeo para confirmar</target>
3341 <context-group name="null"> 3192 <context-group name="null">
3342 <context context-type="linenumber">1</context> 3193 <context context-type="linenumber">1</context>
3343 </context-group> 3194 </context-group>
3344 </trans-unit> 3195 </trans-unit>
3345 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 3196 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
3346 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 3197 <source>My videos</source>
3347 <target>Canal de vídeo <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> excluído.</target> 3198 <target>Meus vídeos</target>
3348 <context-group name="null"> 3199 <context-group name="null">
3349 <context context-type="linenumber">1</context> 3200 <context context-type="linenumber">1</context>
3350 </context-group> 3201 </context-group>
@@ -3419,16 +3270,37 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3419 <context context-type="linenumber">1</context> 3270 <context context-type="linenumber">1</context>
3420 </context-group> 3271 </context-group>
3421 </trans-unit> 3272 </trans-unit>
3422 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 3273 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
3423 <source>Channels</source> 3274 <source>My library</source>
3424 <target>Canais</target> 3275 <target>Minha biblioteca</target>
3425 <context-group name="null"> 3276 <context-group name="null">
3426 <context context-type="linenumber">1</context> 3277 <context context-type="linenumber">1</context>
3427 </context-group> 3278 </context-group>
3428 </trans-unit> 3279 </trans-unit>
3429 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d"> 3280 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
3430 <source>Video imports</source> 3281 <source>My channels</source>
3431 <target>Importações de vídeos</target> 3282 <target>Meus canais</target>
3283 <context-group name="null">
3284 <context context-type="linenumber">1</context>
3285 </context-group>
3286 </trans-unit>
3287 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
3288 <source>My subscriptions</source>
3289 <target>Minhas inscrições</target>
3290 <context-group name="null">
3291 <context context-type="linenumber">1</context>
3292 </context-group>
3293 </trans-unit>
3294 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
3295 <source>Ownership changes</source>
3296 <target>Mudanças de dono</target>
3297 <context-group name="null">
3298 <context context-type="linenumber">1</context>
3299 </context-group>
3300 </trans-unit>
3301 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
3302 <source>My settings</source>
3303 <target>Minhas configurações</target>
3432 <context-group name="null"> 3304 <context-group name="null">
3433 <context context-type="linenumber">1</context> 3305 <context context-type="linenumber">1</context>
3434 </context-group> 3306 </context-group>
@@ -3463,6 +3335,13 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3463 <context context-type="linenumber">1</context> 3335 <context context-type="linenumber">1</context>
3464 </context-group> 3336 </context-group>
3465 </trans-unit> 3337 </trans-unit>
3338 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
3339 <source>Error</source>
3340 <target>Erro</target>
3341 <context-group name="null">
3342 <context context-type="linenumber">1</context>
3343 </context-group>
3344 </trans-unit>
3466 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 3345 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
3467 <source>You need to reconnect.</source> 3346 <source>You need to reconnect.</source>
3468 <target>você precisa se reconectar.</target> 3347 <target>você precisa se reconectar.</target>
@@ -3477,6 +3356,20 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3477 <context context-type="linenumber">1</context> 3356 <context context-type="linenumber">1</context>
3478 </context-group> 3357 </context-group>
3479 </trans-unit> 3358 </trans-unit>
3359 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
3360 <source>Info</source>
3361 <target>Info</target>
3362 <context-group name="null">
3363 <context context-type="linenumber">1</context>
3364 </context-group>
3365 </trans-unit>
3366 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
3367 <source>Success</source>
3368 <target>Sucesso</target>
3369 <context-group name="null">
3370 <context context-type="linenumber">1</context>
3371 </context-group>
3372 </trans-unit>
3480 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 3373 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
3481 <source>Incorrect username or password.</source> 3374 <source>Incorrect username or password.</source>
3482 <target>Nome de usuário ou senha incorretos.</target> 3375 <target>Nome de usuário ou senha incorretos.</target>
@@ -3694,6 +3587,20 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3694 <context context-type="linenumber">1</context> 3587 <context context-type="linenumber">1</context>
3695 </context-group> 3588 </context-group>
3696 </trans-unit> 3589 </trans-unit>
3590 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
3591 <source>Email is required.</source>
3592 <target>E-mail é necessário.</target>
3593 <context-group name="null">
3594 <context context-type="linenumber">1</context>
3595 </context-group>
3596 </trans-unit>
3597 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
3598 <source>Email must be valid.</source>
3599 <target>E-mail deve ser válido.</target>
3600 <context-group name="null">
3601 <context context-type="linenumber">1</context>
3602 </context-group>
3603 </trans-unit>
3697 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 3604 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
3698 <source>Username is required.</source> 3605 <source>Username is required.</source>
3699 <target>Nome de usuário é necessário.</target> 3606 <target>Nome de usuário é necessário.</target>
@@ -3715,41 +3622,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3715 <context context-type="linenumber">1</context> 3622 <context context-type="linenumber">1</context>
3716 </context-group> 3623 </context-group>
3717 </trans-unit> 3624 </trans-unit>
3718 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
3719 <source>Username must be at least 3 characters long.</source>
3720 <target>Nome de usuário deve ter pelo menos 3 caracteres.</target>
3721 <context-group name="null">
3722 <context context-type="linenumber">1</context>
3723 </context-group>
3724 </trans-unit>
3725 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
3726 <source>Username cannot be more than 20 characters long.</source>
3727 <target>Nome de usuário não pode ter mais que 20 caracteres.</target>
3728 <context-group name="null">
3729 <context context-type="linenumber">1</context>
3730 </context-group>
3731 </trans-unit>
3732 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
3733 <source>Username should be only lowercase alphanumeric characters.</source>
3734 <target>Nome de usuário deve ter apenas caracteres alfanuméricos minúsculos.</target>
3735 <context-group name="null">
3736 <context context-type="linenumber">1</context>
3737 </context-group>
3738 </trans-unit>
3739 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
3740 <source>Email is required.</source>
3741 <target>E-mail é necessário.</target>
3742 <context-group name="null">
3743 <context context-type="linenumber">1</context>
3744 </context-group>
3745 </trans-unit>
3746 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
3747 <source>Email must be valid.</source>
3748 <target>E-mail deve ser válido.</target>
3749 <context-group name="null">
3750 <context context-type="linenumber">1</context>
3751 </context-group>
3752 </trans-unit>
3753 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 3625 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
3754 <source>Password must be at least 6 characters long.</source> 3626 <source>Password must be at least 6 characters long.</source>
3755 <target>Senha deve ter pelo menos 6 caracteres.</target> 3627 <target>Senha deve ter pelo menos 6 caracteres.</target>
@@ -3813,20 +3685,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3813 <context context-type="linenumber">1</context> 3685 <context context-type="linenumber">1</context>
3814 </context-group> 3686 </context-group>
3815 </trans-unit> 3687 </trans-unit>
3816 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
3817 <source>Display name must be at least 3 characters long.</source>
3818 <target>Nome de exibição deve ter pelo menos 3 caracteres.</target>
3819 <context-group name="null">
3820 <context context-type="linenumber">1</context>
3821 </context-group>
3822 </trans-unit>
3823 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
3824 <source>Display name cannot be more than 120 characters long.</source>
3825 <target>Nome de exibição não pode ter mais que 120 caracteres.</target>
3826 <context-group name="null">
3827 <context context-type="linenumber">1</context>
3828 </context-group>
3829 </trans-unit>
3830 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 3688 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
3831 <source>Description must be at least 3 characters long.</source> 3689 <source>Description must be at least 3 characters long.</source>
3832 <target>Descrição deve ter pelo menos 3 caracteres.</target> 3690 <target>Descrição deve ter pelo menos 3 caracteres.</target>
@@ -3869,13 +3727,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3869 <context context-type="linenumber">1</context> 3727 <context context-type="linenumber">1</context>
3870 </context-group> 3728 </context-group>
3871 </trans-unit> 3729 </trans-unit>
3872 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
3873 <source>Report reason cannot be more than 300 characters long.</source>
3874 <target>Motivo da denúncia não pode ter mais que 300 caracteres.</target>
3875 <context-group name="null">
3876 <context context-type="linenumber">1</context>
3877 </context-group>
3878 </trans-unit>
3879 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118"> 3730 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
3880 <source>Moderation comment is required.</source> 3731 <source>Moderation comment is required.</source>
3881 <target>Comentário de moderação é obrigatório.</target> 3732 <target>Comentário de moderação é obrigatório.</target>
@@ -3890,13 +3741,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3890 <context context-type="linenumber">1</context> 3741 <context context-type="linenumber">1</context>
3891 </context-group> 3742 </context-group>
3892 </trans-unit> 3743 </trans-unit>
3893 <trans-unit id="89d0b662dde0871cf17244e79b2cb62cd517e44f">
3894 <source>Moderation comment cannot be more than 300 characters long.</source>
3895 <target>Comentário de moderação não pode ter mais de 300 caracteres.</target>
3896 <context-group name="null">
3897 <context context-type="linenumber">1</context>
3898 </context-group>
3899 </trans-unit>
3900 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6"> 3744 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
3901 <source>The channel is required.</source> 3745 <source>The channel is required.</source>
3902 <target>O canal é obrigatório.</target> 3746 <target>O canal é obrigatório.</target>
@@ -3946,27 +3790,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
3946 <context context-type="linenumber">1</context> 3790 <context context-type="linenumber">1</context>
3947 </context-group> 3791 </context-group>
3948 </trans-unit> 3792 </trans-unit>
3949 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069">
3950 <source>Name must be at least 3 characters long.</source>
3951 <target>Nome deve ter pelo menos 3 caracteres.</target>
3952 <context-group name="null">
3953 <context context-type="linenumber">1</context>
3954 </context-group>
3955 </trans-unit>
3956 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482">
3957 <source>Name cannot be more than 20 characters long.</source>
3958 <target>Nome não pode ter mais de 20 caracteres.</target>
3959 <context-group name="null">
3960 <context context-type="linenumber">1</context>
3961 </context-group>
3962 </trans-unit>
3963 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9">
3964 <source>Name should be only lowercase alphanumeric characters.</source>
3965 <target>Nome deve ser apenas caracteres alfanuméricos minúsculos.</target>
3966 <context-group name="null">
3967 <context context-type="linenumber">1</context>
3968 </context-group>
3969 </trans-unit>
3970 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 3793 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
3971 <source>Support text must be at least 3 characters long.</source> 3794 <source>Support text must be at least 3 characters long.</source>
3972 <target>Texto de apoio deve ter pelo menos 3 caracteres.</target> 3795 <target>Texto de apoio deve ter pelo menos 3 caracteres.</target>
@@ -4646,13 +4469,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
4646 <context context-type="linenumber">1</context> 4469 <context context-type="linenumber">1</context>
4647 </context-group> 4470 </context-group>
4648 </trans-unit> 4471 </trans-unit>
4649 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
4650 <source>Subscribed</source>
4651 <target>Inscrito</target>
4652 <context-group name="null">
4653 <context context-type="linenumber">1</context>
4654 </context-group>
4655 </trans-unit>
4656 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded"> 4472 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
4657 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source> 4473 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
4658 <target>Inscrito em <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target> 4474 <target>Inscrito em <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
@@ -4660,9 +4476,9 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
4660 <context context-type="linenumber">1</context> 4476 <context context-type="linenumber">1</context>
4661 </context-group> 4477 </context-group>
4662 </trans-unit> 4478 </trans-unit>
4663 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471"> 4479 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
4664 <source>Unsubscribed</source> 4480 <source>Subscribed</source>
4665 <target>Desinscrito</target> 4481 <target>Inscrito</target>
4666 <context-group name="null"> 4482 <context-group name="null">
4667 <context context-type="linenumber">1</context> 4483 <context context-type="linenumber">1</context>
4668 </context-group> 4484 </context-group>
@@ -4674,6 +4490,13 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
4674 <context context-type="linenumber">1</context> 4490 <context context-type="linenumber">1</context>
4675 </context-group> 4491 </context-group>
4676 </trans-unit> 4492 </trans-unit>
4493 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
4494 <source>Unsubscribed</source>
4495 <target>Desinscrito</target>
4496 <context-group name="null">
4497 <context context-type="linenumber">1</context>
4498 </context-group>
4499 </trans-unit>
4677 <trans-unit id="d4195053fd38eacf6dee1fc507296928978cc8fb"> 4500 <trans-unit id="d4195053fd38eacf6dee1fc507296928978cc8fb">
4678 <source>Only I can see this video</source> 4501 <source>Only I can see this video</source>
4679 <target>Apenas eu posso ver este vídeo</target> 4502 <target>Apenas eu posso ver este vídeo</target>
@@ -4723,13 +4546,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
4723 <context context-type="linenumber">1</context> 4546 <context context-type="linenumber">1</context>
4724 </context-group> 4547 </context-group>
4725 </trans-unit> 4548 </trans-unit>
4726 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4727 <source>Info</source>
4728 <target>Info</target>
4729 <context-group name="null">
4730 <context context-type="linenumber">1</context>
4731 </context-group>
4732 </trans-unit>
4733 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 4549 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
4734 <source>Upload cancelled</source> 4550 <source>Upload cancelled</source>
4735 <target>Envio cancelado</target> 4551 <target>Envio cancelado</target>
@@ -4737,13 +4553,6 @@ Quando você enviar um vídeo neste canal, o campo de apoio a vídeo será preen
4737 <context context-type="linenumber">1</context> 4553 <context context-type="linenumber">1</context>
4738 </context-group> 4554 </context-group>
4739 </trans-unit> 4555 </trans-unit>
4740 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa">
4741 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
4742 <target>Lamentamos, mas o PeerTube não consegue lidar com vídeos&gt; 8GB</target>
4743 <context-group name="null">
4744 <context context-type="linenumber">1</context>
4745 </context-group>
4746 </trans-unit>
4747 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee"> 4556 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
4748 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source> 4557 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
4749 <target>Sua quota de vídeos é excedida com este vídeo (tamanho do vídeo: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, utilizado: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target> 4558 <target>Sua quota de vídeos é excedida com este vídeo (tamanho do vídeo: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, utilizado: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
diff --git a/client/src/locale/target/angular_ru_RU.xml b/client/src/locale/target/angular_ru_RU.xml
index db2a690d5..b3e2afb96 100644
--- a/client/src/locale/target/angular_ru_RU.xml
+++ b/client/src/locale/target/angular_ru_RU.xml
@@ -356,7 +356,7 @@
356 <source>Password</source> 356 <source>Password</source>
357 <target>Пароль</target> 357 <target>Пароль</target>
358 <context-group name="null"> 358 <context-group name="null">
359 <context context-type="linenumber">12</context> 359 <context context-type="linenumber">13</context>
360 </context-group> 360 </context-group>
361 </trans-unit> 361 </trans-unit>
362 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 362 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -370,7 +370,7 @@
370 <source>Login</source> 370 <source>Login</source>
371 <target>ÐвторизациÑ</target> 371 <target>ÐвторизациÑ</target>
372 <context-group name="null"> 372 <context-group name="null">
373 <context context-type="linenumber">38</context> 373 <context context-type="linenumber">36</context>
374 </context-group> 374 </context-group>
375 </trans-unit> 375 </trans-unit>
376 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 376 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -398,7 +398,7 @@
398 <source>Send me an email to reset my password</source> 398 <source>Send me an email to reset my password</source>
399 <target>Отправить пароль на Ñлектронную почту</target> 399 <target>Отправить пароль на Ñлектронную почту</target>
400 <context-group name="null"> 400 <context-group name="null">
401 <context context-type="linenumber">75</context> 401 <context context-type="linenumber">80</context>
402 </context-group> 402 </context-group>
403 </trans-unit> 403 </trans-unit>
404 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 404 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -462,7 +462,7 @@
462 <source>Signup</source> 462 <source>Signup</source>
463 <target>ЗарегиÑтрироватьÑÑ</target> 463 <target>ЗарегиÑтрироватьÑÑ</target>
464 <context-group name="null"> 464 <context-group name="null">
465 <context context-type="linenumber">88</context> 465 <context context-type="linenumber">78</context>
466 </context-group> 466 </context-group>
467 </trans-unit> 467 </trans-unit>
468 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 468 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -519,7 +519,7 @@
519 <source>Change the language</source> 519 <source>Change the language</source>
520 <target>Изменить Ñзык</target> 520 <target>Изменить Ñзык</target>
521 <context-group name="null"> 521 <context-group name="null">
522 <context context-type="linenumber">88</context> 522 <context context-type="linenumber">86</context>
523 </context-group> 523 </context-group>
524 </trans-unit> 524 </trans-unit>
525 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 525 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -530,7 +530,7 @@
530 Мой побличный профиль 530 Мой побличный профиль
531 </target> 531 </target>
532 <context-group name="null"> 532 <context-group name="null">
533 <context context-type="linenumber">18</context> 533 <context context-type="linenumber">16</context>
534 </context-group> 534 </context-group>
535 </trans-unit> 535 </trans-unit>
536 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 536 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -541,7 +541,7 @@
541 ÐœÐ¾Ñ ÑƒÑ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ 541 ÐœÐ¾Ñ ÑƒÑ‡ÐµÑ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ
542 </target> 542 </target>
543 <context-group name="null"> 543 <context-group name="null">
544 <context context-type="linenumber">22</context> 544 <context context-type="linenumber">20</context>
545 </context-group> 545 </context-group>
546 </trans-unit> 546 </trans-unit>
547 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 547 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -552,7 +552,7 @@
552 Мои видео 552 Мои видео
553 </target> 553 </target>
554 <context-group name="null"> 554 <context-group name="null">
555 <context context-type="linenumber">26</context> 555 <context context-type="linenumber">24</context>
556 </context-group> 556 </context-group>
557 </trans-unit> 557 </trans-unit>
558 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 558 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -563,14 +563,14 @@
563 Выйти 563 Выйти
564 </target> 564 </target>
565 <context-group name="null"> 565 <context-group name="null">
566 <context context-type="linenumber">30</context> 566 <context context-type="linenumber">28</context>
567 </context-group> 567 </context-group>
568 </trans-unit> 568 </trans-unit>
569 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 569 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
570 <source>Create an account</source> 570 <source>Create an account</source>
571 <target>Создать учетную запиÑÑŒ</target> 571 <target>Создать учетную запиÑÑŒ</target>
572 <context-group name="null"> 572 <context-group name="null">
573 <context context-type="linenumber">39</context> 573 <context context-type="linenumber">37</context>
574 </context-group> 574 </context-group>
575 </trans-unit> 575 </trans-unit>
576 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 576 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -584,49 +584,49 @@
584 <source>Subscriptions</source> 584 <source>Subscriptions</source>
585 <target>ПодпиÑки</target> 585 <target>ПодпиÑки</target>
586 <context-group name="null"> 586 <context-group name="null">
587 <context context-type="linenumber">47</context> 587 <context context-type="linenumber">45</context>
588 </context-group> 588 </context-group>
589 </trans-unit> 589 </trans-unit>
590 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 590 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
591 <source>Overview</source> 591 <source>Overview</source>
592 <target>Общий вид</target> 592 <target>Общий вид</target>
593 <context-group name="null"> 593 <context-group name="null">
594 <context context-type="linenumber">52</context> 594 <context context-type="linenumber">50</context>
595 </context-group> 595 </context-group>
596 </trans-unit> 596 </trans-unit>
597 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 597 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
598 <source>Trending</source> 598 <source>Trending</source>
599 <target>Тенденции</target> 599 <target>Тенденции</target>
600 <context-group name="null"> 600 <context-group name="null">
601 <context context-type="linenumber">57</context> 601 <context context-type="linenumber">55</context>
602 </context-group> 602 </context-group>
603 </trans-unit> 603 </trans-unit>
604 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 604 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
605 <source>Recently added</source> 605 <source>Recently added</source>
606 <target>Ðедавно добавленный </target> 606 <target>Ðедавно добавленный </target>
607 <context-group name="null"> 607 <context-group name="null">
608 <context context-type="linenumber">62</context> 608 <context context-type="linenumber">60</context>
609 </context-group> 609 </context-group>
610 </trans-unit> 610 </trans-unit>
611 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 611 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
612 <source>Local</source> 612 <source>Local</source>
613 <target>Локальный</target> 613 <target>Локальный</target>
614 <context-group name="null"> 614 <context-group name="null">
615 <context context-type="linenumber">67</context> 615 <context context-type="linenumber">65</context>
616 </context-group> 616 </context-group>
617 </trans-unit> 617 </trans-unit>
618 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 618 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
619 <source>More</source> 619 <source>More</source>
620 <target>Больше</target> 620 <target>Больше</target>
621 <context-group name="null"> 621 <context-group name="null">
622 <context context-type="linenumber">72</context> 622 <context context-type="linenumber">70</context>
623 </context-group> 623 </context-group>
624 </trans-unit> 624 </trans-unit>
625 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 625 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
626 <source>Administration</source> 626 <source>Administration</source>
627 <target>ÐдминиÑтрациÑ</target> 627 <target>ÐдминиÑтрациÑ</target>
628 <context-group name="null"> 628 <context-group name="null">
629 <context context-type="linenumber">76</context> 629 <context context-type="linenumber">74</context>
630 </context-group> 630 </context-group>
631 </trans-unit> 631 </trans-unit>
632 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 632 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -640,7 +640,7 @@
640 <source>Toggle dark interface</source> 640 <source>Toggle dark interface</source>
641 <target>Изменить интерфейÑ</target> 641 <target>Изменить интерфейÑ</target>
642 <context-group name="null"> 642 <context-group name="null">
643 <context context-type="linenumber">94</context> 643 <context context-type="linenumber">92</context>
644 </context-group> 644 </context-group>
645 </trans-unit> 645 </trans-unit>
646 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 646 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -745,7 +745,7 @@
745 <source>No results.</source> 745 <source>No results.</source>
746 <target>Ðет результатов</target> 746 <target>Ðет результатов</target>
747 <context-group name="null"> 747 <context-group name="null">
748 <context context-type="linenumber">17</context> 748 <context context-type="linenumber">20</context>
749 </context-group> 749 </context-group>
750 </trans-unit> 750 </trans-unit>
751 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 751 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -792,15 +792,11 @@
792 <context context-type="linenumber">7</context> 792 <context context-type="linenumber">7</context>
793 </context-group> 793 </context-group>
794 </trans-unit> 794 </trans-unit>
795 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 795 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
796 <source> 796 <source>Submit</source>
797 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 797 <target>Отправить</target>
798</source>
799 <target>
800 О <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> ИнÑтанци
801</target>
802 <context-group name="null"> 798 <context-group name="null">
803 <context context-type="linenumber">1</context> 799 <context context-type="linenumber">31</context>
804 </context-group> 800 </context-group>
805 </trans-unit> 801 </trans-unit>
806 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 802 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -814,47 +810,14 @@
814 <source>Terms</source> 810 <source>Terms</source>
815 <target>УÑÐ»Ð¾Ð²Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ </target> 811 <target>УÑÐ»Ð¾Ð²Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ </target>
816 <context-group name="null"> 812 <context-group name="null">
817 <context context-type="linenumber">44</context> 813 <context context-type="linenumber">39</context>
818 </context-group> 814 </context-group>
819 </trans-unit> 815 </trans-unit>
820 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 816 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
821 <source>User registration is allowed and</source> 817 <source>User registration is allowed and</source>
822 <target>Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑƒÑ‡ÐµÑ‚Ð½Ð¾Ð¹ запиÑи разрешено и</target> 818 <target>Ð¡Ð¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑƒÑ‡ÐµÑ‚Ð½Ð¾Ð¹ запиÑи разрешено и</target>
823 <context-group name="null"> 819 <context-group name="null">
824 <context context-type="linenumber">25</context> 820 <context context-type="linenumber">29</context>
825 </context-group>
826 </trans-unit>
827 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
828 <source>
829 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
830 </source>
831 <target>
832 Ñтот Ñервер предоÑтавлÑет <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> меÑта Ð´Ð»Ñ Ð²Ð¸Ð´ÐµÐ¾ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹.
833 </target>
834 <context-group name="null">
835 <context context-type="linenumber">27</context>
836 </context-group>
837 </trans-unit>
838 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
839 <source>
840 this instance provides unlimited space for the videos of its users.
841 </source>
842 <target>
843 Ñтот Ñервер предоÑтавлÑет неограниченное меÑто Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹.
844 </target>
845 <context-group name="null">
846 <context context-type="linenumber">31</context>
847 </context-group>
848 </trans-unit>
849 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
850 <source>
851 User registration is currently not allowed.
852 </source>
853 <target>
854 Создание учетной запиÑи не разрешено в данный момент.
855 </target>
856 <context-group name="null">
857 <context context-type="linenumber">36</context>
858 </context-group> 821 </context-group>
859 </trans-unit> 822 </trans-unit>
860 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 823 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1163,49 +1126,49 @@
1163 <source>Short description</source> 1126 <source>Short description</source>
1164 <target>Краткое опиÑание</target> 1127 <target>Краткое опиÑание</target>
1165 <context-group name="null"> 1128 <context-group name="null">
1166 <context context-type="linenumber">22</context> 1129 <context context-type="linenumber">21</context>
1167 </context-group> 1130 </context-group>
1168 </trans-unit> 1131 </trans-unit>
1169 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1132 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1170 <source>Default client route</source> 1133 <source>Default client route</source>
1171 <target>Default client route</target> 1134 <target>Default client route</target>
1172 <context-group name="null"> 1135 <context-group name="null">
1173 <context context-type="linenumber">55</context> 1136 <context context-type="linenumber">48</context>
1174 </context-group> 1137 </context-group>
1175 </trans-unit> 1138 </trans-unit>
1176 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1139 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1177 <source>Videos Overview</source> 1140 <source>Videos Overview</source>
1178 <target>Ð’Ñе видео</target> 1141 <target>Ð’Ñе видео</target>
1179 <context-group name="null"> 1142 <context-group name="null">
1180 <context context-type="linenumber">58</context> 1143 <context context-type="linenumber">51</context>
1181 </context-group> 1144 </context-group>
1182 </trans-unit> 1145 </trans-unit>
1183 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1146 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1184 <source>Videos Trending</source> 1147 <source>Videos Trending</source>
1185 <target>Тенденции видео</target> 1148 <target>Тенденции видео</target>
1186 <context-group name="null"> 1149 <context-group name="null">
1187 <context context-type="linenumber">59</context> 1150 <context context-type="linenumber">52</context>
1188 </context-group> 1151 </context-group>
1189 </trans-unit> 1152 </trans-unit>
1190 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1153 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1191 <source>Videos Recently Added</source> 1154 <source>Videos Recently Added</source>
1192 <target>Ðедавно добавленное видео</target> 1155 <target>Ðедавно добавленное видео</target>
1193 <context-group name="null"> 1156 <context-group name="null">
1194 <context context-type="linenumber">60</context> 1157 <context context-type="linenumber">53</context>
1195 </context-group> 1158 </context-group>
1196 </trans-unit> 1159 </trans-unit>
1197 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1160 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1198 <source>Local videos</source> 1161 <source>Local videos</source>
1199 <target>МеÑтное видео</target> 1162 <target>МеÑтное видео</target>
1200 <context-group name="null"> 1163 <context-group name="null">
1201 <context context-type="linenumber">61</context> 1164 <context context-type="linenumber">54</context>
1202 </context-group> 1165 </context-group>
1203 </trans-unit> 1166 </trans-unit>
1204 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1167 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1205 <source>Policy on videos containing sensitive content</source> 1168 <source>Policy on videos containing sensitive content</source>
1206 <target>Политика каÑательно видео Ñодержащих нежелательный контент</target> 1169 <target>Политика каÑательно видео Ñодержащих нежелательный контент</target>
1207 <context-group name="null"> 1170 <context-group name="null">
1208 <context context-type="linenumber">70</context> 1171 <context context-type="linenumber">61</context>
1209 </context-group> 1172 </context-group>
1210 </trans-unit> 1173 </trans-unit>
1211 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1174 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1240,23 +1203,44 @@
1240 <source>Signup enabled</source> 1203 <source>Signup enabled</source>
1241 <target>РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð°</target> 1204 <target>РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð°ÐºÑ‚Ð¸Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð°</target>
1242 <context-group name="null"> 1205 <context-group name="null">
1243 <context context-type="linenumber">93</context> 1206 <context context-type="linenumber">84</context>
1244 </context-group> 1207 </context-group>
1245 </trans-unit> 1208 </trans-unit>
1246 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1209 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1247 <source>Signup requires email verification</source> 1210 <source>Signup requires email verification</source>
1248 <target>Ð”Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации нужно подтвержение через Ñлектронную почту</target> 1211 <target>Ð”Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации нужно подтвержение через Ñлектронную почту</target>
1249 <context-group name="null"> 1212 <context-group name="null">
1250 <context context-type="linenumber">100</context> 1213 <context context-type="linenumber">91</context>
1251 </context-group> 1214 </context-group>
1252 </trans-unit> 1215 </trans-unit>
1253 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1216 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1254 <source>Signup limit</source> 1217 <source>Signup limit</source>
1255 <target>Лимит региÑтрации</target> 1218 <target>Лимит региÑтрации</target>
1256 <context-group name="null"> 1219 <context-group name="null">
1220 <context context-type="linenumber">96</context>
1221 </context-group>
1222 </trans-unit>
1223 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1224 <source>Users</source>
1225 <target>Пользователи</target>
1226 <context-group name="null">
1257 <context context-type="linenumber">105</context> 1227 <context context-type="linenumber">105</context>
1258 </context-group> 1228 </context-group>
1259 </trans-unit> 1229 </trans-unit>
1230 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1231 <source>User default video quota</source>
1232 <target>Квота видео по умолчанию на одного пользователÑ</target>
1233 <context-group name="null">
1234 <context context-type="linenumber">109</context>
1235 </context-group>
1236 </trans-unit>
1237 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1238 <source>User default daily upload limit</source>
1239 <target>Ежедневный лимит загрузок по умолчанию на одгого пользователÑ</target>
1240 <context-group name="null">
1241 <context context-type="linenumber">121</context>
1242 </context-group>
1243 </trans-unit>
1260 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1244 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1261 <source>Import</source> 1245 <source>Import</source>
1262 <target>Импортировать</target> 1246 <target>Импортировать</target>
@@ -1268,42 +1252,21 @@
1268 <source>Video import with a torrent file or a magnet URI enabled</source> 1252 <source>Video import with a torrent file or a magnet URI enabled</source>
1269 <target>Импорт видео Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ файла торент или magnet URI активирован</target> 1253 <target>Импорт видео Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ файла торент или magnet URI активирован</target>
1270 <context-group name="null"> 1254 <context-group name="null">
1271 <context context-type="linenumber">127</context> 1255 <context context-type="linenumber">148</context>
1272 </context-group> 1256 </context-group>
1273 </trans-unit> 1257 </trans-unit>
1274 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1258 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1275 <source>Administrator</source> 1259 <source>Administrator</source>
1276 <target>ÐдминиÑтратор</target> 1260 <target>ÐдминиÑтратор</target>
1277 <context-group name="null"> 1261 <context-group name="null">
1278 <context context-type="linenumber">131</context> 1262 <context context-type="linenumber">155</context>
1279 </context-group> 1263 </context-group>
1280 </trans-unit> 1264 </trans-unit>
1281 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1265 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1282 <source>Admin email</source> 1266 <source>Admin email</source>
1283 <target>Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð° админиÑтратора</target> 1267 <target>Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ñ‡Ñ‚Ð° админиÑтратора</target>
1284 <context-group name="null"> 1268 <context-group name="null">
1285 <context context-type="linenumber">134</context> 1269 <context context-type="linenumber">158</context>
1286 </context-group>
1287 </trans-unit>
1288 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1289 <source>Users</source>
1290 <target>Пользователи</target>
1291 <context-group name="null">
1292 <context context-type="linenumber">144</context>
1293 </context-group>
1294 </trans-unit>
1295 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1296 <source>User default video quota</source>
1297 <target>Квота видео по умолчанию на одного пользователÑ</target>
1298 <context-group name="null">
1299 <context context-type="linenumber">147</context>
1300 </context-group>
1301 </trans-unit>
1302 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1303 <source>User default daily upload limit</source>
1304 <target>Ежедневный лимит загрузок по умолчанию на одгого пользователÑ</target>
1305 <context-group name="null">
1306 <context context-type="linenumber">161</context>
1307 </context-group> 1270 </context-group>
1308 </trans-unit> 1271 </trans-unit>
1309 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1272 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1324,21 +1287,21 @@
1324 <source>Your Twitter username</source> 1287 <source>Your Twitter username</source>
1325 <target>Ваше Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð² Twitter</target> 1288 <target>Ваше Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð² Twitter</target>
1326 <context-group name="null"> 1289 <context-group name="null">
1327 <context context-type="linenumber">181</context> 1290 <context context-type="linenumber">184</context>
1328 </context-group> 1291 </context-group>
1329 </trans-unit> 1292 </trans-unit>
1330 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1293 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1331 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1294 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1332 <target>Показывает учетнаю запиÑÑŒ в Twitter Ñайта или платформы Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… было опубликован контент</target> 1295 <target>Показывает учетнаю запиÑÑŒ в Twitter Ñайта или платформы Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… было опубликован контент</target>
1333 <context-group name="null"> 1296 <context-group name="null">
1334 <context context-type="linenumber">184</context> 1297 <context context-type="linenumber">187</context>
1335 </context-group> 1298 </context-group>
1336 </trans-unit> 1299 </trans-unit>
1337 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1300 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1338 <source>Instance whitelisted by Twitter</source> 1301 <source>Instance whitelisted by Twitter</source>
1339 <target>Сервер имеет аккредитацию Twitter</target> 1302 <target>Сервер имеет аккредитацию Twitter</target>
1340 <context-group name="null"> 1303 <context-group name="null">
1341 <context context-type="linenumber">198</context> 1304 <context context-type="linenumber">199</context>
1342 </context-group> 1305 </context-group>
1343 </trans-unit> 1306 </trans-unit>
1344 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1307 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1352,35 +1315,35 @@
1352 <source>Transcoding</source> 1315 <source>Transcoding</source>
1353 <target>ТранÑкодирование</target> 1316 <target>ТранÑкодирование</target>
1354 <context-group name="null"> 1317 <context-group name="null">
1355 <context context-type="linenumber">210</context> 1318 <context context-type="linenumber">215</context>
1356 </context-group> 1319 </context-group>
1357 </trans-unit> 1320 </trans-unit>
1358 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1321 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1359 <source>Transcoding enabled</source> 1322 <source>Transcoding enabled</source>
1360 <target>ТранÑкодирование активировано</target> 1323 <target>ТранÑкодирование активировано</target>
1361 <context-group name="null"> 1324 <context-group name="null">
1362 <context context-type="linenumber">215</context> 1325 <context context-type="linenumber">221</context>
1363 </context-group> 1326 </context-group>
1364 </trans-unit> 1327 </trans-unit>
1365 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1328 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1366 <source>If you disable transcoding, many videos from your users will not work!</source> 1329 <source>If you disable transcoding, many videos from your users will not work!</source>
1367 <target>ЕÑли вы дезактивируете транÑкодирование, многие видео пользователей переÑтанут работать</target> 1330 <target>ЕÑли вы дезактивируете транÑкодирование, многие видео пользователей переÑтанут работать</target>
1368 <context-group name="null"> 1331 <context-group name="null">
1369 <context context-type="linenumber">216</context> 1332 <context context-type="linenumber">222</context>
1370 </context-group> 1333 </context-group>
1371 </trans-unit> 1334 </trans-unit>
1372 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1335 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1373 <source>Transcoding threads</source> 1336 <source>Transcoding threads</source>
1374 <target>КоличеÑтво threads Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½ÑкодированиÑ</target> 1337 <target>КоличеÑтво threads Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½ÑкодированиÑ</target>
1375 <context-group name="null"> 1338 <context-group name="null">
1376 <context context-type="linenumber">223</context> 1339 <context context-type="linenumber">237</context>
1377 </context-group> 1340 </context-group>
1378 </trans-unit> 1341 </trans-unit>
1379 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1342 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1380 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1343 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1381 <target>Разрешение <x id="INTERPOLATION" equiv-text="{{resolution}}"/> активировано</target> 1344 <target>Разрешение <x id="INTERPOLATION" equiv-text="{{resolution}}"/> активировано</target>
1382 <context-group name="null"> 1345 <context-group name="null">
1383 <context context-type="linenumber">239</context> 1346 <context context-type="linenumber">252</context>
1384 </context-group> 1347 </context-group>
1385 </trans-unit> 1348 </trans-unit>
1386 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1349 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1395,83 +1358,48 @@
1395 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1358 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1396 </target> 1359 </target>
1397 <context-group name="null"> 1360 <context-group name="null">
1398 <context context-type="linenumber">244</context> 1361 <context context-type="linenumber">260</context>
1399 </context-group> 1362 </context-group>
1400 </trans-unit> 1363 </trans-unit>
1401 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1364 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1402 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1365 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1403 <target>Ðекоторые миниатюры не федератные (миниатюры, названиÑ). Они взÑÑ‚Ñ‹ непоÑредÑтвенно из их оригинального Ñервера и мы их не храним.</target> 1366 <target>Ðекоторые миниатюры не федератные (миниатюры, названиÑ). Они взÑÑ‚Ñ‹ непоÑредÑтвенно из их оригинального Ñервера и мы их не храним.</target>
1404 <context-group name="null"> 1367 <context-group name="null">
1405 <context context-type="linenumber">249</context> 1368 <context context-type="linenumber">265</context>
1406 </context-group> 1369 </context-group>
1407 </trans-unit> 1370 </trans-unit>
1408 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1371 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1409 <source>Previews cache size</source> 1372 <source>Previews cache size</source>
1410 <target>Размер кеша предпроÑмотра</target> 1373 <target>Размер кеша предпроÑмотра</target>
1411 <context-group name="null"> 1374 <context-group name="null">
1412 <context context-type="linenumber">254</context> 1375 <context context-type="linenumber">271</context>
1413 </context-group> 1376 </context-group>
1414 </trans-unit> 1377 </trans-unit>
1415 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1378 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1416 <source>Video captions cache size</source> 1379 <source>Video captions cache size</source>
1417 <target>Размер кеша предпроÑмотра надпиÑей</target> 1380 <target>Размер кеша предпроÑмотра надпиÑей</target>
1418 <context-group name="null"> 1381 <context-group name="null">
1419 <context context-type="linenumber">265</context> 1382 <context context-type="linenumber">280</context>
1420 </context-group> 1383 </context-group>
1421 </trans-unit> 1384 </trans-unit>
1422 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1385 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1423 <source>Customizations</source> 1386 <source>Customizations</source>
1424 <target>ПерÑонализациÑ</target> 1387 <target>ПерÑонализациÑ</target>
1425 <context-group name="null"> 1388 <context-group name="null">
1426 <context context-type="linenumber">275</context> 1389 <context context-type="linenumber">289</context>
1427 </context-group> 1390 </context-group>
1428 </trans-unit> 1391 </trans-unit>
1429 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1392 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1430 <source>JavaScript</source> 1393 <source>JavaScript</source>
1431 <target>Ява Скрипт</target> 1394 <target>Ява Скрипт</target>
1432 <context-group name="null"> 1395 <context-group name="null">
1433 <context context-type="linenumber">278</context> 1396 <context context-type="linenumber">294</context>
1434 </context-group> 1397 </context-group>
1435 </trans-unit> 1398 </trans-unit>
1436 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1399 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1437 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1400 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1438 <target>Ðапишите непоÑредÑтвенно код Ява Скрипта .&lt;br /&gt;Пример : &lt;pre&gt;console.log('мой Ñервер крут');&lt;/pre&gt;</target> 1401 <target>Ðапишите непоÑредÑтвенно код Ява Скрипта .&lt;br /&gt;Пример : &lt;pre&gt;console.log('мой Ñервер крут');&lt;/pre&gt;</target>
1439 <context-group name="null"> 1402 <context-group name="null">
1440 <context context-type="linenumber">281</context>
1441 </context-group>
1442 </trans-unit>
1443 <trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5">
1444 <source>
1445 Write directly CSS code. Example:&lt;br /&gt;
1446 &lt;pre&gt;
1447 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1448 background-color: red;
1449 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1450 &lt;/pre&gt;
1451
1452 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1453 &lt;pre&gt;
1454 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1455 color: red;
1456 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1457 &lt;/pre&gt;
1458 </source>
1459 <target>
1460 Ðапишите непоÑредÑтвенно код CSS. Пример:&lt;br /&gt;
1461 &lt;pre&gt;
1462 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1463 background-color: red;
1464 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1465 &lt;/pre&gt;
1466
1467 Ðачните Ñ &lt;em&gt;#custom-css&lt;/em&gt; чтоб получить приоритет. Пример:
1468 &lt;pre&gt;
1469 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1470 color: red;
1471 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1472 &lt;/pre&gt;
1473 </target>
1474 <context-group name="null">
1475 <context context-type="linenumber">297</context> 1403 <context context-type="linenumber">297</context>
1476 </context-group> 1404 </context-group>
1477 </trans-unit> 1405 </trans-unit>
@@ -1479,21 +1407,21 @@
1479 <source>Advanced configuration</source> 1407 <source>Advanced configuration</source>
1480 <target>ÐŸÑ€Ð¾Ð´Ð²Ð¸Ð½ÑƒÑ‚Ð°Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ</target> 1408 <target>ÐŸÑ€Ð¾Ð´Ð²Ð¸Ð½ÑƒÑ‚Ð°Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ</target>
1481 <context-group name="null"> 1409 <context-group name="null">
1482 <context context-type="linenumber">207</context> 1410 <context context-type="linenumber">212</context>
1483 </context-group> 1411 </context-group>
1484 </trans-unit> 1412 </trans-unit>
1485 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1413 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1486 <source>Update configuration</source> 1414 <source>Update configuration</source>
1487 <target>Обновить конфигурацию</target> 1415 <target>Обновить конфигурацию</target>
1488 <context-group name="null"> 1416 <context-group name="null">
1489 <context context-type="linenumber">325</context> 1417 <context context-type="linenumber">340</context>
1490 </context-group> 1418 </context-group>
1491 </trans-unit> 1419 </trans-unit>
1492 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1420 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1493 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1421 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1494 <target>ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð½ÐµÑƒÐ´Ð°Ñ‡Ð½Ð°Ñ. ПожалуйÑта, найдите потенциальную ошибку в разных окнах. </target> 1422 <target>ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð½ÐµÑƒÐ´Ð°Ñ‡Ð½Ð°Ñ. ПожалуйÑта, найдите потенциальную ошибку в разных окнах. </target>
1495 <context-group name="null"> 1423 <context-group name="null">
1496 <context context-type="linenumber">326</context> 1424 <context context-type="linenumber">341</context>
1497 </context-group> 1425 </context-group>
1498 </trans-unit> 1426 </trans-unit>
1499 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1427 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1740,7 +1668,7 @@
1740 <source>Ban reason:</source> 1668 <source>Ban reason:</source>
1741 <target>Причины бана:</target> 1669 <target>Причины бана:</target>
1742 <context-group name="null"> 1670 <context-group name="null">
1743 <context context-type="linenumber">92</context> 1671 <context context-type="linenumber">95</context>
1744 </context-group> 1672 </context-group>
1745 </trans-unit> 1673 </trans-unit>
1746 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 1674 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -1807,7 +1735,7 @@
1807 <source>Actions</source> 1735 <source>Actions</source>
1808 <target>ДейÑтвиÑ</target> 1736 <target>ДейÑтвиÑ</target>
1809 <context-group name="null"> 1737 <context-group name="null">
1810 <context context-type="linenumber">33</context> 1738 <context context-type="linenumber">35</context>
1811 </context-group> 1739 </context-group>
1812 </trans-unit> 1740 </trans-unit>
1813 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 1741 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -1842,14 +1770,14 @@
1842 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 1770 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
1843 <target>Дата <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 1771 <target>Дата <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
1844 <context-group name="null"> 1772 <context-group name="null">
1845 <context context-type="linenumber">10</context> 1773 <context context-type="linenumber">11</context>
1846 </context-group> 1774 </context-group>
1847 </trans-unit> 1775 </trans-unit>
1848 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f"> 1776 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
1849 <source>Blacklist reason:</source> 1777 <source>Blacklist reason:</source>
1850 <target>Причина блокированиÑ:</target> 1778 <target>Причина блокированиÑ:</target>
1851 <context-group name="null"> 1779 <context-group name="null">
1852 <context context-type="linenumber">41</context> 1780 <context context-type="linenumber">43</context>
1853 </context-group> 1781 </context-group>
1854 </trans-unit> 1782 </trans-unit>
1855 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 1783 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -1873,55 +1801,6 @@
1873 <context context-type="linenumber">7</context> 1801 <context context-type="linenumber">7</context>
1874 </context-group> 1802 </context-group>
1875 </trans-unit> 1803 </trans-unit>
1876 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
1877 <source>My settings</source>
1878 <target>Мои наÑтройки</target>
1879 <context-group name="null">
1880 <context context-type="linenumber">3</context>
1881 </context-group>
1882 </trans-unit>
1883 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
1884 <source>My library</source>
1885 <target>ÐœÐ¾Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ°</target>
1886 <context-group name="null">
1887 <context context-type="linenumber">7</context>
1888 </context-group>
1889 </trans-unit>
1890 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
1891 <source>My channels</source>
1892 <target>Мои каналы</target>
1893 <context-group name="null">
1894 <context context-type="linenumber">12</context>
1895 </context-group>
1896 </trans-unit>
1897 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
1898 <source>My videos</source>
1899 <target>Мои видео</target>
1900 <context-group name="null">
1901 <context context-type="linenumber">14</context>
1902 </context-group>
1903 </trans-unit>
1904 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
1905 <source>My subscriptions</source>
1906 <target>Мои подпиÑки</target>
1907 <context-group name="null">
1908 <context context-type="linenumber">16</context>
1909 </context-group>
1910 </trans-unit>
1911 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
1912 <source>My imports</source>
1913 <target>Мои импортированные видео</target>
1914 <context-group name="null">
1915 <context context-type="linenumber">18</context>
1916 </context-group>
1917 </trans-unit>
1918 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
1919 <source>Ownership changes</source>
1920 <target>Смена ÑобÑтвенника</target>
1921 <context-group name="null">
1922 <context context-type="linenumber">33</context>
1923 </context-group>
1924 </trans-unit>
1925 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 1804 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
1926 <source>Video quota:</source> 1805 <source>Video quota:</source>
1927 <target>Квота видео</target> 1806 <target>Квота видео</target>
@@ -1933,21 +1812,21 @@
1933 <source>Profile</source> 1812 <source>Profile</source>
1934 <target>Профиль</target> 1813 <target>Профиль</target>
1935 <context-group name="null"> 1814 <context-group name="null">
1936 <context context-type="linenumber">8</context> 1815 <context context-type="linenumber">7</context>
1937 </context-group> 1816 </context-group>
1938 </trans-unit> 1817 </trans-unit>
1939 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 1818 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
1940 <source>Video settings</source> 1819 <source>Video settings</source>
1941 <target>ÐаÑтройки видео</target> 1820 <target>ÐаÑтройки видео</target>
1942 <context-group name="null"> 1821 <context-group name="null">
1943 <context context-type="linenumber">15</context> 1822 <context context-type="linenumber">16</context>
1944 </context-group> 1823 </context-group>
1945 </trans-unit> 1824 </trans-unit>
1946 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 1825 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
1947 <source>Danger zone</source> 1826 <source>Danger zone</source>
1948 <target>ОраÑÐ½Ð°Ñ Ð·Ð¾Ð½Ð°</target> 1827 <target>ОраÑÐ½Ð°Ñ Ð·Ð¾Ð½Ð°</target>
1949 <context-group name="null"> 1828 <context-group name="null">
1950 <context context-type="linenumber">18</context> 1829 <context context-type="linenumber">19</context>
1951 </context-group> 1830 </context-group>
1952 </trans-unit> 1831 </trans-unit>
1953 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 1832 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -1975,13 +1854,6 @@
1975 <context context-type="linenumber">35</context> 1854 <context context-type="linenumber">35</context>
1976 </context-group> 1855 </context-group>
1977 </trans-unit> 1856 </trans-unit>
1978 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
1979 <source>Submit</source>
1980 <target>Отправить</target>
1981 <context-group name="null">
1982 <context context-type="linenumber">24</context>
1983 </context-group>
1984 </trans-unit>
1985 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 1857 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
1986 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 1858 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
1987 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> проÑмотры</target> 1859 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> проÑмотры</target>
@@ -2279,6 +2151,48 @@ When you will upload a video in this channel, the video support field will be au
2279 <context context-type="linenumber">17</context> 2151 <context context-type="linenumber">17</context>
2280 </context-group> 2152 </context-group>
2281 </trans-unit> 2153 </trans-unit>
2154 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2155 <source>My videos</source>
2156 <target>Мои видео</target>
2157 <context-group name="null">
2158 <context context-type="linenumber">1</context>
2159 </context-group>
2160 </trans-unit>
2161 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2162 <source>My library</source>
2163 <target>ÐœÐ¾Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ°</target>
2164 <context-group name="null">
2165 <context context-type="linenumber">1</context>
2166 </context-group>
2167 </trans-unit>
2168 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2169 <source>My channels</source>
2170 <target>Мои каналы</target>
2171 <context-group name="null">
2172 <context context-type="linenumber">1</context>
2173 </context-group>
2174 </trans-unit>
2175 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2176 <source>My subscriptions</source>
2177 <target>Мои подпиÑки</target>
2178 <context-group name="null">
2179 <context context-type="linenumber">1</context>
2180 </context-group>
2181 </trans-unit>
2182 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
2183 <source>Ownership changes</source>
2184 <target>Смена ÑобÑтвенника</target>
2185 <context-group name="null">
2186 <context context-type="linenumber">1</context>
2187 </context-group>
2188 </trans-unit>
2189 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2190 <source>My settings</source>
2191 <target>Мои наÑтройки</target>
2192 <context-group name="null">
2193 <context context-type="linenumber">1</context>
2194 </context-group>
2195 </trans-unit>
2282 <trans-unit id="f15f2e02b1f6a96553e98ea4a969045d17ec1400"> 2196 <trans-unit id="f15f2e02b1f6a96553e98ea4a969045d17ec1400">
2283 <source>Transcoding threads is required.</source> 2197 <source>Transcoding threads is required.</source>
2284 <target>ТранÑкодирование потоки требуетÑÑ.</target> 2198 <target>ТранÑкодирование потоки требуетÑÑ.</target>
@@ -2307,13 +2221,6 @@ When you will upload a video in this channel, the video support field will be au
2307 <context context-type="linenumber">1</context> 2221 <context context-type="linenumber">1</context>
2308 </context-group> 2222 </context-group>
2309 </trans-unit> 2223 </trans-unit>
2310 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
2311 <source>Username must be at least 3 characters long.</source>
2312 <target>Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ быть длиной не менее 3-Ñ… Ñимволов.</target>
2313 <context-group name="null">
2314 <context context-type="linenumber">1</context>
2315 </context-group>
2316 </trans-unit>
2317 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 2224 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
2318 <source>Password must be at least 6 characters long.</source> 2225 <source>Password must be at least 6 characters long.</source>
2319 <target>Пароль должен быть длиной не менее 6 Ñимволов.</target> 2226 <target>Пароль должен быть длиной не менее 6 Ñимволов.</target>
@@ -2321,13 +2228,6 @@ When you will upload a video in this channel, the video support field will be au
2321 <context context-type="linenumber">1</context> 2228 <context context-type="linenumber">1</context>
2322 </context-group> 2229 </context-group>
2323 </trans-unit> 2230 </trans-unit>
2324 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
2325 <source>Display name must be at least 3 characters long.</source>
2326 <target>Отображаемое Ð¸Ð¼Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ иметь длину не менее 3-Ñ… Ñимволов.</target>
2327 <context-group name="null">
2328 <context context-type="linenumber">1</context>
2329 </context-group>
2330 </trans-unit>
2331 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 2231 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
2332 <source>Description must be at least 3 characters long.</source> 2232 <source>Description must be at least 3 characters long.</source>
2333 <target>ОпиÑание должно быть длиной не менее 3-Ñ… Ñимволов.</target> 2233 <target>ОпиÑание должно быть длиной не менее 3-Ñ… Ñимволов.</target>
@@ -2363,13 +2263,6 @@ When you will upload a video in this channel, the video support field will be au
2363 <context context-type="linenumber">1</context> 2263 <context context-type="linenumber">1</context>
2364 </context-group> 2264 </context-group>
2365 </trans-unit> 2265 </trans-unit>
2366 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069">
2367 <source>Name must be at least 3 characters long.</source>
2368 <target>Длина имени должна быть не менее 3 Ñимволов.</target>
2369 <context-group name="null">
2370 <context context-type="linenumber">1</context>
2371 </context-group>
2372 </trans-unit>
2373 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 2266 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
2374 <source>Support text must be at least 3 characters long.</source> 2267 <source>Support text must be at least 3 characters long.</source>
2375 <target>ТекÑÑ‚ поддержки должен Ñодержать не менее 3 Ñимволов.</target> 2268 <target>ТекÑÑ‚ поддержки должен Ñодержать не менее 3 Ñимволов.</target>
diff --git a/client/src/locale/target/angular_sv_SE.xml b/client/src/locale/target/angular_sv_SE.xml
index e30575d80..ffa8b19ca 100644
--- a/client/src/locale/target/angular_sv_SE.xml
+++ b/client/src/locale/target/angular_sv_SE.xml
@@ -499,7 +499,7 @@
499 <source>Password</source> 499 <source>Password</source>
500 <target>Lösenord</target> 500 <target>Lösenord</target>
501 <context-group name="null"> 501 <context-group name="null">
502 <context context-type="linenumber">12</context> 502 <context context-type="linenumber">13</context>
503 </context-group> 503 </context-group>
504 </trans-unit> 504 </trans-unit>
505 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 505 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -513,7 +513,7 @@
513 <source>Login</source> 513 <source>Login</source>
514 <target>Logga in</target> 514 <target>Logga in</target>
515 <context-group name="null"> 515 <context-group name="null">
516 <context context-type="linenumber">38</context> 516 <context context-type="linenumber">36</context>
517 </context-group> 517 </context-group>
518 </trans-unit> 518 </trans-unit>
519 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 519 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -541,7 +541,7 @@
541 <source>Send me an email to reset my password</source> 541 <source>Send me an email to reset my password</source>
542 <target>Skicka ett e-postmeddelande för att återställa mitt lösenord</target> 542 <target>Skicka ett e-postmeddelande för att återställa mitt lösenord</target>
543 <context-group name="null"> 543 <context-group name="null">
544 <context context-type="linenumber">75</context> 544 <context context-type="linenumber">80</context>
545 </context-group> 545 </context-group>
546 </trans-unit> 546 </trans-unit>
547 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 547 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -612,7 +612,7 @@
612 <source>Signup</source> 612 <source>Signup</source>
613 <target>Registrering</target> 613 <target>Registrering</target>
614 <context-group name="null"> 614 <context-group name="null">
615 <context context-type="linenumber">88</context> 615 <context context-type="linenumber">78</context>
616 </context-group> 616 </context-group>
617 </trans-unit> 617 </trans-unit>
618 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 618 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -682,7 +682,7 @@
682 <source>Change the language</source> 682 <source>Change the language</source>
683 <target>Ändra språk</target> 683 <target>Ändra språk</target>
684 <context-group name="null"> 684 <context-group name="null">
685 <context context-type="linenumber">88</context> 685 <context context-type="linenumber">86</context>
686 </context-group> 686 </context-group>
687 </trans-unit> 687 </trans-unit>
688 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 688 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -693,7 +693,7 @@
693 Min offentliga profil 693 Min offentliga profil
694 </target> 694 </target>
695 <context-group name="null"> 695 <context-group name="null">
696 <context context-type="linenumber">18</context> 696 <context context-type="linenumber">16</context>
697 </context-group> 697 </context-group>
698 </trans-unit> 698 </trans-unit>
699 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 699 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -704,7 +704,7 @@
704 Mitt konto 704 Mitt konto
705 </target> 705 </target>
706 <context-group name="null"> 706 <context-group name="null">
707 <context context-type="linenumber">22</context> 707 <context context-type="linenumber">20</context>
708 </context-group> 708 </context-group>
709 </trans-unit> 709 </trans-unit>
710 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 710 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -715,7 +715,7 @@
715 Mina videor 715 Mina videor
716 </target> 716 </target>
717 <context-group name="null"> 717 <context-group name="null">
718 <context context-type="linenumber">26</context> 718 <context context-type="linenumber">24</context>
719 </context-group> 719 </context-group>
720 </trans-unit> 720 </trans-unit>
721 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 721 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -726,14 +726,14 @@
726 Logga ut 726 Logga ut
727 </target> 727 </target>
728 <context-group name="null"> 728 <context-group name="null">
729 <context context-type="linenumber">30</context> 729 <context context-type="linenumber">28</context>
730 </context-group> 730 </context-group>
731 </trans-unit> 731 </trans-unit>
732 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 732 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
733 <source>Create an account</source> 733 <source>Create an account</source>
734 <target>Skapa ett konto</target> 734 <target>Skapa ett konto</target>
735 <context-group name="null"> 735 <context-group name="null">
736 <context context-type="linenumber">39</context> 736 <context context-type="linenumber">37</context>
737 </context-group> 737 </context-group>
738 </trans-unit> 738 </trans-unit>
739 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 739 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -747,49 +747,49 @@
747 <source>Subscriptions</source> 747 <source>Subscriptions</source>
748 <target>Prenumerationer</target> 748 <target>Prenumerationer</target>
749 <context-group name="null"> 749 <context-group name="null">
750 <context context-type="linenumber">47</context> 750 <context context-type="linenumber">45</context>
751 </context-group> 751 </context-group>
752 </trans-unit> 752 </trans-unit>
753 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 753 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
754 <source>Overview</source> 754 <source>Overview</source>
755 <target>Översikt</target> 755 <target>Översikt</target>
756 <context-group name="null"> 756 <context-group name="null">
757 <context context-type="linenumber">52</context> 757 <context context-type="linenumber">50</context>
758 </context-group> 758 </context-group>
759 </trans-unit> 759 </trans-unit>
760 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 760 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
761 <source>Trending</source> 761 <source>Trending</source>
762 <target>Populärt</target> 762 <target>Populärt</target>
763 <context-group name="null"> 763 <context-group name="null">
764 <context context-type="linenumber">57</context> 764 <context context-type="linenumber">55</context>
765 </context-group> 765 </context-group>
766 </trans-unit> 766 </trans-unit>
767 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 767 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
768 <source>Recently added</source> 768 <source>Recently added</source>
769 <target>Nyligen tillagt</target> 769 <target>Nyligen tillagt</target>
770 <context-group name="null"> 770 <context-group name="null">
771 <context context-type="linenumber">62</context> 771 <context context-type="linenumber">60</context>
772 </context-group> 772 </context-group>
773 </trans-unit> 773 </trans-unit>
774 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 774 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
775 <source>Local</source> 775 <source>Local</source>
776 <target>Lokalt</target> 776 <target>Lokalt</target>
777 <context-group name="null"> 777 <context-group name="null">
778 <context context-type="linenumber">67</context> 778 <context context-type="linenumber">65</context>
779 </context-group> 779 </context-group>
780 </trans-unit> 780 </trans-unit>
781 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 781 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
782 <source>More</source> 782 <source>More</source>
783 <target>Mer</target> 783 <target>Mer</target>
784 <context-group name="null"> 784 <context-group name="null">
785 <context context-type="linenumber">72</context> 785 <context context-type="linenumber">70</context>
786 </context-group> 786 </context-group>
787 </trans-unit> 787 </trans-unit>
788 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 788 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
789 <source>Administration</source> 789 <source>Administration</source>
790 <target>Administration</target> 790 <target>Administration</target>
791 <context-group name="null"> 791 <context-group name="null">
792 <context context-type="linenumber">76</context> 792 <context context-type="linenumber">74</context>
793 </context-group> 793 </context-group>
794 </trans-unit> 794 </trans-unit>
795 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 795 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -803,14 +803,14 @@
803 <source>Show keyboard shortcuts</source> 803 <source>Show keyboard shortcuts</source>
804 <target>Visa kortkommandon</target> 804 <target>Visa kortkommandon</target>
805 <context-group name="null"> 805 <context-group name="null">
806 <context context-type="linenumber">91</context> 806 <context context-type="linenumber">89</context>
807 </context-group> 807 </context-group>
808 </trans-unit> 808 </trans-unit>
809 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 809 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
810 <source>Toggle dark interface</source> 810 <source>Toggle dark interface</source>
811 <target>Växla mörkt gränssnitt</target> 811 <target>Växla mörkt gränssnitt</target>
812 <context-group name="null"> 812 <context-group name="null">
813 <context context-type="linenumber">94</context> 813 <context context-type="linenumber">92</context>
814 </context-group> 814 </context-group>
815 </trans-unit> 815 </trans-unit>
816 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 816 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -915,14 +915,14 @@
915 <source>Display unlisted and private videos</source> 915 <source>Display unlisted and private videos</source>
916 <target>Visa olistade och privata videor</target> 916 <target>Visa olistade och privata videor</target>
917 <context-group name="null"> 917 <context-group name="null">
918 <context context-type="linenumber">11</context> 918 <context context-type="linenumber">14</context>
919 </context-group> 919 </context-group>
920 </trans-unit> 920 </trans-unit>
921 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 921 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
922 <source>No results.</source> 922 <source>No results.</source>
923 <target>Inga resultat.</target> 923 <target>Inga resultat.</target>
924 <context-group name="null"> 924 <context-group name="null">
925 <context context-type="linenumber">17</context> 925 <context context-type="linenumber">20</context>
926 </context-group> 926 </context-group>
927 </trans-unit> 927 </trans-unit>
928 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 928 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -980,15 +980,22 @@
980 <context context-type="linenumber">7</context> 980 <context context-type="linenumber">7</context>
981 </context-group> 981 </context-group>
982 </trans-unit> 982 </trans-unit>
983 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 983 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
984 <source> 984 <source>
985 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 985 Cancel
986</source> 986 </source>
987 <target> 987 <target>
988 Om instansen <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> 988 Avbryt
989</target> 989 </target>
990 <context-group name="null"> 990 <context-group name="null">
991 <context context-type="linenumber">1</context> 991 <context context-type="linenumber">26</context>
992 </context-group>
993 </trans-unit>
994 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
995 <source>Submit</source>
996 <target>Skicka</target>
997 <context-group name="null">
998 <context context-type="linenumber">31</context>
992 </context-group> 999 </context-group>
993 </trans-unit> 1000 </trans-unit>
994 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 1001 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -1002,47 +1009,14 @@
1002 <source>Terms</source> 1009 <source>Terms</source>
1003 <target>Villkor</target> 1010 <target>Villkor</target>
1004 <context-group name="null"> 1011 <context-group name="null">
1005 <context context-type="linenumber">44</context> 1012 <context context-type="linenumber">39</context>
1006 </context-group> 1013 </context-group>
1007 </trans-unit> 1014 </trans-unit>
1008 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 1015 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
1009 <source>User registration is allowed and</source> 1016 <source>User registration is allowed and</source>
1010 <target>Användarregistrering är tillåten och</target> 1017 <target>Användarregistrering är tillåten och</target>
1011 <context-group name="null"> 1018 <context-group name="null">
1012 <context context-type="linenumber">25</context> 1019 <context context-type="linenumber">29</context>
1013 </context-group>
1014 </trans-unit>
1015 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
1016 <source>
1017 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
1018 </source>
1019 <target>
1020 den här instansen tillhandahåller en grundkvot på <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> utrymme för sina användares videor.
1021 </target>
1022 <context-group name="null">
1023 <context context-type="linenumber">27</context>
1024 </context-group>
1025 </trans-unit>
1026 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
1027 <source>
1028 this instance provides unlimited space for the videos of its users.
1029 </source>
1030 <target>
1031 den här instansen tillhandahåller obegränsat utrymme för sina användares videor.
1032 </target>
1033 <context-group name="null">
1034 <context context-type="linenumber">31</context>
1035 </context-group>
1036 </trans-unit>
1037 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
1038 <source>
1039 User registration is currently not allowed.
1040 </source>
1041 <target>
1042 Användarregistrering tillåts inte för tillfället.
1043 </target>
1044 <context-group name="null">
1045 <context context-type="linenumber">36</context>
1046 </context-group> 1020 </context-group>
1047 </trans-unit> 1021 </trans-unit>
1048 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 1022 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1319,22 +1293,30 @@
1319 </context-group> 1293 </context-group>
1320 </trans-unit> 1294 </trans-unit>
1321 <trans-unit id="62a557fcfdbd25a31d1a0332294f94a466fee809"> 1295 <trans-unit id="62a557fcfdbd25a31d1a0332294f94a466fee809">
1322 <source>Muted</source><target>Muted</target><context-group name="null"> 1296 <source>Muted</source>
1297 <target>Ignorerad</target>
1298 <context-group name="null">
1323 <context context-type="linenumber">13</context> 1299 <context context-type="linenumber">13</context>
1324 </context-group> 1300 </context-group>
1325 </trans-unit> 1301 </trans-unit>
1326 <trans-unit id="48bbf6dbdb22e0ef4bd257eae2ab356f2ea66c89"> 1302 <trans-unit id="48bbf6dbdb22e0ef4bd257eae2ab356f2ea66c89">
1327 <source>Muted by your instance</source><target>Muted by your instance</target><context-group name="null"> 1303 <source>Muted by your instance</source>
1304 <target>Ignorerad av din instans</target>
1305 <context-group name="null">
1328 <context context-type="linenumber">14</context> 1306 <context context-type="linenumber">14</context>
1329 </context-group> 1307 </context-group>
1330 </trans-unit> 1308 </trans-unit>
1331 <trans-unit id="44bd08a7ec1e407356620967d65d8fe2d8639d0a"> 1309 <trans-unit id="44bd08a7ec1e407356620967d65d8fe2d8639d0a">
1332 <source>Instance muted</source><target>Instance muted</target><context-group name="null"> 1310 <source>Instance muted</source>
1311 <target>Instans ignorerad</target>
1312 <context-group name="null">
1333 <context context-type="linenumber">15</context> 1313 <context context-type="linenumber">15</context>
1334 </context-group> 1314 </context-group>
1335 </trans-unit> 1315 </trans-unit>
1336 <trans-unit id="1a6443bb7ed01046dd83cf78806f795f1204ffa1"> 1316 <trans-unit id="1a6443bb7ed01046dd83cf78806f795f1204ffa1">
1337 <source>Instance muted by your instance</source><target>Instance muted by your instance</target><context-group name="null"> 1317 <source>Instance muted by your instance</source>
1318 <target>Instans ignorerad av din instans</target>
1319 <context-group name="null">
1338 <context context-type="linenumber">16</context> 1320 <context context-type="linenumber">16</context>
1339 </context-group> 1321 </context-group>
1340 </trans-unit> 1322 </trans-unit>
@@ -1391,49 +1373,49 @@
1391 <source>Short description</source> 1373 <source>Short description</source>
1392 <target>Kort beskrivning</target> 1374 <target>Kort beskrivning</target>
1393 <context-group name="null"> 1375 <context-group name="null">
1394 <context context-type="linenumber">22</context> 1376 <context context-type="linenumber">21</context>
1395 </context-group> 1377 </context-group>
1396 </trans-unit> 1378 </trans-unit>
1397 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1379 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1398 <source>Default client route</source> 1380 <source>Default client route</source>
1399 <target>Klientens standardrouting</target> 1381 <target>Klientens standardrouting</target>
1400 <context-group name="null"> 1382 <context-group name="null">
1401 <context context-type="linenumber">55</context> 1383 <context context-type="linenumber">48</context>
1402 </context-group> 1384 </context-group>
1403 </trans-unit> 1385 </trans-unit>
1404 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1386 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1405 <source>Videos Overview</source> 1387 <source>Videos Overview</source>
1406 <target>Videoöversikt</target> 1388 <target>Videoöversikt</target>
1407 <context-group name="null"> 1389 <context-group name="null">
1408 <context context-type="linenumber">58</context> 1390 <context context-type="linenumber">51</context>
1409 </context-group> 1391 </context-group>
1410 </trans-unit> 1392 </trans-unit>
1411 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1393 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1412 <source>Videos Trending</source> 1394 <source>Videos Trending</source>
1413 <target>Populära videor</target> 1395 <target>Populära videor</target>
1414 <context-group name="null"> 1396 <context-group name="null">
1415 <context context-type="linenumber">59</context> 1397 <context context-type="linenumber">52</context>
1416 </context-group> 1398 </context-group>
1417 </trans-unit> 1399 </trans-unit>
1418 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1400 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1419 <source>Videos Recently Added</source> 1401 <source>Videos Recently Added</source>
1420 <target>Nyligen tillagda videor</target> 1402 <target>Nyligen tillagda videor</target>
1421 <context-group name="null"> 1403 <context-group name="null">
1422 <context context-type="linenumber">60</context> 1404 <context context-type="linenumber">53</context>
1423 </context-group> 1405 </context-group>
1424 </trans-unit> 1406 </trans-unit>
1425 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1407 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1426 <source>Local videos</source> 1408 <source>Local videos</source>
1427 <target>Lokala videor</target> 1409 <target>Lokala videor</target>
1428 <context-group name="null"> 1410 <context-group name="null">
1429 <context context-type="linenumber">61</context> 1411 <context context-type="linenumber">54</context>
1430 </context-group> 1412 </context-group>
1431 </trans-unit> 1413 </trans-unit>
1432 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1414 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1433 <source>Policy on videos containing sensitive content</source> 1415 <source>Policy on videos containing sensitive content</source>
1434 <target>Policy för videor med känsligt innehåll</target> 1416 <target>Policy för videor med känsligt innehåll</target>
1435 <context-group name="null"> 1417 <context-group name="null">
1436 <context context-type="linenumber">70</context> 1418 <context context-type="linenumber">61</context>
1437 </context-group> 1419 </context-group>
1438 </trans-unit> 1420 </trans-unit>
1439 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1421 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1468,23 +1450,44 @@
1468 <source>Signup enabled</source> 1450 <source>Signup enabled</source>
1469 <target>Registrering aktiverad</target> 1451 <target>Registrering aktiverad</target>
1470 <context-group name="null"> 1452 <context-group name="null">
1471 <context context-type="linenumber">93</context> 1453 <context context-type="linenumber">84</context>
1472 </context-group> 1454 </context-group>
1473 </trans-unit> 1455 </trans-unit>
1474 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1456 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1475 <source>Signup requires email verification</source> 1457 <source>Signup requires email verification</source>
1476 <target>Registrering kräver e-postverifikation</target> 1458 <target>Registrering kräver e-postverifikation</target>
1477 <context-group name="null"> 1459 <context-group name="null">
1478 <context context-type="linenumber">100</context> 1460 <context context-type="linenumber">91</context>
1479 </context-group> 1461 </context-group>
1480 </trans-unit> 1462 </trans-unit>
1481 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1463 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1482 <source>Signup limit</source> 1464 <source>Signup limit</source>
1483 <target>Registreringsgräns</target> 1465 <target>Registreringsgräns</target>
1484 <context-group name="null"> 1466 <context-group name="null">
1467 <context context-type="linenumber">96</context>
1468 </context-group>
1469 </trans-unit>
1470 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1471 <source>Users</source>
1472 <target>Användare</target>
1473 <context-group name="null">
1485 <context context-type="linenumber">105</context> 1474 <context context-type="linenumber">105</context>
1486 </context-group> 1475 </context-group>
1487 </trans-unit> 1476 </trans-unit>
1477 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1478 <source>User default video quota</source>
1479 <target>Standardkvot för användares videor</target>
1480 <context-group name="null">
1481 <context context-type="linenumber">109</context>
1482 </context-group>
1483 </trans-unit>
1484 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1485 <source>User default daily upload limit</source>
1486 <target>Standarduppladdningsgräns för användare</target>
1487 <context-group name="null">
1488 <context context-type="linenumber">121</context>
1489 </context-group>
1490 </trans-unit>
1488 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1491 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1489 <source>Import</source> 1492 <source>Import</source>
1490 <target>Importera</target> 1493 <target>Importera</target>
@@ -1496,49 +1499,28 @@
1496 <source>Video import with HTTP URL (i.e. YouTube) enabled</source> 1499 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1497 <target>Videoimport med HTTP-URL tillåten (t.ex. YouTube)</target> 1500 <target>Videoimport med HTTP-URL tillåten (t.ex. YouTube)</target>
1498 <context-group name="null"> 1501 <context-group name="null">
1499 <context context-type="linenumber">120</context> 1502 <context context-type="linenumber">141</context>
1500 </context-group> 1503 </context-group>
1501 </trans-unit> 1504 </trans-unit>
1502 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e"> 1505 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e">
1503 <source>Video import with a torrent file or a magnet URI enabled</source> 1506 <source>Video import with a torrent file or a magnet URI enabled</source>
1504 <target>Videoimport med torrentfil eller magnet-URI är tillåten</target> 1507 <target>Videoimport med torrentfil eller magnet-URI är tillåten</target>
1505 <context-group name="null"> 1508 <context-group name="null">
1506 <context context-type="linenumber">127</context> 1509 <context context-type="linenumber">148</context>
1507 </context-group> 1510 </context-group>
1508 </trans-unit> 1511 </trans-unit>
1509 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1512 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1510 <source>Administrator</source> 1513 <source>Administrator</source>
1511 <target>Administratör</target> 1514 <target>Administratör</target>
1512 <context-group name="null"> 1515 <context-group name="null">
1513 <context context-type="linenumber">131</context> 1516 <context context-type="linenumber">155</context>
1514 </context-group> 1517 </context-group>
1515 </trans-unit> 1518 </trans-unit>
1516 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1519 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1517 <source>Admin email</source> 1520 <source>Admin email</source>
1518 <target>Administratörens e-postadress</target> 1521 <target>Administratörens e-postadress</target>
1519 <context-group name="null"> 1522 <context-group name="null">
1520 <context context-type="linenumber">134</context> 1523 <context context-type="linenumber">158</context>
1521 </context-group>
1522 </trans-unit>
1523 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1524 <source>Users</source>
1525 <target>Användare</target>
1526 <context-group name="null">
1527 <context context-type="linenumber">144</context>
1528 </context-group>
1529 </trans-unit>
1530 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1531 <source>User default video quota</source>
1532 <target>Standardkvot för användares videor</target>
1533 <context-group name="null">
1534 <context context-type="linenumber">147</context>
1535 </context-group>
1536 </trans-unit>
1537 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1538 <source>User default daily upload limit</source>
1539 <target>Standarduppladdningsgräns för användare</target>
1540 <context-group name="null">
1541 <context context-type="linenumber">161</context>
1542 </context-group> 1524 </context-group>
1543 </trans-unit> 1525 </trans-unit>
1544 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1526 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1559,21 +1541,21 @@
1559 <source>Your Twitter username</source> 1541 <source>Your Twitter username</source>
1560 <target>Ditt användarnamn på Twitter</target> 1542 <target>Ditt användarnamn på Twitter</target>
1561 <context-group name="null"> 1543 <context-group name="null">
1562 <context context-type="linenumber">181</context> 1544 <context context-type="linenumber">184</context>
1563 </context-group> 1545 </context-group>
1564 </trans-unit> 1546 </trans-unit>
1565 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1547 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1566 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1548 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1567 <target>Webbplatsens eller plattformens Twitterkonto, på vilken innehållet publicerades.</target> 1549 <target>Webbplatsens eller plattformens Twitterkonto, på vilken innehållet publicerades.</target>
1568 <context-group name="null"> 1550 <context-group name="null">
1569 <context context-type="linenumber">184</context> 1551 <context context-type="linenumber">187</context>
1570 </context-group> 1552 </context-group>
1571 </trans-unit> 1553 </trans-unit>
1572 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1554 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1573 <source>Instance whitelisted by Twitter</source> 1555 <source>Instance whitelisted by Twitter</source>
1574 <target>Instans vitlistad av Twitter</target> 1556 <target>Instans vitlistad av Twitter</target>
1575 <context-group name="null"> 1557 <context-group name="null">
1576 <context context-type="linenumber">198</context> 1558 <context context-type="linenumber">199</context>
1577 </context-group> 1559 </context-group>
1578 </trans-unit> 1560 </trans-unit>
1579 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1561 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1587,35 +1569,35 @@
1587 <source>Transcoding</source> 1569 <source>Transcoding</source>
1588 <target>Omkodning</target> 1570 <target>Omkodning</target>
1589 <context-group name="null"> 1571 <context-group name="null">
1590 <context context-type="linenumber">210</context> 1572 <context context-type="linenumber">215</context>
1591 </context-group> 1573 </context-group>
1592 </trans-unit> 1574 </trans-unit>
1593 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1575 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1594 <source>Transcoding enabled</source> 1576 <source>Transcoding enabled</source>
1595 <target>Omkodning aktiverad</target> 1577 <target>Omkodning aktiverad</target>
1596 <context-group name="null"> 1578 <context-group name="null">
1597 <context context-type="linenumber">215</context> 1579 <context context-type="linenumber">221</context>
1598 </context-group> 1580 </context-group>
1599 </trans-unit> 1581 </trans-unit>
1600 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1582 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1601 <source>If you disable transcoding, many videos from your users will not work!</source> 1583 <source>If you disable transcoding, many videos from your users will not work!</source>
1602 <target>Om du avaktiverar omkodning, kommer många av dina användares videor inte fungera!</target> 1584 <target>Om du avaktiverar omkodning, kommer många av dina användares videor inte fungera!</target>
1603 <context-group name="null"> 1585 <context-group name="null">
1604 <context context-type="linenumber">216</context> 1586 <context context-type="linenumber">222</context>
1605 </context-group> 1587 </context-group>
1606 </trans-unit> 1588 </trans-unit>
1607 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1589 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1608 <source>Transcoding threads</source> 1590 <source>Transcoding threads</source>
1609 <target>Omkodningstrådar</target> 1591 <target>Omkodningstrådar</target>
1610 <context-group name="null"> 1592 <context-group name="null">
1611 <context context-type="linenumber">223</context> 1593 <context context-type="linenumber">237</context>
1612 </context-group> 1594 </context-group>
1613 </trans-unit> 1595 </trans-unit>
1614 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1596 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1615 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1597 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1616 <target>Upplösningen <x id="INTERPOLATION" equiv-text="{{resolution}}"/> tillåten</target> 1598 <target>Upplösningen <x id="INTERPOLATION" equiv-text="{{resolution}}"/> tillåten</target>
1617 <context-group name="null"> 1599 <context-group name="null">
1618 <context context-type="linenumber">239</context> 1600 <context context-type="linenumber">252</context>
1619 </context-group> 1601 </context-group>
1620 </trans-unit> 1602 </trans-unit>
1621 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1603 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1630,83 +1612,48 @@
1630 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1612 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1631 </target> 1613 </target>
1632 <context-group name="null"> 1614 <context-group name="null">
1633 <context context-type="linenumber">244</context> 1615 <context context-type="linenumber">260</context>
1634 </context-group> 1616 </context-group>
1635 </trans-unit> 1617 </trans-unit>
1636 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1618 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1637 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1619 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1638 <target>Vissa filer är inte federerade (till exempel förhandsvisningar och undertexter). Vi kan hämta dem direkt från ursprungsinstansen och cachelagra dem.</target> 1620 <target>Vissa filer är inte federerade (till exempel förhandsvisningar och undertexter). Vi kan hämta dem direkt från ursprungsinstansen och cachelagra dem.</target>
1639 <context-group name="null"> 1621 <context-group name="null">
1640 <context context-type="linenumber">249</context> 1622 <context context-type="linenumber">265</context>
1641 </context-group> 1623 </context-group>
1642 </trans-unit> 1624 </trans-unit>
1643 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1625 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1644 <source>Previews cache size</source> 1626 <source>Previews cache size</source>
1645 <target>Förhandsvisningens cachestorlek</target> 1627 <target>Förhandsvisningens cachestorlek</target>
1646 <context-group name="null"> 1628 <context-group name="null">
1647 <context context-type="linenumber">254</context> 1629 <context context-type="linenumber">271</context>
1648 </context-group> 1630 </context-group>
1649 </trans-unit> 1631 </trans-unit>
1650 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1632 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1651 <source>Video captions cache size</source> 1633 <source>Video captions cache size</source>
1652 <target>Undertexternas cachestorlek</target> 1634 <target>Undertexternas cachestorlek</target>
1653 <context-group name="null"> 1635 <context-group name="null">
1654 <context context-type="linenumber">265</context> 1636 <context context-type="linenumber">280</context>
1655 </context-group> 1637 </context-group>
1656 </trans-unit> 1638 </trans-unit>
1657 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1639 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1658 <source>Customizations</source> 1640 <source>Customizations</source>
1659 <target>Anpassningar</target> 1641 <target>Anpassningar</target>
1660 <context-group name="null"> 1642 <context-group name="null">
1661 <context context-type="linenumber">275</context> 1643 <context context-type="linenumber">289</context>
1662 </context-group> 1644 </context-group>
1663 </trans-unit> 1645 </trans-unit>
1664 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1646 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1665 <source>JavaScript</source> 1647 <source>JavaScript</source>
1666 <target>JavaScript</target> 1648 <target>JavaScript</target>
1667 <context-group name="null"> 1649 <context-group name="null">
1668 <context context-type="linenumber">278</context> 1650 <context context-type="linenumber">294</context>
1669 </context-group> 1651 </context-group>
1670 </trans-unit> 1652 </trans-unit>
1671 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1653 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1672 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1654 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1673 <target>Skriv direkt med JavaScript-kod.&lt;br /&gt;Exempel: &lt;pre&gt;console.log('min instans är fantastisk');&lt;/pre&gt;</target> 1655 <target>Skriv direkt med JavaScript-kod.&lt;br /&gt;Exempel: &lt;pre&gt;console.log('min instans är fantastisk');&lt;/pre&gt;</target>
1674 <context-group name="null"> 1656 <context-group name="null">
1675 <context context-type="linenumber">281</context>
1676 </context-group>
1677 </trans-unit>
1678 <trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5">
1679 <source>
1680 Write directly CSS code. Example:&lt;br /&gt;
1681 &lt;pre&gt;
1682 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1683 background-color: red;
1684 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1685 &lt;/pre&gt;
1686
1687 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1688 &lt;pre&gt;
1689 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1690 color: red;
1691 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1692 &lt;/pre&gt;
1693 </source>
1694 <target>
1695 Skriv CSS-kod direkt. Exempel:&lt;br /&gt;
1696 &lt;pre&gt;
1697 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1698 background-color: red;
1699 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1700 &lt;/pre&gt;
1701
1702 Lägg till &lt;em&gt;#custom-css&lt;/em&gt; först för att åsidosätta stilmallen. Exempel:
1703 &lt;pre&gt;
1704 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1705 color: red;
1706 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1707 &lt;/pre&gt;
1708 </target>
1709 <context-group name="null">
1710 <context context-type="linenumber">297</context> 1657 <context context-type="linenumber">297</context>
1711 </context-group> 1658 </context-group>
1712 </trans-unit> 1659 </trans-unit>
@@ -1714,21 +1661,21 @@
1714 <source>Advanced configuration</source> 1661 <source>Advanced configuration</source>
1715 <target>Avancerade inställningar</target> 1662 <target>Avancerade inställningar</target>
1716 <context-group name="null"> 1663 <context-group name="null">
1717 <context context-type="linenumber">207</context> 1664 <context context-type="linenumber">212</context>
1718 </context-group> 1665 </context-group>
1719 </trans-unit> 1666 </trans-unit>
1720 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1667 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1721 <source>Update configuration</source> 1668 <source>Update configuration</source>
1722 <target>Uppdatera inställningar</target> 1669 <target>Uppdatera inställningar</target>
1723 <context-group name="null"> 1670 <context-group name="null">
1724 <context context-type="linenumber">325</context> 1671 <context context-type="linenumber">340</context>
1725 </context-group> 1672 </context-group>
1726 </trans-unit> 1673 </trans-unit>
1727 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1674 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1728 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1675 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1729 <target>Det verkar som att konfigurationen inte stämmer. Sök efter eventuella fel i de olika flikarna.</target> 1676 <target>Det verkar som att konfigurationen inte stämmer. Sök efter eventuella fel i de olika flikarna.</target>
1730 <context-group name="null"> 1677 <context-group name="null">
1731 <context context-type="linenumber">326</context> 1678 <context context-type="linenumber">341</context>
1732 </context-group> 1679 </context-group>
1733 </trans-unit> 1680 </trans-unit>
1734 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1681 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -2015,11 +1962,25 @@ Det verkar som du inte är på en HTTPS-server. Din webbserver behöver ha TLS a
2015 <context context-type="linenumber">133</context> 1962 <context context-type="linenumber">133</context>
2016 </context-group> 1963 </context-group>
2017 </trans-unit> 1964 </trans-unit>
1965 <trans-unit id="02ba1a65db92d1d0ab4ba380086e9be61891aaa5">
1966 <source>User's email must be verified to login</source>
1967 <target>Användarens e-post måste verifieras innan inloggning</target>
1968 <context-group name="null">
1969 <context context-type="linenumber">72</context>
1970 </context-group>
1971 </trans-unit>
1972 <trans-unit id="79cee9973620b2592ff2824c525aa8ed0b5e2b8b">
1973 <source>User's email is verified / User can login without email verification</source>
1974 <target>Användarens e-post har verifierats / Användaren behöver inte verifiera sin e-post för att logga in</target>
1975 <context-group name="null">
1976 <context context-type="linenumber">76</context>
1977 </context-group>
1978 </trans-unit>
2018 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee"> 1979 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee">
2019 <source>Ban reason:</source> 1980 <source>Ban reason:</source>
2020 <target>Blockeringsanledning:</target> 1981 <target>Blockeringsanledning:</target>
2021 <context-group name="null"> 1982 <context-group name="null">
2022 <context context-type="linenumber">92</context> 1983 <context context-type="linenumber">95</context>
2023 </context-group> 1984 </context-group>
2024 </trans-unit> 1985 </trans-unit>
2025 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 1986 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -2086,7 +2047,7 @@ Det verkar som du inte är på en HTTPS-server. Din webbserver behöver ha TLS a
2086 <source>Actions</source> 2047 <source>Actions</source>
2087 <target>Åtgärder</target> 2048 <target>Åtgärder</target>
2088 <context-group name="null"> 2049 <context-group name="null">
2089 <context context-type="linenumber">33</context> 2050 <context context-type="linenumber">35</context>
2090 </context-group> 2051 </context-group>
2091 </trans-unit> 2052 </trans-unit>
2092 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 2053 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -2121,14 +2082,14 @@ Det verkar som du inte är på en HTTPS-server. Din webbserver behöver ha TLS a
2121 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 2082 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2122 <target>Datum <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 2083 <target>Datum <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2123 <context-group name="null"> 2084 <context-group name="null">
2124 <context context-type="linenumber">10</context> 2085 <context context-type="linenumber">11</context>
2125 </context-group> 2086 </context-group>
2126 </trans-unit> 2087 </trans-unit>
2127 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f"> 2088 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
2128 <source>Blacklist reason:</source> 2089 <source>Blacklist reason:</source>
2129 <target>Anledning för svartlistning:</target> 2090 <target>Anledning för svartlistning:</target>
2130 <context-group name="null"> 2091 <context-group name="null">
2131 <context context-type="linenumber">41</context> 2092 <context context-type="linenumber">43</context>
2132 </context-group> 2093 </context-group>
2133 </trans-unit> 2094 </trans-unit>
2134 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 2095 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -2153,12 +2114,16 @@ Det verkar som du inte är på en HTTPS-server. Din webbserver behöver ha TLS a
2153 </context-group> 2114 </context-group>
2154 </trans-unit> 2115 </trans-unit>
2155 <trans-unit id="b1ff109b26ae8f08650415454b9098c43eba2e2c"> 2116 <trans-unit id="b1ff109b26ae8f08650415454b9098c43eba2e2c">
2156 <source>Muted accounts</source><target>Muted accounts</target><context-group name="null"> 2117 <source>Muted accounts</source>
2118 <target>Ignorerade konton</target>
2119 <context-group name="null">
2157 <context context-type="linenumber">2</context> 2120 <context context-type="linenumber">2</context>
2158 </context-group> 2121 </context-group>
2159 </trans-unit> 2122 </trans-unit>
2160 <trans-unit id="bd0611346af048015e0a1275091ef68ce98832d2"> 2123 <trans-unit id="bd0611346af048015e0a1275091ef68ce98832d2">
2161 <source>Muted servers</source><target>Muted servers</target><context-group name="null"> 2124 <source>Muted servers</source>
2125 <target>Ignorerade servrar</target>
2126 <context-group name="null">
2162 <context context-type="linenumber">11</context> 2127 <context context-type="linenumber">11</context>
2163 </context-group> 2128 </context-group>
2164 </trans-unit> 2129 </trans-unit>
@@ -2170,74 +2135,17 @@ Det verkar som du inte är på en HTTPS-server. Din webbserver behöver ha TLS a
2170 </context-group> 2135 </context-group>
2171 </trans-unit> 2136 </trans-unit>
2172 <trans-unit id="079e99cce11c87b142e80fdd14dae98a61012fc4"> 2137 <trans-unit id="079e99cce11c87b142e80fdd14dae98a61012fc4">
2173 <source>Muted at <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source><target>Muted at <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target><context-group name="null"> 2138 <source>Muted at <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2139 <target>Ignorerad på <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2140 <context-group name="null">
2174 <context context-type="linenumber">13</context> 2141 <context context-type="linenumber">13</context>
2175 </context-group> 2142 </context-group>
2176 </trans-unit> 2143 </trans-unit>
2177 <trans-unit id="1f689fada9748a830117f5b429a88ef8629082a8"> 2144 <trans-unit id="1f689fada9748a830117f5b429a88ef8629082a8">
2178 <source>Unmute</source><target>Unmute</target><context-group name="null"> 2145 <source>Unmute</source>
2179 <context context-type="linenumber">23</context> 2146 <target>Sluta ignorera</target>
2180 </context-group>
2181 </trans-unit>
2182 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2183 <source>My settings</source>
2184 <target>Mina inställningar</target>
2185 <context-group name="null">
2186 <context context-type="linenumber">3</context>
2187 </context-group>
2188 </trans-unit>
2189 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2190 <source>My library</source>
2191 <target>Mitt bibliotek</target>
2192 <context-group name="null">
2193 <context context-type="linenumber">7</context>
2194 </context-group>
2195 </trans-unit>
2196 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2197 <source>My channels</source>
2198 <target>Mina kanaler</target>
2199 <context-group name="null">
2200 <context context-type="linenumber">12</context>
2201 </context-group>
2202 </trans-unit>
2203 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2204 <source>My videos</source>
2205 <target>Mina videor</target>
2206 <context-group name="null">
2207 <context context-type="linenumber">14</context>
2208 </context-group>
2209 </trans-unit>
2210 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2211 <source>My subscriptions</source>
2212 <target>Mina prenumerationer</target>
2213 <context-group name="null">
2214 <context context-type="linenumber">16</context>
2215 </context-group>
2216 </trans-unit>
2217 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
2218 <source>My imports</source>
2219 <target>Mina importeringar</target>
2220 <context-group name="null">
2221 <context context-type="linenumber">18</context>
2222 </context-group>
2223 </trans-unit>
2224 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
2225 <source>Misc</source>
2226 <target>Diverse</target>
2227 <context-group name="null">
2228 <context context-type="linenumber">24</context>
2229 </context-group>
2230 </trans-unit>
2231 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2232 <source>Muted instances</source><target>Muted instances</target><context-group name="null">
2233 <context context-type="linenumber">2</context>
2234 </context-group>
2235 </trans-unit>
2236 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
2237 <source>Ownership changes</source>
2238 <target>Ändringar av ägarskap</target>
2239 <context-group name="null"> 2147 <context-group name="null">
2240 <context context-type="linenumber">33</context> 2148 <context context-type="linenumber">23</context>
2241 </context-group> 2149 </context-group>
2242 </trans-unit> 2150 </trans-unit>
2243 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 2151 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
@@ -2251,21 +2159,21 @@ Det verkar som du inte är på en HTTPS-server. Din webbserver behöver ha TLS a
2251 <source>Profile</source> 2159 <source>Profile</source>
2252 <target>Profil</target> 2160 <target>Profil</target>
2253 <context-group name="null"> 2161 <context-group name="null">
2254 <context context-type="linenumber">8</context> 2162 <context context-type="linenumber">7</context>
2255 </context-group> 2163 </context-group>
2256 </trans-unit> 2164 </trans-unit>
2257 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 2165 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
2258 <source>Video settings</source> 2166 <source>Video settings</source>
2259 <target>Videoinställningar</target> 2167 <target>Videoinställningar</target>
2260 <context-group name="null"> 2168 <context-group name="null">
2261 <context context-type="linenumber">15</context> 2169 <context context-type="linenumber">16</context>
2262 </context-group> 2170 </context-group>
2263 </trans-unit> 2171 </trans-unit>
2264 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 2172 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
2265 <source>Danger zone</source> 2173 <source>Danger zone</source>
2266 <target>Riskzon</target> 2174 <target>Riskzon</target>
2267 <context-group name="null"> 2175 <context-group name="null">
2268 <context context-type="linenumber">18</context> 2176 <context context-type="linenumber">19</context>
2269 </context-group> 2177 </context-group>
2270 </trans-unit> 2178 </trans-unit>
2271 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 2179 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -2293,13 +2201,6 @@ Det verkar som du inte är på en HTTPS-server. Din webbserver behöver ha TLS a
2293 <context context-type="linenumber">35</context> 2201 <context context-type="linenumber">35</context>
2294 </context-group> 2202 </context-group>
2295 </trans-unit> 2203 </trans-unit>
2296 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
2297 <source>Submit</source>
2298 <target>Skicka</target>
2299 <context-group name="null">
2300 <context context-type="linenumber">24</context>
2301 </context-group>
2302 </trans-unit>
2303 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 2204 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
2304 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 2205 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2305 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> visningar</target> 2206 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> visningar</target>
@@ -2459,6 +2360,13 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
2459 <context context-type="linenumber">47</context> 2360 <context context-type="linenumber">47</context>
2460 </context-group> 2361 </context-group>
2461 </trans-unit> 2362 </trans-unit>
2363 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2364 <source>Muted instances</source>
2365 <target>Ignorerade instanser</target>
2366 <context-group name="null">
2367 <context context-type="linenumber">2</context>
2368 </context-group>
2369 </trans-unit>
2462 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 2370 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
2463 <source>Change password</source> 2371 <source>Change password</source>
2464 <target>Ändra lösenord</target> 2372 <target>Ändra lösenord</target>
@@ -2664,6 +2572,13 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
2664 <context context-type="linenumber">159</context> 2572 <context context-type="linenumber">159</context>
2665 </context-group> 2573 </context-group>
2666 </trans-unit> 2574 </trans-unit>
2575 <trans-unit id="385811ab5a5c3e96e0db46c9ce1fc3147d8cd4c7">
2576 <source>Sorry, but something went wrong</source>
2577 <target>Någonting har tyvärr gått fel</target>
2578 <context-group name="null">
2579 <context context-type="linenumber">49</context>
2580 </context-group>
2581 </trans-unit>
2667 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2"> 2582 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2">
2668 <source> 2583 <source>
2669 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video. 2584 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video.
@@ -2700,14 +2615,14 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
2700 <source>Publish will be available when upload is finished</source> 2615 <source>Publish will be available when upload is finished</source>
2701 <target>Du kan publicera när uppladdningen är klar</target> 2616 <target>Du kan publicera när uppladdningen är klar</target>
2702 <context-group name="null"> 2617 <context-group name="null">
2703 <context context-type="linenumber">53</context> 2618 <context context-type="linenumber">58</context>
2704 </context-group> 2619 </context-group>
2705 </trans-unit> 2620 </trans-unit>
2706 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 2621 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2707 <source>Publish</source> 2622 <source>Publish</source>
2708 <target>Publisera</target> 2623 <target>Publisera</target>
2709 <context-group name="null"> 2624 <context-group name="null">
2710 <context context-type="linenumber">60</context> 2625 <context context-type="linenumber">65</context>
2711 </context-group> 2626 </context-group>
2712 </trans-unit> 2627 </trans-unit>
2713 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 2628 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -2890,14 +2805,14 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
2890 <source>Wait transcoding before publishing the video</source> 2805 <source>Wait transcoding before publishing the video</source>
2891 <target>Publicera video när omkodningen är avklarad</target> 2806 <target>Publicera video när omkodningen är avklarad</target>
2892 <context-group name="null"> 2807 <context-group name="null">
2893 <context context-type="linenumber">130</context> 2808 <context context-type="linenumber">131</context>
2894 </context-group> 2809 </context-group>
2895 </trans-unit> 2810 </trans-unit>
2896 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 2811 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2897 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 2812 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
2898 <target>Om du väljer att inte vänta på omkodningen innan publicering, kommer videon inte gå att spela förrän omkodningen är färdig.</target> 2813 <target>Om du väljer att inte vänta på omkodningen innan publicering, kommer videon inte gå att spela förrän omkodningen är färdig.</target>
2899 <context-group name="null"> 2814 <context-group name="null">
2900 <context context-type="linenumber">131</context> 2815 <context context-type="linenumber">132</context>
2901 </context-group> 2816 </context-group>
2902 </trans-unit> 2817 </trans-unit>
2903 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2818 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2911,49 +2826,49 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
2911 <source>Add another caption</source> 2826 <source>Add another caption</source>
2912 <target>Lägg till ännu en text</target> 2827 <target>Lägg till ännu en text</target>
2913 <context-group name="null"> 2828 <context-group name="null">
2914 <context context-type="linenumber">146</context> 2829 <context context-type="linenumber">147</context>
2915 </context-group> 2830 </context-group>
2916 </trans-unit> 2831 </trans-unit>
2917 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 2832 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2918 <source>See the subtitle file</source> 2833 <source>See the subtitle file</source>
2919 <target>Se undertextfilen</target> 2834 <target>Se undertextfilen</target>
2920 <context-group name="null"> 2835 <context-group name="null">
2921 <context context-type="linenumber">155</context> 2836 <context context-type="linenumber">156</context>
2922 </context-group> 2837 </context-group>
2923 </trans-unit> 2838 </trans-unit>
2924 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee"> 2839 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee">
2925 <source>Already uploaded ✔</source> 2840 <source>Already uploaded ✔</source>
2926 <target>Redan uppladdad ✔</target> 2841 <target>Redan uppladdad ✔</target>
2927 <context-group name="null"> 2842 <context-group name="null">
2928 <context context-type="linenumber">159</context> 2843 <context context-type="linenumber">160</context>
2929 </context-group> 2844 </context-group>
2930 </trans-unit> 2845 </trans-unit>
2931 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad"> 2846 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad">
2932 <source>Will be created on update</source> 2847 <source>Will be created on update</source>
2933 <target>Kommer skapas vid uppdatering</target> 2848 <target>Kommer skapas vid uppdatering</target>
2934 <context-group name="null"> 2849 <context-group name="null">
2935 <context context-type="linenumber">167</context> 2850 <context context-type="linenumber">168</context>
2936 </context-group> 2851 </context-group>
2937 </trans-unit> 2852 </trans-unit>
2938 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 2853 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2939 <source>Cancel create</source> 2854 <source>Cancel create</source>
2940 <target>Avbryt skapande</target> 2855 <target>Avbryt skapande</target>
2941 <context-group name="null"> 2856 <context-group name="null">
2942 <context context-type="linenumber">169</context> 2857 <context context-type="linenumber">170</context>
2943 </context-group> 2858 </context-group>
2944 </trans-unit> 2859 </trans-unit>
2945 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393"> 2860 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393">
2946 <source>Will be deleted on update</source> 2861 <source>Will be deleted on update</source>
2947 <target>Kommer raderas vid uppdatering</target> 2862 <target>Kommer raderas vid uppdatering</target>
2948 <context-group name="null"> 2863 <context-group name="null">
2949 <context context-type="linenumber">175</context> 2864 <context context-type="linenumber">176</context>
2950 </context-group> 2865 </context-group>
2951 </trans-unit> 2866 </trans-unit>
2952 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 2867 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2953 <source>Cancel deletion</source> 2868 <source>Cancel deletion</source>
2954 <target>Avbryt radering</target> 2869 <target>Avbryt radering</target>
2955 <context-group name="null"> 2870 <context-group name="null">
2956 <context context-type="linenumber">177</context> 2871 <context context-type="linenumber">178</context>
2957 </context-group> 2872 </context-group>
2958 </trans-unit> 2873 </trans-unit>
2959 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0"> 2874 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0">
@@ -2964,28 +2879,28 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
2964 Inga undertexter för tillfället. 2879 Inga undertexter för tillfället.
2965 </target> 2880 </target>
2966 <context-group name="null"> 2881 <context-group name="null">
2967 <context context-type="linenumber">182</context> 2882 <context context-type="linenumber">183</context>
2968 </context-group> 2883 </context-group>
2969 </trans-unit> 2884 </trans-unit>
2970 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 2885 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2971 <source>Captions</source> 2886 <source>Captions</source>
2972 <target>Texter</target> 2887 <target>Texter</target>
2973 <context-group name="null"> 2888 <context-group name="null">
2974 <context context-type="linenumber">139</context> 2889 <context context-type="linenumber">140</context>
2975 </context-group> 2890 </context-group>
2976 </trans-unit> 2891 </trans-unit>
2977 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 2892 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
2978 <source>Upload thumbnail</source> 2893 <source>Upload thumbnail</source>
2979 <target>Ladda upp miniatyrbild</target> 2894 <target>Ladda upp miniatyrbild</target>
2980 <context-group name="null"> 2895 <context-group name="null">
2981 <context context-type="linenumber">195</context> 2896 <context context-type="linenumber">196</context>
2982 </context-group> 2897 </context-group>
2983 </trans-unit> 2898 </trans-unit>
2984 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 2899 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
2985 <source>Upload preview</source> 2900 <source>Upload preview</source>
2986 <target>Ladda upp förhandsvisning</target> 2901 <target>Ladda upp förhandsvisning</target>
2987 <context-group name="null"> 2902 <context-group name="null">
2988 <context context-type="linenumber">202</context> 2903 <context context-type="linenumber">203</context>
2989 </context-group> 2904 </context-group>
2990 </trans-unit> 2905 </trans-unit>
2991 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 2906 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -2999,14 +2914,14 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
2999 <source>Short text to tell people how they can support you (membership platform...).</source> 2914 <source>Short text to tell people how they can support you (membership platform...).</source>
3000 <target>Kort text för att berätta hur andra kan stödja dig (medlemsplattform …).</target> 2915 <target>Kort text för att berätta hur andra kan stödja dig (medlemsplattform …).</target>
3001 <context-group name="null"> 2916 <context-group name="null">
3002 <context context-type="linenumber">209</context> 2917 <context context-type="linenumber">210</context>
3003 </context-group> 2918 </context-group>
3004 </trans-unit> 2919 </trans-unit>
3005 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 2920 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
3006 <source>Advanced settings</source> 2921 <source>Advanced settings</source>
3007 <target>Avancerade inställningar</target> 2922 <target>Avancerade inställningar</target>
3008 <context-group name="null"> 2923 <context-group name="null">
3009 <context context-type="linenumber">190</context> 2924 <context context-type="linenumber">191</context>
3010 </context-group> 2925 </context-group>
3011 </trans-unit> 2926 </trans-unit>
3012 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 2927 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -3073,17 +2988,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
3073 <context context-type="linenumber">3</context> 2988 <context context-type="linenumber">3</context>
3074 </context-group> 2989 </context-group>
3075 </trans-unit> 2990 </trans-unit>
3076 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
3077 <source>
3078 Cancel
3079 </source>
3080 <target>
3081 Avbryt
3082 </target>
3083 <context-group name="null">
3084 <context context-type="linenumber">19</context>
3085 </context-group>
3086 </trans-unit>
3087 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 2991 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
3088 <source>Share</source> 2992 <source>Share</source>
3089 <target>Dela</target> 2993 <target>Dela</target>
@@ -3309,7 +3213,7 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
3309 the sharing system used for this video implies that some technical information about your system (such as a public IP address) can be sent to other peers. 3213 the sharing system used for this video implies that some technical information about your system (such as a public IP address) can be sent to other peers.
3310 </source> 3214 </source>
3311 <target> 3215 <target>
3312 den här videons delningssystem medför att en del teknisk information om ditt system (såsom publik IP-adress) kan skickas till andra serventer. 3216 den här videons delningssystem gör att en del teknisk information om ditt system (som publik IP-adress) kan skickas till andra serventer.
3313 </target> 3217 </target>
3314 <context-group name="null"> 3218 <context-group name="null">
3315 <context context-type="linenumber">209</context> 3219 <context context-type="linenumber">209</context>
@@ -3470,13 +3374,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
3470 <context context-type="linenumber">14</context> 3374 <context context-type="linenumber">14</context>
3471 </context-group> 3375 </context-group>
3472 </trans-unit> 3376 </trans-unit>
3473 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
3474 <source>Error getting about from server</source>
3475 <target>Kan inte hämta information om instansen från servern</target>
3476 <context-group name="null">
3477 <context context-type="linenumber">1</context>
3478 </context-group>
3479 </trans-unit>
3480 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 3377 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
3481 <source>No description</source> 3378 <source>No description</source>
3482 <target>Ingen beskrivning</target> 3379 <target>Ingen beskrivning</target>
@@ -3498,13 +3395,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
3498 <context context-type="linenumber">1</context> 3395 <context context-type="linenumber">1</context>
3499 </context-group> 3396 </context-group>
3500 </trans-unit> 3397 </trans-unit>
3501 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
3502 <source>Error</source>
3503 <target>Fel</target>
3504 <context-group name="null">
3505 <context context-type="linenumber">1</context>
3506 </context-group>
3507 </trans-unit>
3508 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6"> 3398 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
3509 <source>240p</source> 3399 <source>240p</source>
3510 <target>240p</target> 3400 <target>240p</target>
@@ -3547,13 +3437,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
3547 <context context-type="linenumber">1</context> 3437 <context context-type="linenumber">1</context>
3548 </context-group> 3438 </context-group>
3549 </trans-unit> 3439 </trans-unit>
3550 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
3551 <source>Success</source>
3552 <target>Åtgärden lyckades</target>
3553 <context-group name="null">
3554 <context context-type="linenumber">1</context>
3555 </context-group>
3556 </trans-unit>
3557 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 3440 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
3558 <source>Configuration updated.</source> 3441 <source>Configuration updated.</source>
3559 <target>Konfigurering uppdaterad.</target> 3442 <target>Konfigurering uppdaterad.</target>
@@ -3716,12 +3599,16 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
3716 </context-group> 3599 </context-group>
3717 </trans-unit> 3600 </trans-unit>
3718 <trans-unit id="53cc0f4a4566c4139c65f93b5dce2fe8302e78da"> 3601 <trans-unit id="53cc0f4a4566c4139c65f93b5dce2fe8302e78da">
3719 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by your instance.</source><target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by your instance.</target><context-group name="null"> 3602 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by your instance.</source>
3603 <target>Kontot <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> ignoreras inte längre av din instans.</target>
3604 <context-group name="null">
3720 <context context-type="linenumber">1</context> 3605 <context context-type="linenumber">1</context>
3721 </context-group> 3606 </context-group>
3722 </trans-unit> 3607 </trans-unit>
3723 <trans-unit id="468b52e3c04fb9a3d8c8213555dfcad0cbcae330"> 3608 <trans-unit id="468b52e3c04fb9a3d8c8213555dfcad0cbcae330">
3724 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by your instance.</source><target>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by your instance.</target><context-group name="null"> 3609 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by your instance.</source>
3610 <target>Instansen <x id="INTERPOLATION" equiv-text="{{host}}"/> ignoreras inte längre av din instans.</target>
3611 <context-group name="null">
3725 <context context-type="linenumber">1</context> 3612 <context context-type="linenumber">1</context>
3726 </context-group> 3613 </context-group>
3727 </trans-unit> 3614 </trans-unit>
@@ -3816,6 +3703,13 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
3816 <context context-type="linenumber">1</context> 3703 <context context-type="linenumber">1</context>
3817 </context-group> 3704 </context-group>
3818 </trans-unit> 3705 </trans-unit>
3706 <trans-unit id="910ed85f550272401b134a40d019ab3359fe883f">
3707 <source>Set Email as Verified</source>
3708 <target>Markera e-post som verifierad</target>
3709 <context-group name="null">
3710 <context context-type="linenumber">1</context>
3711 </context-group>
3712 </trans-unit>
3819 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf"> 3713 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf">
3820 <source>You cannot ban root.</source> 3714 <source>You cannot ban root.</source>
3821 <target>Du kan inte blockera root.</target> 3715 <target>Du kan inte blockera root.</target>
@@ -3858,13 +3752,24 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
3858 <context context-type="linenumber">1</context> 3752 <context context-type="linenumber">1</context>
3859 </context-group> 3753 </context-group>
3860 </trans-unit> 3754 </trans-unit>
3755 <trans-unit id="f4a8f2ef1fbfc19e1e049e69f63c40063c0d0650">
3756 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users email set as verified.</source>
3757 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> användares e-post har markerats som verifierade.</target>
3758 <context-group name="null">
3759 <context context-type="linenumber">1</context>
3760 </context-group>
3761 </trans-unit>
3861 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de"> 3762 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de">
3862 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source><target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</target><context-group name="null"> 3763 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source>
3764 <target>Kontot <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> ignoreras inte längre.</target>
3765 <context-group name="null">
3863 <context context-type="linenumber">1</context> 3766 <context context-type="linenumber">1</context>
3864 </context-group> 3767 </context-group>
3865 </trans-unit> 3768 </trans-unit>
3866 <trans-unit id="c6af80b42938d4a49e6f6c4f60ce26228916994c"> 3769 <trans-unit id="c6af80b42938d4a49e6f6c4f60ce26228916994c">
3867 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted.</source><target>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted.</target><context-group name="null"> 3770 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted.</source>
3771 <target>Instansen <x id="INTERPOLATION" equiv-text="{{host}}"/> ignoreras inte längre.</target>
3772 <context-group name="null">
3868 <context context-type="linenumber">1</context> 3773 <context context-type="linenumber">1</context>
3869 </context-group> 3774 </context-group>
3870 </trans-unit> 3775 </trans-unit>
@@ -3966,23 +3871,16 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
3966 <context context-type="linenumber">1</context> 3871 <context context-type="linenumber">1</context>
3967 </context-group> 3872 </context-group>
3968 </trans-unit> 3873 </trans-unit>
3969 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 3874 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
3970 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 3875 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
3971 <target>Vill du verkligen radera <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? Det kommer radera samtliga videor som laddats upp till kanalen.</target> 3876 <target>Kanalen <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> har raderats.</target>
3972 <context-group name="null">
3973 <context context-type="linenumber">1</context>
3974 </context-group>
3975 </trans-unit>
3976 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
3977 <source>Please type the name of the video channel to confirm</source>
3978 <target>Fyll i kanalens namn för att bekräfta</target>
3979 <context-group name="null"> 3877 <context-group name="null">
3980 <context context-type="linenumber">1</context> 3878 <context context-type="linenumber">1</context>
3981 </context-group> 3879 </context-group>
3982 </trans-unit> 3880 </trans-unit>
3983 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 3881 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
3984 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 3882 <source>My videos</source>
3985 <target>Kanalen <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> har raderats.</target> 3883 <target>Mina videor</target>
3986 <context-group name="null"> 3884 <context-group name="null">
3987 <context context-type="linenumber">1</context> 3885 <context context-type="linenumber">1</context>
3988 </context-group> 3886 </context-group>
@@ -4057,16 +3955,44 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
4057 <context context-type="linenumber">1</context> 3955 <context context-type="linenumber">1</context>
4058 </context-group> 3956 </context-group>
4059 </trans-unit> 3957 </trans-unit>
4060 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 3958 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
4061 <source>Channels</source> 3959 <source>My library</source>
4062 <target>Kanaler</target> 3960 <target>Mitt bibliotek</target>
3961 <context-group name="null">
3962 <context context-type="linenumber">1</context>
3963 </context-group>
3964 </trans-unit>
3965 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
3966 <source>My channels</source>
3967 <target>Mina kanaler</target>
3968 <context-group name="null">
3969 <context context-type="linenumber">1</context>
3970 </context-group>
3971 </trans-unit>
3972 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
3973 <source>My subscriptions</source>
3974 <target>Mina prenumerationer</target>
3975 <context-group name="null">
3976 <context context-type="linenumber">1</context>
3977 </context-group>
3978 </trans-unit>
3979 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
3980 <source>Misc</source>
3981 <target>Diverse</target>
3982 <context-group name="null">
3983 <context context-type="linenumber">1</context>
3984 </context-group>
3985 </trans-unit>
3986 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
3987 <source>Ownership changes</source>
3988 <target>Ändringar av ägarskap</target>
4063 <context-group name="null"> 3989 <context-group name="null">
4064 <context context-type="linenumber">1</context> 3990 <context context-type="linenumber">1</context>
4065 </context-group> 3991 </context-group>
4066 </trans-unit> 3992 </trans-unit>
4067 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d"> 3993 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
4068 <source>Video imports</source> 3994 <source>My settings</source>
4069 <target>Videoimporteringar</target> 3995 <target>Mina inställningar</target>
4070 <context-group name="null"> 3996 <context-group name="null">
4071 <context context-type="linenumber">1</context> 3997 <context context-type="linenumber">1</context>
4072 </context-group> 3998 </context-group>
@@ -4192,6 +4118,13 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
4192 <context context-type="linenumber">1</context> 4118 <context context-type="linenumber">1</context>
4193 </context-group> 4119 </context-group>
4194 </trans-unit> 4120 </trans-unit>
4121 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
4122 <source>Error</source>
4123 <target>Fel</target>
4124 <context-group name="null">
4125 <context context-type="linenumber">1</context>
4126 </context-group>
4127 </trans-unit>
4195 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 4128 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
4196 <source>You need to reconnect.</source> 4129 <source>You need to reconnect.</source>
4197 <target>Du måste återansluta.</target> 4130 <target>Du måste återansluta.</target>
@@ -4213,6 +4146,20 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
4213 <context context-type="linenumber">1</context> 4146 <context context-type="linenumber">1</context>
4214 </context-group> 4147 </context-group>
4215 </trans-unit> 4148 </trans-unit>
4149 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4150 <source>Info</source>
4151 <target>Information</target>
4152 <context-group name="null">
4153 <context context-type="linenumber">1</context>
4154 </context-group>
4155 </trans-unit>
4156 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
4157 <source>Success</source>
4158 <target>Åtgärden lyckades</target>
4159 <context-group name="null">
4160 <context context-type="linenumber">1</context>
4161 </context-group>
4162 </trans-unit>
4216 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 4163 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
4217 <source>Incorrect username or password.</source> 4164 <source>Incorrect username or password.</source>
4218 <target>Felaktigt användarnamn eller lösenord.</target> 4165 <target>Felaktigt användarnamn eller lösenord.</target>
@@ -4430,6 +4377,20 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
4430 <context context-type="linenumber">1</context> 4377 <context context-type="linenumber">1</context>
4431 </context-group> 4378 </context-group>
4432 </trans-unit> 4379 </trans-unit>
4380 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4381 <source>Email is required.</source>
4382 <target>E-postadress måste uppges.</target>
4383 <context-group name="null">
4384 <context context-type="linenumber">1</context>
4385 </context-group>
4386 </trans-unit>
4387 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4388 <source>Email must be valid.</source>
4389 <target>E-postadressen måste vara giltig.</target>
4390 <context-group name="null">
4391 <context context-type="linenumber">1</context>
4392 </context-group>
4393 </trans-unit>
4433 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 4394 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
4434 <source>Username is required.</source> 4395 <source>Username is required.</source>
4435 <target>Användarnamn måste fyllas i.</target> 4396 <target>Användarnamn måste fyllas i.</target>
@@ -4451,41 +4412,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
4451 <context context-type="linenumber">1</context> 4412 <context context-type="linenumber">1</context>
4452 </context-group> 4413 </context-group>
4453 </trans-unit> 4414 </trans-unit>
4454 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
4455 <source>Username must be at least 3 characters long.</source>
4456 <target>Användarnamnet måste innehålla minst tre tecken.</target>
4457 <context-group name="null">
4458 <context context-type="linenumber">1</context>
4459 </context-group>
4460 </trans-unit>
4461 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
4462 <source>Username cannot be more than 20 characters long.</source>
4463 <target>Användarnamnet får inte vara mer än 20 tecken långt.</target>
4464 <context-group name="null">
4465 <context context-type="linenumber">1</context>
4466 </context-group>
4467 </trans-unit>
4468 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
4469 <source>Username should be only lowercase alphanumeric characters.</source>
4470 <target>Användarnamnet får endast bestå av små bokstäver och siffror.</target>
4471 <context-group name="null">
4472 <context context-type="linenumber">1</context>
4473 </context-group>
4474 </trans-unit>
4475 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4476 <source>Email is required.</source>
4477 <target>E-postadress måste uppges.</target>
4478 <context-group name="null">
4479 <context context-type="linenumber">1</context>
4480 </context-group>
4481 </trans-unit>
4482 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4483 <source>Email must be valid.</source>
4484 <target>E-postadressen måste vara giltig.</target>
4485 <context-group name="null">
4486 <context context-type="linenumber">1</context>
4487 </context-group>
4488 </trans-unit>
4489 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 4415 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
4490 <source>Password must be at least 6 characters long.</source> 4416 <source>Password must be at least 6 characters long.</source>
4491 <target>Lösenordet måste innehålla minst sex tecken.</target> 4417 <target>Lösenordet måste innehålla minst sex tecken.</target>
@@ -4549,20 +4475,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
4549 <context context-type="linenumber">1</context> 4475 <context context-type="linenumber">1</context>
4550 </context-group> 4476 </context-group>
4551 </trans-unit> 4477 </trans-unit>
4552 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
4553 <source>Display name must be at least 3 characters long.</source>
4554 <target>Visningsnamnet måste innehålla minst tre tecken.</target>
4555 <context-group name="null">
4556 <context context-type="linenumber">1</context>
4557 </context-group>
4558 </trans-unit>
4559 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
4560 <source>Display name cannot be more than 120 characters long.</source>
4561 <target>Visningsnamnet får inte vara mer än 120 tecken långt.</target>
4562 <context-group name="null">
4563 <context context-type="linenumber">1</context>
4564 </context-group>
4565 </trans-unit>
4566 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 4478 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
4567 <source>Description must be at least 3 characters long.</source> 4479 <source>Description must be at least 3 characters long.</source>
4568 <target>Beskrivningen måste innehålla minst tre tecken.</target> 4480 <target>Beskrivningen måste innehålla minst tre tecken.</target>
@@ -4612,13 +4524,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
4612 <context context-type="linenumber">1</context> 4524 <context context-type="linenumber">1</context>
4613 </context-group> 4525 </context-group>
4614 </trans-unit> 4526 </trans-unit>
4615 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
4616 <source>Report reason cannot be more than 300 characters long.</source>
4617 <target>Orsak för rapportering får inte vara mer än 300 tecken lång.</target>
4618 <context-group name="null">
4619 <context context-type="linenumber">1</context>
4620 </context-group>
4621 </trans-unit>
4622 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118"> 4527 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
4623 <source>Moderation comment is required.</source> 4528 <source>Moderation comment is required.</source>
4624 <target>Moderationskommentar krävs.</target> 4529 <target>Moderationskommentar krävs.</target>
@@ -4633,13 +4538,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
4633 <context context-type="linenumber">1</context> 4538 <context context-type="linenumber">1</context>
4634 </context-group> 4539 </context-group>
4635 </trans-unit> 4540 </trans-unit>
4636 <trans-unit id="89d0b662dde0871cf17244e79b2cb62cd517e44f">
4637 <source>Moderation comment cannot be more than 300 characters long.</source>
4638 <target>Moderationskommentaren får inte vara mer än 300 tecken lång.</target>
4639 <context-group name="null">
4640 <context context-type="linenumber">1</context>
4641 </context-group>
4642 </trans-unit>
4643 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6"> 4541 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
4644 <source>The channel is required.</source> 4542 <source>The channel is required.</source>
4645 <target>Kanalen måste anges.</target> 4543 <target>Kanalen måste anges.</target>
@@ -4696,27 +4594,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
4696 <context context-type="linenumber">1</context> 4594 <context context-type="linenumber">1</context>
4697 </context-group> 4595 </context-group>
4698 </trans-unit> 4596 </trans-unit>
4699 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069">
4700 <source>Name must be at least 3 characters long.</source>
4701 <target>Namnet måste innehålla minst tre tecken.</target>
4702 <context-group name="null">
4703 <context context-type="linenumber">1</context>
4704 </context-group>
4705 </trans-unit>
4706 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482">
4707 <source>Name cannot be more than 20 characters long.</source>
4708 <target>Namnet får inte vara mer än 20 tecken långt.</target>
4709 <context-group name="null">
4710 <context context-type="linenumber">1</context>
4711 </context-group>
4712 </trans-unit>
4713 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9">
4714 <source>Name should be only lowercase alphanumeric characters.</source>
4715 <target>Namnet kan endast bestå av små bokstäver och siffror</target>
4716 <context-group name="null">
4717 <context context-type="linenumber">1</context>
4718 </context-group>
4719 </trans-unit>
4720 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 4597 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
4721 <source>Support text must be at least 3 characters long.</source> 4598 <source>Support text must be at least 3 characters long.</source>
4722 <target>Supporttexten måste innehålla minst tre tecken.</target> 4599 <target>Supporttexten måste innehålla minst tre tecken.</target>
@@ -5396,73 +5273,108 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
5396 <context context-type="linenumber">1</context> 5273 <context context-type="linenumber">1</context>
5397 </context-group> 5274 </context-group>
5398 </trans-unit> 5275 </trans-unit>
5276 <trans-unit id="534202c90c6dcadd2989fc72c5030d5483e26096">
5277 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> email set as verified</source>
5278 <target>Användaren <x id="INTERPOLATION" equiv-text="{{username}}"/>s e-post har markerats som verifierad.</target>
5279 <context-group name="null">
5280 <context context-type="linenumber">1</context>
5281 </context-group>
5282 </trans-unit>
5399 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249"> 5283 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249">
5400 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source><target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</target><context-group name="null"> 5284 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source>
5285 <target>Kontot <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> ignoreras.</target>
5286 <context-group name="null">
5401 <context context-type="linenumber">1</context> 5287 <context context-type="linenumber">1</context>
5402 </context-group> 5288 </context-group>
5403 </trans-unit> 5289 </trans-unit>
5404 <trans-unit id="086eda792aeb1b0d131d633b50fdd1792f5f24c6"> 5290 <trans-unit id="086eda792aeb1b0d131d633b50fdd1792f5f24c6">
5405 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted.</source><target>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted.</target><context-group name="null"> 5291 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted.</source>
5292 <target>Instansen <x id="INTERPOLATION" equiv-text="{{host}}"/> ignoreras.</target>
5293 <context-group name="null">
5406 <context context-type="linenumber">1</context> 5294 <context context-type="linenumber">1</context>
5407 </context-group> 5295 </context-group>
5408 </trans-unit> 5296 </trans-unit>
5409 <trans-unit id="bb72d6d1219e89d182e9fd09d853d83baf8d6499"> 5297 <trans-unit id="bb72d6d1219e89d182e9fd09d853d83baf8d6499">
5410 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted by the instance.</source><target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted by the instance.</target><context-group name="null"> 5298 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted by the instance.</source>
5299 <target>Kontot <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> ignoreras av instansen.</target>
5300 <context-group name="null">
5411 <context context-type="linenumber">1</context> 5301 <context context-type="linenumber">1</context>
5412 </context-group> 5302 </context-group>
5413 </trans-unit> 5303 </trans-unit>
5414 <trans-unit id="8686834bc4afe42c1991c6c18f0bce174a0e17a6"> 5304 <trans-unit id="8686834bc4afe42c1991c6c18f0bce174a0e17a6">
5415 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by the instance.</source><target>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by the instance.</target><context-group name="null"> 5305 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted by the instance.</source>
5306 <target>Kontot <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> ignoreras inte längre av instansen.</target>
5307 <context-group name="null">
5416 <context context-type="linenumber">1</context> 5308 <context context-type="linenumber">1</context>
5417 </context-group> 5309 </context-group>
5418 </trans-unit> 5310 </trans-unit>
5419 <trans-unit id="35d3509161861a610b0895bf084c781e56ba2830"> 5311 <trans-unit id="35d3509161861a610b0895bf084c781e56ba2830">
5420 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted by the instance.</source><target>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted by the instance.</target><context-group name="null"> 5312 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> muted by the instance.</source>
5313 <target>Instansen <x id="INTERPOLATION" equiv-text="{{host}}"/> ignoreras av instansen.</target>
5314 <context-group name="null">
5421 <context context-type="linenumber">1</context> 5315 <context context-type="linenumber">1</context>
5422 </context-group> 5316 </context-group>
5423 </trans-unit> 5317 </trans-unit>
5424 <trans-unit id="978aeec5613fa97e8a5336d3599cebb23ee5a90f"> 5318 <trans-unit id="978aeec5613fa97e8a5336d3599cebb23ee5a90f">
5425 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by the instance.</source><target>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by the instance.</target><context-group name="null"> 5319 <source>Instance <x id="INTERPOLATION" equiv-text="{{host}}"/> unmuted by the instance.</source>
5320 <target>Instansen <x id="INTERPOLATION" equiv-text="{{host}}"/> ignoreras inte längre av instansen.</target>
5321 <context-group name="null">
5426 <context context-type="linenumber">1</context> 5322 <context context-type="linenumber">1</context>
5427 </context-group> 5323 </context-group>
5428 </trans-unit> 5324 </trans-unit>
5429 <trans-unit id="4a09bf8724e7659fbb5ec33647529cdef7614bdc"> 5325 <trans-unit id="4a09bf8724e7659fbb5ec33647529cdef7614bdc">
5430 <source>Mute this account</source><target>Mute this account</target><context-group name="null"> 5326 <source>Mute this account</source>
5327 <target>Ignorera det här kontot</target>
5328 <context-group name="null">
5431 <context context-type="linenumber">1</context> 5329 <context context-type="linenumber">1</context>
5432 </context-group> 5330 </context-group>
5433 </trans-unit> 5331 </trans-unit>
5434 <trans-unit id="d666ca3261aef72b2ddcd649d7b32af488f59952"> 5332 <trans-unit id="d666ca3261aef72b2ddcd649d7b32af488f59952">
5435 <source>Unmute this account</source><target>Unmute this account</target><context-group name="null"> 5333 <source>Unmute this account</source>
5334 <target>Sluta ignorera det här kontot</target>
5335 <context-group name="null">
5436 <context context-type="linenumber">1</context> 5336 <context context-type="linenumber">1</context>
5437 </context-group> 5337 </context-group>
5438 </trans-unit> 5338 </trans-unit>
5439 <trans-unit id="e17218983b1de76e5a920b04e1c2ecbdb6e3e06d"> 5339 <trans-unit id="e17218983b1de76e5a920b04e1c2ecbdb6e3e06d">
5440 <source>Mute the instance</source><target>Mute the instance</target><context-group name="null"> 5340 <source>Mute the instance</source>
5341 <target>Ignorera instansen</target>
5342 <context-group name="null">
5441 <context context-type="linenumber">1</context> 5343 <context context-type="linenumber">1</context>
5442 </context-group> 5344 </context-group>
5443 </trans-unit> 5345 </trans-unit>
5444 <trans-unit id="a23514d8aca2f8633622dda0e86b399dc576a2b9"> 5346 <trans-unit id="a23514d8aca2f8633622dda0e86b399dc576a2b9">
5445 <source>Unmute the instance</source><target>Unmute the instance</target><context-group name="null"> 5347 <source>Unmute the instance</source>
5348 <target>Sluta ignorera instansen</target>
5349 <context-group name="null">
5446 <context context-type="linenumber">1</context> 5350 <context context-type="linenumber">1</context>
5447 </context-group> 5351 </context-group>
5448 </trans-unit> 5352 </trans-unit>
5449 <trans-unit id="4e4107055b44eee44b6954c41120de1cb4d46432"> 5353 <trans-unit id="4e4107055b44eee44b6954c41120de1cb4d46432">
5450 <source>Mute this account by your instance</source><target>Mute this account by your instance</target><context-group name="null"> 5354 <source>Mute this account by your instance</source>
5355 <target>Ignorera det här kontot av din instans</target>
5356 <context-group name="null">
5451 <context context-type="linenumber">1</context> 5357 <context context-type="linenumber">1</context>
5452 </context-group> 5358 </context-group>
5453 </trans-unit> 5359 </trans-unit>
5454 <trans-unit id="a51c59cb5ecb7004a6a8ddd2855b5c52266ad957"> 5360 <trans-unit id="a51c59cb5ecb7004a6a8ddd2855b5c52266ad957">
5455 <source>Unmute this account by your instance</source><target>Unmute this account by your instance</target><context-group name="null"> 5361 <source>Unmute this account by your instance</source>
5362 <target>Sluta ignorera det här kontot av din instans</target>
5363 <context-group name="null">
5456 <context context-type="linenumber">1</context> 5364 <context context-type="linenumber">1</context>
5457 </context-group> 5365 </context-group>
5458 </trans-unit> 5366 </trans-unit>
5459 <trans-unit id="588073e831cec240d6bb0db0b133e45dab69f178"> 5367 <trans-unit id="588073e831cec240d6bb0db0b133e45dab69f178">
5460 <source>Mute the instance by your instance</source><target>Mute the instance by your instance</target><context-group name="null"> 5368 <source>Mute the instance by your instance</source>
5369 <target>Ignorera instansen av din instans</target>
5370 <context-group name="null">
5461 <context context-type="linenumber">1</context> 5371 <context context-type="linenumber">1</context>
5462 </context-group> 5372 </context-group>
5463 </trans-unit> 5373 </trans-unit>
5464 <trans-unit id="676221cdabd4805901343976988c028dbf71b20a"> 5374 <trans-unit id="676221cdabd4805901343976988c028dbf71b20a">
5465 <source>Unmute the instance by your instance</source><target>Unmute the instance by your instance</target><context-group name="null"> 5375 <source>Unmute the instance by your instance</source>
5376 <target>Sluta ignorera instansen av din instans</target>
5377 <context-group name="null">
5466 <context context-type="linenumber">1</context> 5378 <context context-type="linenumber">1</context>
5467 </context-group> 5379 </context-group>
5468 </trans-unit> 5380 </trans-unit>
@@ -5494,13 +5406,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
5494 <context context-type="linenumber">1</context> 5406 <context context-type="linenumber">1</context>
5495 </context-group> 5407 </context-group>
5496 </trans-unit> 5408 </trans-unit>
5497 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5498 <source>Subscribed</source>
5499 <target>Prenumererar</target>
5500 <context-group name="null">
5501 <context context-type="linenumber">1</context>
5502 </context-group>
5503 </trans-unit>
5504 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded"> 5409 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
5505 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source> 5410 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
5506 <target>Prenumererar på <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target> 5411 <target>Prenumererar på <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
@@ -5508,9 +5413,9 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
5508 <context context-type="linenumber">1</context> 5413 <context context-type="linenumber">1</context>
5509 </context-group> 5414 </context-group>
5510 </trans-unit> 5415 </trans-unit>
5511 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471"> 5416 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5512 <source>Unsubscribed</source> 5417 <source>Subscribed</source>
5513 <target>Prenumeration avbruten</target> 5418 <target>Prenumererar</target>
5514 <context-group name="null"> 5419 <context-group name="null">
5515 <context context-type="linenumber">1</context> 5420 <context context-type="linenumber">1</context>
5516 </context-group> 5421 </context-group>
@@ -5522,6 +5427,13 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
5522 <context context-type="linenumber">1</context> 5427 <context context-type="linenumber">1</context>
5523 </context-group> 5428 </context-group>
5524 </trans-unit> 5429 </trans-unit>
5430 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
5431 <source>Unsubscribed</source>
5432 <target>Prenumeration avbruten</target>
5433 <context-group name="null">
5434 <context context-type="linenumber">1</context>
5435 </context-group>
5436 </trans-unit>
5525 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf"> 5437 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf">
5526 <source>Moderator</source> 5438 <source>Moderator</source>
5527 <target>Moderator</target> 5439 <target>Moderator</target>
@@ -5550,6 +5462,20 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
5550 <context context-type="linenumber">1</context> 5462 <context context-type="linenumber">1</context>
5551 </context-group> 5463 </context-group>
5552 </trans-unit> 5464 </trans-unit>
5465 <trans-unit id="21565881ad1dff3c98738b9535b3515cec140609">
5466 <source>Welcome! Now please check your emails to verify your account and complete signup.</source>
5467 <target>Välkommen! Kontrollera gärna din e-post för att verifiera ditt konto och fullfölja kontoskapandet.</target>
5468 <context-group name="null">
5469 <context context-type="linenumber">1</context>
5470 </context-group>
5471 </trans-unit>
5472 <trans-unit id="14200e26888a07633c0f177020dce8f3ec7311a6">
5473 <source>You are now logged in as <x id="INTERPOLATION" equiv-text="{{username}}"/>!</source>
5474 <target>Du är nu inloggad som <x id="INTERPOLATION" equiv-text="{{username}}"/>!</target>
5475 <context-group name="null">
5476 <context context-type="linenumber">1</context>
5477 </context-group>
5478 </trans-unit>
5553 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb"> 5479 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb">
5554 <source>Video to import updated.</source> 5480 <source>Video to import updated.</source>
5555 <target>Videon att importera har uppdaterats.</target> 5481 <target>Videon att importera har uppdaterats.</target>
@@ -5578,13 +5504,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
5578 <context context-type="linenumber">1</context> 5504 <context context-type="linenumber">1</context>
5579 </context-group> 5505 </context-group>
5580 </trans-unit> 5506 </trans-unit>
5581 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
5582 <source>Info</source>
5583 <target>Information</target>
5584 <context-group name="null">
5585 <context context-type="linenumber">1</context>
5586 </context-group>
5587 </trans-unit>
5588 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 5507 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
5589 <source>Upload cancelled</source> 5508 <source>Upload cancelled</source>
5590 <target>Uppladdningen avbröts</target> 5509 <target>Uppladdningen avbröts</target>
@@ -5592,13 +5511,6 @@ När du laddar upp en video i den här kanalen kommer supportfältet automatiskt
5592 <context context-type="linenumber">1</context> 5511 <context context-type="linenumber">1</context>
5593 </context-group> 5512 </context-group>
5594 </trans-unit> 5513 </trans-unit>
5595 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa">
5596 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
5597 <target>Vi ber om ursäkt, PeerTube kan tyvärr inte hantera videor större än 8GB</target>
5598 <context-group name="null">
5599 <context context-type="linenumber">1</context>
5600 </context-group>
5601 </trans-unit>
5602 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee"> 5514 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
5603 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source> 5515 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
5604 <target>Den här videon kommer överskrida din videokvot (videostorlek: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, använt: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, kvot: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target> 5516 <target>Den här videon kommer överskrida din videokvot (videostorlek: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, använt: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, kvot: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
diff --git a/client/src/locale/target/angular_ta.xml b/client/src/locale/target/angular_ta.xml
index 35385cfdb..abd878aaa 100644
--- a/client/src/locale/target/angular_ta.xml
+++ b/client/src/locale/target/angular_ta.xml
@@ -201,14 +201,14 @@
201 <source>Password</source> 201 <source>Password</source>
202 <target>கடவà¯à®šà¯à®šà¯Šà®²à¯</target> 202 <target>கடவà¯à®šà¯à®šà¯Šà®²à¯</target>
203 <context-group name="null"> 203 <context-group name="null">
204 <context context-type="linenumber">12</context> 204 <context context-type="linenumber">13</context>
205 </context-group> 205 </context-group>
206 </trans-unit> 206 </trans-unit>
207 <trans-unit id="6765b4c916060f6bc42d9bb69e80377dbcb5e4e9"> 207 <trans-unit id="6765b4c916060f6bc42d9bb69e80377dbcb5e4e9">
208 <source>Login</source> 208 <source>Login</source>
209 <target>உளà¯à®¨à¯à®´à¯ˆ</target> 209 <target>உளà¯à®¨à¯à®´à¯ˆ</target>
210 <context-group name="null"> 210 <context-group name="null">
211 <context context-type="linenumber">38</context> 211 <context context-type="linenumber">36</context>
212 </context-group> 212 </context-group>
213 </trans-unit> 213 </trans-unit>
214 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 214 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -257,7 +257,7 @@
257 <source>Change the language</source> 257 <source>Change the language</source>
258 <target>மொழியை மாறà¯à®±à¯</target> 258 <target>மொழியை மாறà¯à®±à¯</target>
259 <context-group name="null"> 259 <context-group name="null">
260 <context context-type="linenumber">88</context> 260 <context context-type="linenumber">86</context>
261 </context-group> 261 </context-group>
262 </trans-unit> 262 </trans-unit>
263 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 263 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -268,28 +268,28 @@
268 வெளியேற௠268 வெளியேறà¯
269 </target> 269 </target>
270 <context-group name="null"> 270 <context-group name="null">
271 <context context-type="linenumber">30</context> 271 <context context-type="linenumber">28</context>
272 </context-group> 272 </context-group>
273 </trans-unit> 273 </trans-unit>
274 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 274 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
275 <source>Create an account</source> 275 <source>Create an account</source>
276 <target>கணகà¯à®•à¯ˆ உரà¯à®µà®¾à®•à¯à®•à¯</target> 276 <target>கணகà¯à®•à¯ˆ உரà¯à®µà®¾à®•à¯à®•à¯</target>
277 <context-group name="null"> 277 <context-group name="null">
278 <context context-type="linenumber">39</context> 278 <context context-type="linenumber">37</context>
279 </context-group> 279 </context-group>
280 </trans-unit> 280 </trans-unit>
281 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 281 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
282 <source>Recently added</source> 282 <source>Recently added</source>
283 <target>சமீபதà¯à®¤à®¿à®¯à®µà¯ˆ</target> 283 <target>சமீபதà¯à®¤à®¿à®¯à®µà¯ˆ</target>
284 <context-group name="null"> 284 <context-group name="null">
285 <context context-type="linenumber">62</context> 285 <context context-type="linenumber">60</context>
286 </context-group> 286 </context-group>
287 </trans-unit> 287 </trans-unit>
288 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 288 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
289 <source>More</source> 289 <source>More</source>
290 <target>மேலà¯à®®à¯</target> 290 <target>மேலà¯à®®à¯</target>
291 <context-group name="null"> 291 <context-group name="null">
292 <context context-type="linenumber">72</context> 292 <context context-type="linenumber">70</context>
293 </context-group> 293 </context-group>
294 </trans-unit> 294 </trans-unit>
295 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 295 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -352,7 +352,7 @@
352 <source>No results.</source> 352 <source>No results.</source>
353 <target>à®®à¯à®Ÿà®¿à®µà¯à®•à®³à¯ இலà¯à®²à¯ˆ.</target> 353 <target>à®®à¯à®Ÿà®¿à®µà¯à®•à®³à¯ இலà¯à®²à¯ˆ.</target>
354 <context-group name="null"> 354 <context-group name="null">
355 <context context-type="linenumber">17</context> 355 <context context-type="linenumber">20</context>
356 </context-group> 356 </context-group>
357 </trans-unit> 357 </trans-unit>
358 <trans-unit id="6385c357c1de58ce92c0cf618ecf9cf74b917390"> 358 <trans-unit id="6385c357c1de58ce92c0cf618ecf9cf74b917390">
@@ -394,7 +394,7 @@
394 <source>Users</source> 394 <source>Users</source>
395 <target>பயணரà¯à®•à®³à¯</target> 395 <target>பயணரà¯à®•à®³à¯</target>
396 <context-group name="null"> 396 <context-group name="null">
397 <context context-type="linenumber">144</context> 397 <context context-type="linenumber">105</context>
398 </context-group> 398 </context-group>
399 </trans-unit> 399 </trans-unit>
400 <trans-unit id="99cb827741e93125476a0f5b676372d85d15b5fc"> 400 <trans-unit id="99cb827741e93125476a0f5b676372d85d15b5fc">
@@ -408,7 +408,7 @@
408 <source>Your Twitter username</source> 408 <source>Your Twitter username</source>
409 <target>உஙà¯à®•à®³à¯ Twitter பயணரà¯à®ªà¯†à®¯à®°à¯</target> 409 <target>உஙà¯à®•à®³à¯ Twitter பயணரà¯à®ªà¯†à®¯à®°à¯</target>
410 <context-group name="null"> 410 <context-group name="null">
411 <context context-type="linenumber">181</context> 411 <context context-type="linenumber">184</context>
412 </context-group> 412 </context-group>
413 </trans-unit> 413 </trans-unit>
414 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 414 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -422,7 +422,7 @@
422 <source>JavaScript</source> 422 <source>JavaScript</source>
423 <target>JavaScript</target> 423 <target>JavaScript</target>
424 <context-group name="null"> 424 <context-group name="null">
425 <context context-type="linenumber">278</context> 425 <context context-type="linenumber">294</context>
426 </context-group> 426 </context-group>
427 </trans-unit> 427 </trans-unit>
428 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 428 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
diff --git a/client/src/locale/target/angular_zh_Hans_CN.xml b/client/src/locale/target/angular_zh_Hans_CN.xml
index c8ed702f8..09ed78392 100644
--- a/client/src/locale/target/angular_zh_Hans_CN.xml
+++ b/client/src/locale/target/angular_zh_Hans_CN.xml
@@ -499,7 +499,7 @@
499 <source>Password</source> 499 <source>Password</source>
500 <target>密ç </target> 500 <target>密ç </target>
501 <context-group name="null"> 501 <context-group name="null">
502 <context context-type="linenumber">12</context> 502 <context context-type="linenumber">13</context>
503 </context-group> 503 </context-group>
504 </trans-unit> 504 </trans-unit>
505 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 505 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -513,7 +513,7 @@
513 <source>Login</source> 513 <source>Login</source>
514 <target>登录</target> 514 <target>登录</target>
515 <context-group name="null"> 515 <context-group name="null">
516 <context context-type="linenumber">38</context> 516 <context context-type="linenumber">36</context>
517 </context-group> 517 </context-group>
518 </trans-unit> 518 </trans-unit>
519 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 519 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -541,7 +541,7 @@
541 <source>Send me an email to reset my password</source> 541 <source>Send me an email to reset my password</source>
542 <target>å‘é€å¯†ç é‡ç½®é‚®ä»¶</target> 542 <target>å‘é€å¯†ç é‡ç½®é‚®ä»¶</target>
543 <context-group name="null"> 543 <context-group name="null">
544 <context context-type="linenumber">75</context> 544 <context context-type="linenumber">80</context>
545 </context-group> 545 </context-group>
546 </trans-unit> 546 </trans-unit>
547 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 547 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -610,7 +610,7 @@
610 <source>Signup</source> 610 <source>Signup</source>
611 <target>注册</target> 611 <target>注册</target>
612 <context-group name="null"> 612 <context-group name="null">
613 <context context-type="linenumber">88</context> 613 <context context-type="linenumber">78</context>
614 </context-group> 614 </context-group>
615 </trans-unit> 615 </trans-unit>
616 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 616 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -680,7 +680,7 @@
680 <source>Change the language</source> 680 <source>Change the language</source>
681 <target>更改语言</target> 681 <target>更改语言</target>
682 <context-group name="null"> 682 <context-group name="null">
683 <context context-type="linenumber">88</context> 683 <context context-type="linenumber">86</context>
684 </context-group> 684 </context-group>
685 </trans-unit> 685 </trans-unit>
686 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 686 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -691,7 +691,7 @@
691 我的公开个人资料 691 我的公开个人资料
692 </target> 692 </target>
693 <context-group name="null"> 693 <context-group name="null">
694 <context context-type="linenumber">18</context> 694 <context context-type="linenumber">16</context>
695 </context-group> 695 </context-group>
696 </trans-unit> 696 </trans-unit>
697 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 697 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -702,7 +702,7 @@
702 我的å¸æˆ· 702 我的å¸æˆ·
703 </target> 703 </target>
704 <context-group name="null"> 704 <context-group name="null">
705 <context context-type="linenumber">22</context> 705 <context context-type="linenumber">20</context>
706 </context-group> 706 </context-group>
707 </trans-unit> 707 </trans-unit>
708 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 708 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -713,7 +713,7 @@
713 我的视频 713 我的视频
714 </target> 714 </target>
715 <context-group name="null"> 715 <context-group name="null">
716 <context context-type="linenumber">26</context> 716 <context context-type="linenumber">24</context>
717 </context-group> 717 </context-group>
718 </trans-unit> 718 </trans-unit>
719 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 719 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -724,14 +724,14 @@
724 注销 724 注销
725 </target> 725 </target>
726 <context-group name="null"> 726 <context-group name="null">
727 <context context-type="linenumber">30</context> 727 <context context-type="linenumber">28</context>
728 </context-group> 728 </context-group>
729 </trans-unit> 729 </trans-unit>
730 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 730 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
731 <source>Create an account</source> 731 <source>Create an account</source>
732 <target>创建å¸æˆ·</target> 732 <target>创建å¸æˆ·</target>
733 <context-group name="null"> 733 <context-group name="null">
734 <context context-type="linenumber">39</context> 734 <context context-type="linenumber">37</context>
735 </context-group> 735 </context-group>
736 </trans-unit> 736 </trans-unit>
737 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 737 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -745,49 +745,49 @@
745 <source>Subscriptions</source> 745 <source>Subscriptions</source>
746 <target>订阅内容</target> 746 <target>订阅内容</target>
747 <context-group name="null"> 747 <context-group name="null">
748 <context context-type="linenumber">47</context> 748 <context context-type="linenumber">45</context>
749 </context-group> 749 </context-group>
750 </trans-unit> 750 </trans-unit>
751 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 751 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
752 <source>Overview</source> 752 <source>Overview</source>
753 <target>总览</target> 753 <target>总览</target>
754 <context-group name="null"> 754 <context-group name="null">
755 <context context-type="linenumber">52</context> 755 <context context-type="linenumber">50</context>
756 </context-group> 756 </context-group>
757 </trans-unit> 757 </trans-unit>
758 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 758 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
759 <source>Trending</source> 759 <source>Trending</source>
760 <target>时下æµè¡Œ</target> 760 <target>时下æµè¡Œ</target>
761 <context-group name="null"> 761 <context-group name="null">
762 <context context-type="linenumber">57</context> 762 <context context-type="linenumber">55</context>
763 </context-group> 763 </context-group>
764 </trans-unit> 764 </trans-unit>
765 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 765 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
766 <source>Recently added</source> 766 <source>Recently added</source>
767 <target>最近添加</target> 767 <target>最近添加</target>
768 <context-group name="null"> 768 <context-group name="null">
769 <context context-type="linenumber">62</context> 769 <context context-type="linenumber">60</context>
770 </context-group> 770 </context-group>
771 </trans-unit> 771 </trans-unit>
772 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 772 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
773 <source>Local</source> 773 <source>Local</source>
774 <target>本地</target> 774 <target>本地</target>
775 <context-group name="null"> 775 <context-group name="null">
776 <context context-type="linenumber">67</context> 776 <context context-type="linenumber">65</context>
777 </context-group> 777 </context-group>
778 </trans-unit> 778 </trans-unit>
779 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 779 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
780 <source>More</source> 780 <source>More</source>
781 <target>更多</target> 781 <target>更多</target>
782 <context-group name="null"> 782 <context-group name="null">
783 <context context-type="linenumber">72</context> 783 <context context-type="linenumber">70</context>
784 </context-group> 784 </context-group>
785 </trans-unit> 785 </trans-unit>
786 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 786 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
787 <source>Administration</source> 787 <source>Administration</source>
788 <target>管ç†</target> 788 <target>管ç†</target>
789 <context-group name="null"> 789 <context-group name="null">
790 <context context-type="linenumber">76</context> 790 <context context-type="linenumber">74</context>
791 </context-group> 791 </context-group>
792 </trans-unit> 792 </trans-unit>
793 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 793 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -801,14 +801,14 @@
801 <source>Show keyboard shortcuts</source> 801 <source>Show keyboard shortcuts</source>
802 <target>显示键盘快æ·é”®</target> 802 <target>显示键盘快æ·é”®</target>
803 <context-group name="null"> 803 <context-group name="null">
804 <context context-type="linenumber">91</context> 804 <context context-type="linenumber">89</context>
805 </context-group> 805 </context-group>
806 </trans-unit> 806 </trans-unit>
807 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 807 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
808 <source>Toggle dark interface</source> 808 <source>Toggle dark interface</source>
809 <target>切æ¢å¤œé—´æ¨¡å¼</target> 809 <target>切æ¢å¤œé—´æ¨¡å¼</target>
810 <context-group name="null"> 810 <context-group name="null">
811 <context context-type="linenumber">94</context> 811 <context context-type="linenumber">92</context>
812 </context-group> 812 </context-group>
813 </trans-unit> 813 </trans-unit>
814 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 814 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -913,14 +913,14 @@
913 <source>Display unlisted and private videos</source> 913 <source>Display unlisted and private videos</source>
914 <target>显示ä¸å…¬å¼€å’Œç§äº«è§†é¢‘</target> 914 <target>显示ä¸å…¬å¼€å’Œç§äº«è§†é¢‘</target>
915 <context-group name="null"> 915 <context-group name="null">
916 <context context-type="linenumber">11</context> 916 <context context-type="linenumber">14</context>
917 </context-group> 917 </context-group>
918 </trans-unit> 918 </trans-unit>
919 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 919 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
920 <source>No results.</source> 920 <source>No results.</source>
921 <target>没有结果。</target> 921 <target>没有结果。</target>
922 <context-group name="null"> 922 <context-group name="null">
923 <context context-type="linenumber">17</context> 923 <context context-type="linenumber">20</context>
924 </context-group> 924 </context-group>
925 </trans-unit> 925 </trans-unit>
926 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 926 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -978,15 +978,22 @@
978 <context context-type="linenumber">7</context> 978 <context context-type="linenumber">7</context>
979 </context-group> 979 </context-group>
980 </trans-unit> 980 </trans-unit>
981 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 981 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
982 <source> 982 <source>
983 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 983 Cancel
984</source> 984 </source>
985 <target> 985 <target>
986 关于实例 <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> 986 å–消
987</target> 987 </target>
988 <context-group name="null"> 988 <context-group name="null">
989 <context context-type="linenumber">1</context> 989 <context context-type="linenumber">26</context>
990 </context-group>
991 </trans-unit>
992 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
993 <source>Submit</source>
994 <target>æ交</target>
995 <context-group name="null">
996 <context context-type="linenumber">31</context>
990 </context-group> 997 </context-group>
991 </trans-unit> 998 </trans-unit>
992 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 999 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -1000,47 +1007,14 @@
1000 <source>Terms</source> 1007 <source>Terms</source>
1001 <target>æ¡æ¬¾</target> 1008 <target>æ¡æ¬¾</target>
1002 <context-group name="null"> 1009 <context-group name="null">
1003 <context context-type="linenumber">44</context> 1010 <context context-type="linenumber">39</context>
1004 </context-group> 1011 </context-group>
1005 </trans-unit> 1012 </trans-unit>
1006 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 1013 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
1007 <source>User registration is allowed and</source> 1014 <source>User registration is allowed and</source>
1008 <target>当å‰å¼€æ”¾æ³¨å†Œï¼Œå¹¶ä¸”</target> 1015 <target>当å‰å¼€æ”¾æ³¨å†Œï¼Œå¹¶ä¸”</target>
1009 <context-group name="null"> 1016 <context-group name="null">
1010 <context context-type="linenumber">25</context> 1017 <context context-type="linenumber">29</context>
1011 </context-group>
1012 </trans-unit>
1013 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
1014 <source>
1015 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
1016 </source>
1017 <target>
1018 本实例为用户上传的视频æä¾› <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> 的基本存储空间。
1019 </target>
1020 <context-group name="null">
1021 <context context-type="linenumber">27</context>
1022 </context-group>
1023 </trans-unit>
1024 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
1025 <source>
1026 this instance provides unlimited space for the videos of its users.
1027 </source>
1028 <target>
1029 本实例为用户上传的视频æ供无é™åˆ¶çš„存储空间。
1030 </target>
1031 <context-group name="null">
1032 <context context-type="linenumber">31</context>
1033 </context-group>
1034 </trans-unit>
1035 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
1036 <source>
1037 User registration is currently not allowed.
1038 </source>
1039 <target>
1040 当å‰ä¸å¼€æ”¾æ³¨å†Œã€‚
1041 </target>
1042 <context-group name="null">
1043 <context context-type="linenumber">36</context>
1044 </context-group> 1018 </context-group>
1045 </trans-unit> 1019 </trans-unit>
1046 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 1020 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1395,49 +1369,49 @@
1395 <source>Short description</source> 1369 <source>Short description</source>
1396 <target>简介</target> 1370 <target>简介</target>
1397 <context-group name="null"> 1371 <context-group name="null">
1398 <context context-type="linenumber">22</context> 1372 <context context-type="linenumber">21</context>
1399 </context-group> 1373 </context-group>
1400 </trans-unit> 1374 </trans-unit>
1401 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1375 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1402 <source>Default client route</source> 1376 <source>Default client route</source>
1403 <target>首页默认内容</target> 1377 <target>首页默认内容</target>
1404 <context-group name="null"> 1378 <context-group name="null">
1405 <context context-type="linenumber">55</context> 1379 <context context-type="linenumber">48</context>
1406 </context-group> 1380 </context-group>
1407 </trans-unit> 1381 </trans-unit>
1408 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1382 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1409 <source>Videos Overview</source> 1383 <source>Videos Overview</source>
1410 <target>视频总览</target> 1384 <target>视频总览</target>
1411 <context-group name="null"> 1385 <context-group name="null">
1412 <context context-type="linenumber">58</context> 1386 <context context-type="linenumber">51</context>
1413 </context-group> 1387 </context-group>
1414 </trans-unit> 1388 </trans-unit>
1415 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1389 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1416 <source>Videos Trending</source> 1390 <source>Videos Trending</source>
1417 <target>时下æµè¡Œçš„视频</target> 1391 <target>时下æµè¡Œçš„视频</target>
1418 <context-group name="null"> 1392 <context-group name="null">
1419 <context context-type="linenumber">59</context> 1393 <context context-type="linenumber">52</context>
1420 </context-group> 1394 </context-group>
1421 </trans-unit> 1395 </trans-unit>
1422 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1396 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1423 <source>Videos Recently Added</source> 1397 <source>Videos Recently Added</source>
1424 <target>最近添加的视频</target> 1398 <target>最近添加的视频</target>
1425 <context-group name="null"> 1399 <context-group name="null">
1426 <context context-type="linenumber">60</context> 1400 <context context-type="linenumber">53</context>
1427 </context-group> 1401 </context-group>
1428 </trans-unit> 1402 </trans-unit>
1429 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1403 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1430 <source>Local videos</source> 1404 <source>Local videos</source>
1431 <target>本地视频</target> 1405 <target>本地视频</target>
1432 <context-group name="null"> 1406 <context-group name="null">
1433 <context context-type="linenumber">61</context> 1407 <context context-type="linenumber">54</context>
1434 </context-group> 1408 </context-group>
1435 </trans-unit> 1409 </trans-unit>
1436 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1410 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1437 <source>Policy on videos containing sensitive content</source> 1411 <source>Policy on videos containing sensitive content</source>
1438 <target>针对包å«æ•æ„Ÿå†…容视频的策略</target> 1412 <target>针对包å«æ•æ„Ÿå†…容视频的策略</target>
1439 <context-group name="null"> 1413 <context-group name="null">
1440 <context context-type="linenumber">70</context> 1414 <context context-type="linenumber">61</context>
1441 </context-group> 1415 </context-group>
1442 </trans-unit> 1416 </trans-unit>
1443 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1417 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1472,23 +1446,44 @@
1472 <source>Signup enabled</source> 1446 <source>Signup enabled</source>
1473 <target>开放注册</target> 1447 <target>开放注册</target>
1474 <context-group name="null"> 1448 <context-group name="null">
1475 <context context-type="linenumber">93</context> 1449 <context context-type="linenumber">84</context>
1476 </context-group> 1450 </context-group>
1477 </trans-unit> 1451 </trans-unit>
1478 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1452 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1479 <source>Signup requires email verification</source> 1453 <source>Signup requires email verification</source>
1480 <target>注册需è¦éªŒè¯ç”µå­é‚®ä»¶åœ°å€</target> 1454 <target>注册需è¦éªŒè¯ç”µå­é‚®ä»¶åœ°å€</target>
1481 <context-group name="null"> 1455 <context-group name="null">
1482 <context context-type="linenumber">100</context> 1456 <context context-type="linenumber">91</context>
1483 </context-group> 1457 </context-group>
1484 </trans-unit> 1458 </trans-unit>
1485 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1459 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1486 <source>Signup limit</source> 1460 <source>Signup limit</source>
1487 <target>注册é™åˆ¶</target> 1461 <target>注册é™åˆ¶</target>
1488 <context-group name="null"> 1462 <context-group name="null">
1463 <context context-type="linenumber">96</context>
1464 </context-group>
1465 </trans-unit>
1466 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1467 <source>Users</source>
1468 <target>用户</target>
1469 <context-group name="null">
1489 <context context-type="linenumber">105</context> 1470 <context context-type="linenumber">105</context>
1490 </context-group> 1471 </context-group>
1491 </trans-unit> 1472 </trans-unit>
1473 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1474 <source>User default video quota</source>
1475 <target>用户默认视频存储空间大å°</target>
1476 <context-group name="null">
1477 <context context-type="linenumber">109</context>
1478 </context-group>
1479 </trans-unit>
1480 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1481 <source>User default daily upload limit</source>
1482 <target>用户默认å•æ—¥ä¸Šä¼ é™é¢</target>
1483 <context-group name="null">
1484 <context context-type="linenumber">121</context>
1485 </context-group>
1486 </trans-unit>
1492 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1487 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1493 <source>Import</source> 1488 <source>Import</source>
1494 <target>导入</target> 1489 <target>导入</target>
@@ -1500,49 +1495,28 @@
1500 <source>Video import with HTTP URL (i.e. YouTube) enabled</source> 1495 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1501 <target>å…许通过 HTTP URL(例如 YouTube)导入视频</target> 1496 <target>å…许通过 HTTP URL(例如 YouTube)导入视频</target>
1502 <context-group name="null"> 1497 <context-group name="null">
1503 <context context-type="linenumber">120</context> 1498 <context context-type="linenumber">141</context>
1504 </context-group> 1499 </context-group>
1505 </trans-unit> 1500 </trans-unit>
1506 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e"> 1501 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e">
1507 <source>Video import with a torrent file or a magnet URI enabled</source> 1502 <source>Video import with a torrent file or a magnet URI enabled</source>
1508 <target>å…许通过ç§å­æ–‡ä»¶æˆ–ç£åŠ›é“¾å¯¼å…¥è§†é¢‘</target> 1503 <target>å…许通过ç§å­æ–‡ä»¶æˆ–ç£åŠ›é“¾å¯¼å…¥è§†é¢‘</target>
1509 <context-group name="null"> 1504 <context-group name="null">
1510 <context context-type="linenumber">127</context> 1505 <context context-type="linenumber">148</context>
1511 </context-group> 1506 </context-group>
1512 </trans-unit> 1507 </trans-unit>
1513 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1508 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1514 <source>Administrator</source> 1509 <source>Administrator</source>
1515 <target>管ç†å‘˜</target> 1510 <target>管ç†å‘˜</target>
1516 <context-group name="null"> 1511 <context-group name="null">
1517 <context context-type="linenumber">131</context> 1512 <context context-type="linenumber">155</context>
1518 </context-group> 1513 </context-group>
1519 </trans-unit> 1514 </trans-unit>
1520 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1515 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1521 <source>Admin email</source> 1516 <source>Admin email</source>
1522 <target>管ç†å‘˜ç”µå­é‚®ä»¶åœ°å€</target> 1517 <target>管ç†å‘˜ç”µå­é‚®ä»¶åœ°å€</target>
1523 <context-group name="null"> 1518 <context-group name="null">
1524 <context context-type="linenumber">134</context> 1519 <context context-type="linenumber">158</context>
1525 </context-group>
1526 </trans-unit>
1527 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1528 <source>Users</source>
1529 <target>用户</target>
1530 <context-group name="null">
1531 <context context-type="linenumber">144</context>
1532 </context-group>
1533 </trans-unit>
1534 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1535 <source>User default video quota</source>
1536 <target>用户默认视频存储空间大å°</target>
1537 <context-group name="null">
1538 <context context-type="linenumber">147</context>
1539 </context-group>
1540 </trans-unit>
1541 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1542 <source>User default daily upload limit</source>
1543 <target>用户默认å•æ—¥ä¸Šä¼ é™é¢</target>
1544 <context-group name="null">
1545 <context context-type="linenumber">161</context>
1546 </context-group> 1520 </context-group>
1547 </trans-unit> 1521 </trans-unit>
1548 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1522 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1563,21 +1537,21 @@
1563 <source>Your Twitter username</source> 1537 <source>Your Twitter username</source>
1564 <target>您的 Twitter 用户å</target> 1538 <target>您的 Twitter 用户å</target>
1565 <context-group name="null"> 1539 <context-group name="null">
1566 <context context-type="linenumber">181</context> 1540 <context context-type="linenumber">184</context>
1567 </context-group> 1541 </context-group>
1568 </trans-unit> 1542 </trans-unit>
1569 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1543 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1570 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1544 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1571 <target>显示此内容所在的å‘布平å°å¯¹åº”çš„ Twitter å¸æˆ·ã€‚</target> 1545 <target>显示此内容所在的å‘布平å°å¯¹åº”çš„ Twitter å¸æˆ·ã€‚</target>
1572 <context-group name="null"> 1546 <context-group name="null">
1573 <context context-type="linenumber">184</context> 1547 <context context-type="linenumber">187</context>
1574 </context-group> 1548 </context-group>
1575 </trans-unit> 1549 </trans-unit>
1576 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1550 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1577 <source>Instance whitelisted by Twitter</source> 1551 <source>Instance whitelisted by Twitter</source>
1578 <target>实例已进入 Twitter 白åå•</target> 1552 <target>实例已进入 Twitter 白åå•</target>
1579 <context-group name="null"> 1553 <context-group name="null">
1580 <context context-type="linenumber">198</context> 1554 <context context-type="linenumber">199</context>
1581 </context-group> 1555 </context-group>
1582 </trans-unit> 1556 </trans-unit>
1583 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1557 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1591,35 +1565,35 @@
1591 <source>Transcoding</source> 1565 <source>Transcoding</source>
1592 <target>转ç </target> 1566 <target>转ç </target>
1593 <context-group name="null"> 1567 <context-group name="null">
1594 <context context-type="linenumber">210</context> 1568 <context context-type="linenumber">215</context>
1595 </context-group> 1569 </context-group>
1596 </trans-unit> 1570 </trans-unit>
1597 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1571 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1598 <source>Transcoding enabled</source> 1572 <source>Transcoding enabled</source>
1599 <target>å¯ç”¨è½¬ç </target> 1573 <target>å¯ç”¨è½¬ç </target>
1600 <context-group name="null"> 1574 <context-group name="null">
1601 <context context-type="linenumber">215</context> 1575 <context context-type="linenumber">221</context>
1602 </context-group> 1576 </context-group>
1603 </trans-unit> 1577 </trans-unit>
1604 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1578 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1605 <source>If you disable transcoding, many videos from your users will not work!</source> 1579 <source>If you disable transcoding, many videos from your users will not work!</source>
1606 <target>如果ç¦ç”¨è½¬ç ï¼Œç”¨æˆ·ä¸Šä¼ çš„视频很有å¯èƒ½æ— æ³•æ­£å¸¸æ’­æ”¾ï¼</target> 1580 <target>如果ç¦ç”¨è½¬ç ï¼Œç”¨æˆ·ä¸Šä¼ çš„视频很有å¯èƒ½æ— æ³•æ­£å¸¸æ’­æ”¾ï¼</target>
1607 <context-group name="null"> 1581 <context-group name="null">
1608 <context context-type="linenumber">216</context> 1582 <context context-type="linenumber">222</context>
1609 </context-group> 1583 </context-group>
1610 </trans-unit> 1584 </trans-unit>
1611 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1585 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1612 <source>Transcoding threads</source> 1586 <source>Transcoding threads</source>
1613 <target>转ç çº¿ç¨‹æ•°</target> 1587 <target>转ç çº¿ç¨‹æ•°</target>
1614 <context-group name="null"> 1588 <context-group name="null">
1615 <context context-type="linenumber">223</context> 1589 <context context-type="linenumber">237</context>
1616 </context-group> 1590 </context-group>
1617 </trans-unit> 1591 </trans-unit>
1618 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1592 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1619 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1593 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1620 <target>å¯ç”¨ <x id="INTERPOLATION" equiv-text="{{resolution}}"/> 分辨率</target> 1594 <target>å¯ç”¨ <x id="INTERPOLATION" equiv-text="{{resolution}}"/> 分辨率</target>
1621 <context-group name="null"> 1595 <context-group name="null">
1622 <context context-type="linenumber">239</context> 1596 <context context-type="linenumber">252</context>
1623 </context-group> 1597 </context-group>
1624 </trans-unit> 1598 </trans-unit>
1625 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1599 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1634,83 +1608,48 @@
1634 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1608 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1635 </target> 1609 </target>
1636 <context-group name="null"> 1610 <context-group name="null">
1637 <context context-type="linenumber">244</context> 1611 <context context-type="linenumber">260</context>
1638 </context-group> 1612 </context-group>
1639 </trans-unit> 1613 </trans-unit>
1640 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1614 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1641 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1615 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1642 <target>部分文件ä¸ä¼šè‡ªåŠ¨åŒæ­¥ï¼ˆå¦‚预览图ã€å­—幕)。我们会直接从æºå®žä¾‹æ‹‰å–并进行缓存。</target> 1616 <target>部分文件ä¸ä¼šè‡ªåŠ¨åŒæ­¥ï¼ˆå¦‚预览图ã€å­—幕)。我们会直接从æºå®žä¾‹æ‹‰å–并进行缓存。</target>
1643 <context-group name="null"> 1617 <context-group name="null">
1644 <context context-type="linenumber">249</context> 1618 <context context-type="linenumber">265</context>
1645 </context-group> 1619 </context-group>
1646 </trans-unit> 1620 </trans-unit>
1647 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1621 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1648 <source>Previews cache size</source> 1622 <source>Previews cache size</source>
1649 <target>预览图缓存大å°</target> 1623 <target>预览图缓存大å°</target>
1650 <context-group name="null"> 1624 <context-group name="null">
1651 <context context-type="linenumber">254</context> 1625 <context context-type="linenumber">271</context>
1652 </context-group> 1626 </context-group>
1653 </trans-unit> 1627 </trans-unit>
1654 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1628 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1655 <source>Video captions cache size</source> 1629 <source>Video captions cache size</source>
1656 <target>视频字幕缓存大å°</target> 1630 <target>视频字幕缓存大å°</target>
1657 <context-group name="null"> 1631 <context-group name="null">
1658 <context context-type="linenumber">265</context> 1632 <context context-type="linenumber">280</context>
1659 </context-group> 1633 </context-group>
1660 </trans-unit> 1634 </trans-unit>
1661 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1635 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1662 <source>Customizations</source> 1636 <source>Customizations</source>
1663 <target>自定义</target> 1637 <target>自定义</target>
1664 <context-group name="null"> 1638 <context-group name="null">
1665 <context context-type="linenumber">275</context> 1639 <context context-type="linenumber">289</context>
1666 </context-group> 1640 </context-group>
1667 </trans-unit> 1641 </trans-unit>
1668 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1642 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1669 <source>JavaScript</source> 1643 <source>JavaScript</source>
1670 <target>JavaScript</target> 1644 <target>JavaScript</target>
1671 <context-group name="null"> 1645 <context-group name="null">
1672 <context context-type="linenumber">278</context> 1646 <context context-type="linenumber">294</context>
1673 </context-group> 1647 </context-group>
1674 </trans-unit> 1648 </trans-unit>
1675 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1649 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1676 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1650 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1677 <target>在此处直接输入 JavaScript 代ç ã€‚&lt;br /&gt;示例:&lt;pre&gt;console.log('我的实例太棒了');&lt;/pre&gt;</target> 1651 <target>在此处直接输入 JavaScript 代ç ã€‚&lt;br /&gt;示例:&lt;pre&gt;console.log('我的实例太棒了');&lt;/pre&gt;</target>
1678 <context-group name="null"> 1652 <context-group name="null">
1679 <context context-type="linenumber">281</context>
1680 </context-group>
1681 </trans-unit>
1682 <trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5">
1683 <source>
1684 Write directly CSS code. Example:&lt;br /&gt;
1685 &lt;pre&gt;
1686 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1687 background-color: red;
1688 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1689 &lt;/pre&gt;
1690
1691 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1692 &lt;pre&gt;
1693 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1694 color: red;
1695 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1696 &lt;/pre&gt;
1697 </source>
1698 <target>
1699 在此处直接输入 CSS 代ç ã€‚示例:&lt;br /&gt;
1700 &lt;pre&gt;
1701 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1702 background-color: red;
1703 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1704 &lt;/pre&gt;
1705
1706 您å¯ä»¥é€šè¿‡æ’å…¥ &lt;em&gt;#custom-css&lt;/em&gt; æ¥è¦†ç›–æ ·å¼è®¾ç½®ã€‚示例:
1707 &lt;pre&gt;
1708 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1709 color: red;
1710 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1711 &lt;/pre&gt;
1712 </target>
1713 <context-group name="null">
1714 <context context-type="linenumber">297</context> 1653 <context context-type="linenumber">297</context>
1715 </context-group> 1654 </context-group>
1716 </trans-unit> 1655 </trans-unit>
@@ -1718,21 +1657,21 @@
1718 <source>Advanced configuration</source> 1657 <source>Advanced configuration</source>
1719 <target>高级设置</target> 1658 <target>高级设置</target>
1720 <context-group name="null"> 1659 <context-group name="null">
1721 <context context-type="linenumber">207</context> 1660 <context context-type="linenumber">212</context>
1722 </context-group> 1661 </context-group>
1723 </trans-unit> 1662 </trans-unit>
1724 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1663 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1725 <source>Update configuration</source> 1664 <source>Update configuration</source>
1726 <target>更新设置</target> 1665 <target>更新设置</target>
1727 <context-group name="null"> 1666 <context-group name="null">
1728 <context context-type="linenumber">325</context> 1667 <context context-type="linenumber">340</context>
1729 </context-group> 1668 </context-group>
1730 </trans-unit> 1669 </trans-unit>
1731 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1670 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1732 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1671 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1733 <target>设置信æ¯ä¸åˆæ³•ã€‚请检查å„选项å¡ä¸­çš„设置是å¦å­˜åœ¨é”™è¯¯ã€‚</target> 1672 <target>设置信æ¯ä¸åˆæ³•ã€‚请检查å„选项å¡ä¸­çš„设置是å¦å­˜åœ¨é”™è¯¯ã€‚</target>
1734 <context-group name="null"> 1673 <context-group name="null">
1735 <context context-type="linenumber">326</context> 1674 <context context-type="linenumber">341</context>
1736 </context-group> 1675 </context-group>
1737 </trans-unit> 1676 </trans-unit>
1738 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1677 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -2028,7 +1967,7 @@
2028 <source>Ban reason:</source> 1967 <source>Ban reason:</source>
2029 <target>å°ç¦ç†ç”±ï¼š</target> 1968 <target>å°ç¦ç†ç”±ï¼š</target>
2030 <context-group name="null"> 1969 <context-group name="null">
2031 <context context-type="linenumber">92</context> 1970 <context context-type="linenumber">95</context>
2032 </context-group> 1971 </context-group>
2033 </trans-unit> 1972 </trans-unit>
2034 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 1973 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -2095,7 +2034,7 @@
2095 <source>Actions</source> 2034 <source>Actions</source>
2096 <target>æ“作</target> 2035 <target>æ“作</target>
2097 <context-group name="null"> 2036 <context-group name="null">
2098 <context context-type="linenumber">33</context> 2037 <context context-type="linenumber">35</context>
2099 </context-group> 2038 </context-group>
2100 </trans-unit> 2039 </trans-unit>
2101 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 2040 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -2130,14 +2069,14 @@
2130 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 2069 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2131 <target>日期 <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 2070 <target>日期 <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2132 <context-group name="null"> 2071 <context-group name="null">
2133 <context context-type="linenumber">10</context> 2072 <context context-type="linenumber">11</context>
2134 </context-group> 2073 </context-group>
2135 </trans-unit> 2074 </trans-unit>
2136 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f"> 2075 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
2137 <source>Blacklist reason:</source> 2076 <source>Blacklist reason:</source>
2138 <target>黑åå•ç†ç”±ï¼š</target> 2077 <target>黑åå•ç†ç”±ï¼š</target>
2139 <context-group name="null"> 2078 <context-group name="null">
2140 <context context-type="linenumber">41</context> 2079 <context context-type="linenumber">43</context>
2141 </context-group> 2080 </context-group>
2142 </trans-unit> 2081 </trans-unit>
2143 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 2082 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -2196,69 +2135,6 @@
2196 <context context-type="linenumber">23</context> 2135 <context context-type="linenumber">23</context>
2197 </context-group> 2136 </context-group>
2198 </trans-unit> 2137 </trans-unit>
2199 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2200 <source>My settings</source>
2201 <target>我的设置</target>
2202 <context-group name="null">
2203 <context context-type="linenumber">3</context>
2204 </context-group>
2205 </trans-unit>
2206 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2207 <source>My library</source>
2208 <target>我的库</target>
2209 <context-group name="null">
2210 <context context-type="linenumber">7</context>
2211 </context-group>
2212 </trans-unit>
2213 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2214 <source>My channels</source>
2215 <target>我的频é“</target>
2216 <context-group name="null">
2217 <context context-type="linenumber">12</context>
2218 </context-group>
2219 </trans-unit>
2220 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2221 <source>My videos</source>
2222 <target>我的视频</target>
2223 <context-group name="null">
2224 <context context-type="linenumber">14</context>
2225 </context-group>
2226 </trans-unit>
2227 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2228 <source>My subscriptions</source>
2229 <target>我的订阅</target>
2230 <context-group name="null">
2231 <context context-type="linenumber">16</context>
2232 </context-group>
2233 </trans-unit>
2234 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
2235 <source>My imports</source>
2236 <target>我的导入</target>
2237 <context-group name="null">
2238 <context context-type="linenumber">18</context>
2239 </context-group>
2240 </trans-unit>
2241 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
2242 <source>Misc</source>
2243 <target>æ‚项</target>
2244 <context-group name="null">
2245 <context context-type="linenumber">24</context>
2246 </context-group>
2247 </trans-unit>
2248 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2249 <source>Muted instances</source>
2250 <target>å·²å±è”½çš„实例</target>
2251 <context-group name="null">
2252 <context context-type="linenumber">2</context>
2253 </context-group>
2254 </trans-unit>
2255 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
2256 <source>Ownership changes</source>
2257 <target>视频转移</target>
2258 <context-group name="null">
2259 <context context-type="linenumber">33</context>
2260 </context-group>
2261 </trans-unit>
2262 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 2138 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
2263 <source>Video quota:</source> 2139 <source>Video quota:</source>
2264 <target>视频存储空间:</target> 2140 <target>视频存储空间:</target>
@@ -2270,21 +2146,21 @@
2270 <source>Profile</source> 2146 <source>Profile</source>
2271 <target>个人资料</target> 2147 <target>个人资料</target>
2272 <context-group name="null"> 2148 <context-group name="null">
2273 <context context-type="linenumber">8</context> 2149 <context context-type="linenumber">7</context>
2274 </context-group> 2150 </context-group>
2275 </trans-unit> 2151 </trans-unit>
2276 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 2152 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
2277 <source>Video settings</source> 2153 <source>Video settings</source>
2278 <target>视频设置</target> 2154 <target>视频设置</target>
2279 <context-group name="null"> 2155 <context-group name="null">
2280 <context context-type="linenumber">15</context> 2156 <context context-type="linenumber">16</context>
2281 </context-group> 2157 </context-group>
2282 </trans-unit> 2158 </trans-unit>
2283 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 2159 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
2284 <source>Danger zone</source> 2160 <source>Danger zone</source>
2285 <target>å±é™©é€‰é¡¹</target> 2161 <target>å±é™©é€‰é¡¹</target>
2286 <context-group name="null"> 2162 <context-group name="null">
2287 <context context-type="linenumber">18</context> 2163 <context context-type="linenumber">19</context>
2288 </context-group> 2164 </context-group>
2289 </trans-unit> 2165 </trans-unit>
2290 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 2166 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -2312,13 +2188,6 @@
2312 <context context-type="linenumber">35</context> 2188 <context context-type="linenumber">35</context>
2313 </context-group> 2189 </context-group>
2314 </trans-unit> 2190 </trans-unit>
2315 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
2316 <source>Submit</source>
2317 <target>æ交</target>
2318 <context-group name="null">
2319 <context context-type="linenumber">24</context>
2320 </context-group>
2321 </trans-unit>
2322 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 2191 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
2323 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 2192 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2324 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> 次观看</target> 2193 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> 次观看</target>
@@ -2478,6 +2347,13 @@ When you will upload a video in this channel, the video support field will be au
2478 <context context-type="linenumber">47</context> 2347 <context context-type="linenumber">47</context>
2479 </context-group> 2348 </context-group>
2480 </trans-unit> 2349 </trans-unit>
2350 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2351 <source>Muted instances</source>
2352 <target>å·²å±è”½çš„实例</target>
2353 <context-group name="null">
2354 <context context-type="linenumber">2</context>
2355 </context-group>
2356 </trans-unit>
2481 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 2357 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
2482 <source>Change password</source> 2358 <source>Change password</source>
2483 <target>更改密ç </target> 2359 <target>更改密ç </target>
@@ -2719,14 +2595,14 @@ When you will upload a video in this channel, the video support field will be au
2719 <source>Publish will be available when upload is finished</source> 2595 <source>Publish will be available when upload is finished</source>
2720 <target>上传完毕åŽå³å¯å‘布</target> 2596 <target>上传完毕åŽå³å¯å‘布</target>
2721 <context-group name="null"> 2597 <context-group name="null">
2722 <context context-type="linenumber">53</context> 2598 <context context-type="linenumber">58</context>
2723 </context-group> 2599 </context-group>
2724 </trans-unit> 2600 </trans-unit>
2725 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 2601 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2726 <source>Publish</source> 2602 <source>Publish</source>
2727 <target>å‘布</target> 2603 <target>å‘布</target>
2728 <context-group name="null"> 2604 <context-group name="null">
2729 <context context-type="linenumber">60</context> 2605 <context context-type="linenumber">65</context>
2730 </context-group> 2606 </context-group>
2731 </trans-unit> 2607 </trans-unit>
2732 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 2608 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -2909,14 +2785,14 @@ When you will upload a video in this channel, the video support field will be au
2909 <source>Wait transcoding before publishing the video</source> 2785 <source>Wait transcoding before publishing the video</source>
2910 <target>等待转ç å®Œæ¯•åŽå†å‘布视频</target> 2786 <target>等待转ç å®Œæ¯•åŽå†å‘布视频</target>
2911 <context-group name="null"> 2787 <context-group name="null">
2912 <context context-type="linenumber">130</context> 2788 <context context-type="linenumber">131</context>
2913 </context-group> 2789 </context-group>
2914 </trans-unit> 2790 </trans-unit>
2915 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 2791 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2916 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 2792 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
2917 <target>如果您选择ä¸ç­‰å¾…转ç å°±å‘布视频,则视频在转ç å®Œæ¯•å‰å¾ˆæœ‰å¯èƒ½æ— æ³•æ­£å¸¸æ’­æ”¾ã€‚</target> 2793 <target>如果您选择ä¸ç­‰å¾…转ç å°±å‘布视频,则视频在转ç å®Œæ¯•å‰å¾ˆæœ‰å¯èƒ½æ— æ³•æ­£å¸¸æ’­æ”¾ã€‚</target>
2918 <context-group name="null"> 2794 <context-group name="null">
2919 <context context-type="linenumber">131</context> 2795 <context context-type="linenumber">132</context>
2920 </context-group> 2796 </context-group>
2921 </trans-unit> 2797 </trans-unit>
2922 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2798 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2930,49 +2806,49 @@ When you will upload a video in this channel, the video support field will be au
2930 <source>Add another caption</source> 2806 <source>Add another caption</source>
2931 <target>添加字幕</target> 2807 <target>添加字幕</target>
2932 <context-group name="null"> 2808 <context-group name="null">
2933 <context context-type="linenumber">146</context> 2809 <context context-type="linenumber">147</context>
2934 </context-group> 2810 </context-group>
2935 </trans-unit> 2811 </trans-unit>
2936 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 2812 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2937 <source>See the subtitle file</source> 2813 <source>See the subtitle file</source>
2938 <target>查看字幕文件</target> 2814 <target>查看字幕文件</target>
2939 <context-group name="null"> 2815 <context-group name="null">
2940 <context context-type="linenumber">155</context> 2816 <context context-type="linenumber">156</context>
2941 </context-group> 2817 </context-group>
2942 </trans-unit> 2818 </trans-unit>
2943 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee"> 2819 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee">
2944 <source>Already uploaded ✔</source> 2820 <source>Already uploaded ✔</source>
2945 <target>已上传 ✔</target> 2821 <target>已上传 ✔</target>
2946 <context-group name="null"> 2822 <context-group name="null">
2947 <context context-type="linenumber">159</context> 2823 <context context-type="linenumber">160</context>
2948 </context-group> 2824 </context-group>
2949 </trans-unit> 2825 </trans-unit>
2950 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad"> 2826 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad">
2951 <source>Will be created on update</source> 2827 <source>Will be created on update</source>
2952 <target>将在更新时创建</target> 2828 <target>将在更新时创建</target>
2953 <context-group name="null"> 2829 <context-group name="null">
2954 <context context-type="linenumber">167</context> 2830 <context context-type="linenumber">168</context>
2955 </context-group> 2831 </context-group>
2956 </trans-unit> 2832 </trans-unit>
2957 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 2833 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2958 <source>Cancel create</source> 2834 <source>Cancel create</source>
2959 <target>å–消创建</target> 2835 <target>å–消创建</target>
2960 <context-group name="null"> 2836 <context-group name="null">
2961 <context context-type="linenumber">169</context> 2837 <context context-type="linenumber">170</context>
2962 </context-group> 2838 </context-group>
2963 </trans-unit> 2839 </trans-unit>
2964 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393"> 2840 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393">
2965 <source>Will be deleted on update</source> 2841 <source>Will be deleted on update</source>
2966 <target>将在更新时删除</target> 2842 <target>将在更新时删除</target>
2967 <context-group name="null"> 2843 <context-group name="null">
2968 <context context-type="linenumber">175</context> 2844 <context context-type="linenumber">176</context>
2969 </context-group> 2845 </context-group>
2970 </trans-unit> 2846 </trans-unit>
2971 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 2847 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2972 <source>Cancel deletion</source> 2848 <source>Cancel deletion</source>
2973 <target>å–消删除</target> 2849 <target>å–消删除</target>
2974 <context-group name="null"> 2850 <context-group name="null">
2975 <context context-type="linenumber">177</context> 2851 <context context-type="linenumber">178</context>
2976 </context-group> 2852 </context-group>
2977 </trans-unit> 2853 </trans-unit>
2978 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0"> 2854 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0">
@@ -2983,28 +2859,28 @@ When you will upload a video in this channel, the video support field will be au
2983 当å‰æ²¡æœ‰å­—幕。 2859 当å‰æ²¡æœ‰å­—幕。
2984 </target> 2860 </target>
2985 <context-group name="null"> 2861 <context-group name="null">
2986 <context context-type="linenumber">182</context> 2862 <context context-type="linenumber">183</context>
2987 </context-group> 2863 </context-group>
2988 </trans-unit> 2864 </trans-unit>
2989 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 2865 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2990 <source>Captions</source> 2866 <source>Captions</source>
2991 <target>字幕</target> 2867 <target>字幕</target>
2992 <context-group name="null"> 2868 <context-group name="null">
2993 <context context-type="linenumber">139</context> 2869 <context context-type="linenumber">140</context>
2994 </context-group> 2870 </context-group>
2995 </trans-unit> 2871 </trans-unit>
2996 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 2872 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
2997 <source>Upload thumbnail</source> 2873 <source>Upload thumbnail</source>
2998 <target>上传缩略图</target> 2874 <target>上传缩略图</target>
2999 <context-group name="null"> 2875 <context-group name="null">
3000 <context context-type="linenumber">195</context> 2876 <context context-type="linenumber">196</context>
3001 </context-group> 2877 </context-group>
3002 </trans-unit> 2878 </trans-unit>
3003 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 2879 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
3004 <source>Upload preview</source> 2880 <source>Upload preview</source>
3005 <target>上传预览图</target> 2881 <target>上传预览图</target>
3006 <context-group name="null"> 2882 <context-group name="null">
3007 <context context-type="linenumber">202</context> 2883 <context context-type="linenumber">203</context>
3008 </context-group> 2884 </context-group>
3009 </trans-unit> 2885 </trans-unit>
3010 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 2886 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -3018,14 +2894,14 @@ When you will upload a video in this channel, the video support field will be au
3018 <source>Short text to tell people how they can support you (membership platform...).</source> 2894 <source>Short text to tell people how they can support you (membership platform...).</source>
3019 <target>用一段简短的文字告知观众支æŒæ‚¨çš„频é“的方法(赞助社区等)。</target> 2895 <target>用一段简短的文字告知观众支æŒæ‚¨çš„频é“的方法(赞助社区等)。</target>
3020 <context-group name="null"> 2896 <context-group name="null">
3021 <context context-type="linenumber">209</context> 2897 <context context-type="linenumber">210</context>
3022 </context-group> 2898 </context-group>
3023 </trans-unit> 2899 </trans-unit>
3024 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 2900 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
3025 <source>Advanced settings</source> 2901 <source>Advanced settings</source>
3026 <target>高级设置</target> 2902 <target>高级设置</target>
3027 <context-group name="null"> 2903 <context-group name="null">
3028 <context context-type="linenumber">190</context> 2904 <context context-type="linenumber">191</context>
3029 </context-group> 2905 </context-group>
3030 </trans-unit> 2906 </trans-unit>
3031 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 2907 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -3092,17 +2968,6 @@ When you will upload a video in this channel, the video support field will be au
3092 <context context-type="linenumber">3</context> 2968 <context context-type="linenumber">3</context>
3093 </context-group> 2969 </context-group>
3094 </trans-unit> 2970 </trans-unit>
3095 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
3096 <source>
3097 Cancel
3098 </source>
3099 <target>
3100 å–消
3101 </target>
3102 <context-group name="null">
3103 <context context-type="linenumber">19</context>
3104 </context-group>
3105 </trans-unit>
3106 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 2971 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
3107 <source>Share</source> 2972 <source>Share</source>
3108 <target>分享</target> 2973 <target>分享</target>
@@ -3488,13 +3353,6 @@ When you will upload a video in this channel, the video support field will be au
3488 <context context-type="linenumber">14</context> 3353 <context context-type="linenumber">14</context>
3489 </context-group> 3354 </context-group>
3490 </trans-unit> 3355 </trans-unit>
3491 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
3492 <source>Error getting about from server</source>
3493 <target>从æœåŠ¡å™¨èŽ·å–关于信æ¯æ—¶å‘生错误</target>
3494 <context-group name="null">
3495 <context context-type="linenumber">1</context>
3496 </context-group>
3497 </trans-unit>
3498 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 3356 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
3499 <source>No description</source> 3357 <source>No description</source>
3500 <target>没有说明</target> 3358 <target>没有说明</target>
@@ -3516,13 +3374,6 @@ When you will upload a video in this channel, the video support field will be au
3516 <context context-type="linenumber">1</context> 3374 <context context-type="linenumber">1</context>
3517 </context-group> 3375 </context-group>
3518 </trans-unit> 3376 </trans-unit>
3519 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
3520 <source>Error</source>
3521 <target>错误</target>
3522 <context-group name="null">
3523 <context context-type="linenumber">1</context>
3524 </context-group>
3525 </trans-unit>
3526 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6"> 3377 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
3527 <source>240p</source> 3378 <source>240p</source>
3528 <target>240p</target> 3379 <target>240p</target>
@@ -3565,13 +3416,6 @@ When you will upload a video in this channel, the video support field will be au
3565 <context context-type="linenumber">1</context> 3416 <context context-type="linenumber">1</context>
3566 </context-group> 3417 </context-group>
3567 </trans-unit> 3418 </trans-unit>
3568 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
3569 <source>Success</source>
3570 <target>æˆåŠŸ</target>
3571 <context-group name="null">
3572 <context context-type="linenumber">1</context>
3573 </context-group>
3574 </trans-unit>
3575 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 3419 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
3576 <source>Configuration updated.</source> 3420 <source>Configuration updated.</source>
3577 <target>设置已更新。</target> 3421 <target>设置已更新。</target>
@@ -3993,23 +3837,16 @@ When you will upload a video in this channel, the video support field will be au
3993 <context context-type="linenumber">1</context> 3837 <context context-type="linenumber">1</context>
3994 </context-group> 3838 </context-group>
3995 </trans-unit> 3839 </trans-unit>
3996 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 3840 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
3997 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 3841 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
3998 <target>您确定è¦åˆ é™¤ <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> å—?这将åŒæ—¶åˆ é™¤ä¸Šä¼ è‡³è¯¥é¢‘é“的所有视频。</target> 3842 <target>è§†é¢‘é¢‘é“ <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> 已删除。</target>
3999 <context-group name="null">
4000 <context context-type="linenumber">1</context>
4001 </context-group>
4002 </trans-unit>
4003 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
4004 <source>Please type the name of the video channel to confirm</source>
4005 <target>输入视频频é“的显示å以确认æ“作</target>
4006 <context-group name="null"> 3843 <context-group name="null">
4007 <context context-type="linenumber">1</context> 3844 <context context-type="linenumber">1</context>
4008 </context-group> 3845 </context-group>
4009 </trans-unit> 3846 </trans-unit>
4010 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 3847 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
4011 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 3848 <source>My videos</source>
4012 <target>è§†é¢‘é¢‘é“ <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> 已删除。</target> 3849 <target>我的视频</target>
4013 <context-group name="null"> 3850 <context-group name="null">
4014 <context context-type="linenumber">1</context> 3851 <context context-type="linenumber">1</context>
4015 </context-group> 3852 </context-group>
@@ -4084,16 +3921,44 @@ When you will upload a video in this channel, the video support field will be au
4084 <context context-type="linenumber">1</context> 3921 <context context-type="linenumber">1</context>
4085 </context-group> 3922 </context-group>
4086 </trans-unit> 3923 </trans-unit>
4087 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 3924 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
4088 <source>Channels</source> 3925 <source>My library</source>
4089 <target>é¢é“</target> 3926 <target>æˆçš„库</target>
4090 <context-group name="null"> 3927 <context-group name="null">
4091 <context context-type="linenumber">1</context> 3928 <context context-type="linenumber">1</context>
4092 </context-group> 3929 </context-group>
4093 </trans-unit> 3930 </trans-unit>
4094 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d"> 3931 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
4095 <source>Video imports</source> 3932 <source>My channels</source>
4096 <target>导入的视频</target> 3933 <target>我的频é“</target>
3934 <context-group name="null">
3935 <context context-type="linenumber">1</context>
3936 </context-group>
3937 </trans-unit>
3938 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
3939 <source>My subscriptions</source>
3940 <target>我的订阅</target>
3941 <context-group name="null">
3942 <context context-type="linenumber">1</context>
3943 </context-group>
3944 </trans-unit>
3945 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
3946 <source>Misc</source>
3947 <target>æ‚项</target>
3948 <context-group name="null">
3949 <context context-type="linenumber">1</context>
3950 </context-group>
3951 </trans-unit>
3952 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
3953 <source>Ownership changes</source>
3954 <target>视频转移</target>
3955 <context-group name="null">
3956 <context context-type="linenumber">1</context>
3957 </context-group>
3958 </trans-unit>
3959 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
3960 <source>My settings</source>
3961 <target>我的设置</target>
4097 <context-group name="null"> 3962 <context-group name="null">
4098 <context context-type="linenumber">1</context> 3963 <context context-type="linenumber">1</context>
4099 </context-group> 3964 </context-group>
@@ -4219,6 +4084,13 @@ When you will upload a video in this channel, the video support field will be au
4219 <context context-type="linenumber">1</context> 4084 <context context-type="linenumber">1</context>
4220 </context-group> 4085 </context-group>
4221 </trans-unit> 4086 </trans-unit>
4087 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
4088 <source>Error</source>
4089 <target>错误</target>
4090 <context-group name="null">
4091 <context context-type="linenumber">1</context>
4092 </context-group>
4093 </trans-unit>
4222 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 4094 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
4223 <source>You need to reconnect.</source> 4095 <source>You need to reconnect.</source>
4224 <target>请é‡æ–°è¿›è¡ŒæŽˆæƒã€‚</target> 4096 <target>请é‡æ–°è¿›è¡ŒæŽˆæƒã€‚</target>
@@ -4240,6 +4112,20 @@ When you will upload a video in this channel, the video support field will be au
4240 <context context-type="linenumber">1</context> 4112 <context context-type="linenumber">1</context>
4241 </context-group> 4113 </context-group>
4242 </trans-unit> 4114 </trans-unit>
4115 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4116 <source>Info</source>
4117 <target>æ示</target>
4118 <context-group name="null">
4119 <context context-type="linenumber">1</context>
4120 </context-group>
4121 </trans-unit>
4122 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
4123 <source>Success</source>
4124 <target>æˆåŠŸ</target>
4125 <context-group name="null">
4126 <context context-type="linenumber">1</context>
4127 </context-group>
4128 </trans-unit>
4243 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 4129 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
4244 <source>Incorrect username or password.</source> 4130 <source>Incorrect username or password.</source>
4245 <target>用户å或密ç ä¸æ­£ç¡®ã€‚</target> 4131 <target>用户å或密ç ä¸æ­£ç¡®ã€‚</target>
@@ -4457,6 +4343,20 @@ When you will upload a video in this channel, the video support field will be au
4457 <context context-type="linenumber">1</context> 4343 <context context-type="linenumber">1</context>
4458 </context-group> 4344 </context-group>
4459 </trans-unit> 4345 </trans-unit>
4346 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4347 <source>Email is required.</source>
4348 <target>请输入电å­é‚®ä»¶åœ°å€ã€‚</target>
4349 <context-group name="null">
4350 <context context-type="linenumber">1</context>
4351 </context-group>
4352 </trans-unit>
4353 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4354 <source>Email must be valid.</source>
4355 <target>请输入åˆæ³•çš„电å­é‚®ä»¶åœ°å€ã€‚</target>
4356 <context-group name="null">
4357 <context context-type="linenumber">1</context>
4358 </context-group>
4359 </trans-unit>
4460 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 4360 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
4461 <source>Username is required.</source> 4361 <source>Username is required.</source>
4462 <target>请输入用户å。</target> 4362 <target>请输入用户å。</target>
@@ -4478,41 +4378,6 @@ When you will upload a video in this channel, the video support field will be au
4478 <context context-type="linenumber">1</context> 4378 <context context-type="linenumber">1</context>
4479 </context-group> 4379 </context-group>
4480 </trans-unit> 4380 </trans-unit>
4481 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
4482 <source>Username must be at least 3 characters long.</source>
4483 <target>用户å应至少 3 个字符。</target>
4484 <context-group name="null">
4485 <context context-type="linenumber">1</context>
4486 </context-group>
4487 </trans-unit>
4488 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
4489 <source>Username cannot be more than 20 characters long.</source>
4490 <target>用户åä¸èƒ½è¶…过 20 个字符。</target>
4491 <context-group name="null">
4492 <context context-type="linenumber">1</context>
4493 </context-group>
4494 </trans-unit>
4495 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
4496 <source>Username should be only lowercase alphanumeric characters.</source>
4497 <target>用户ååªèƒ½ä½¿ç”¨å°å†™å­—æ¯å’Œæ•°å­—。</target>
4498 <context-group name="null">
4499 <context context-type="linenumber">1</context>
4500 </context-group>
4501 </trans-unit>
4502 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4503 <source>Email is required.</source>
4504 <target>请输入电å­é‚®ä»¶åœ°å€ã€‚</target>
4505 <context-group name="null">
4506 <context context-type="linenumber">1</context>
4507 </context-group>
4508 </trans-unit>
4509 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4510 <source>Email must be valid.</source>
4511 <target>请输入åˆæ³•çš„电å­é‚®ä»¶åœ°å€ã€‚</target>
4512 <context-group name="null">
4513 <context context-type="linenumber">1</context>
4514 </context-group>
4515 </trans-unit>
4516 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 4381 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
4517 <source>Password must be at least 6 characters long.</source> 4382 <source>Password must be at least 6 characters long.</source>
4518 <target>密ç åº”至少 6 个字符。</target> 4383 <target>密ç åº”至少 6 个字符。</target>
@@ -4576,20 +4441,6 @@ When you will upload a video in this channel, the video support field will be au
4576 <context context-type="linenumber">1</context> 4441 <context context-type="linenumber">1</context>
4577 </context-group> 4442 </context-group>
4578 </trans-unit> 4443 </trans-unit>
4579 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
4580 <source>Display name must be at least 3 characters long.</source>
4581 <target>显示å称应至少 3 个字符。</target>
4582 <context-group name="null">
4583 <context context-type="linenumber">1</context>
4584 </context-group>
4585 </trans-unit>
4586 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
4587 <source>Display name cannot be more than 120 characters long.</source>
4588 <target>显示å称ä¸èƒ½è¶…过 120 个字符。</target>
4589 <context-group name="null">
4590 <context context-type="linenumber">1</context>
4591 </context-group>
4592 </trans-unit>
4593 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 4444 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
4594 <source>Description must be at least 3 characters long.</source> 4445 <source>Description must be at least 3 characters long.</source>
4595 <target>说明应至少 3 个字符。</target> 4446 <target>说明应至少 3 个字符。</target>
@@ -4639,13 +4490,6 @@ When you will upload a video in this channel, the video support field will be au
4639 <context context-type="linenumber">1</context> 4490 <context context-type="linenumber">1</context>
4640 </context-group> 4491 </context-group>
4641 </trans-unit> 4492 </trans-unit>
4642 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
4643 <source>Report reason cannot be more than 300 characters long.</source>
4644 <target>举报ç†ç”±ä¸èƒ½è¶…过 300 个字符。</target>
4645 <context-group name="null">
4646 <context context-type="linenumber">1</context>
4647 </context-group>
4648 </trans-unit>
4649 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118"> 4493 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
4650 <source>Moderation comment is required.</source> 4494 <source>Moderation comment is required.</source>
4651 <target>请输入è¿è¥å¤‡æ³¨ä¿¡æ¯ã€‚</target> 4495 <target>请输入è¿è¥å¤‡æ³¨ä¿¡æ¯ã€‚</target>
@@ -4660,13 +4504,6 @@ When you will upload a video in this channel, the video support field will be au
4660 <context context-type="linenumber">1</context> 4504 <context context-type="linenumber">1</context>
4661 </context-group> 4505 </context-group>
4662 </trans-unit> 4506 </trans-unit>
4663 <trans-unit id="89d0b662dde0871cf17244e79b2cb62cd517e44f">
4664 <source>Moderation comment cannot be more than 300 characters long.</source>
4665 <target>è¿è¥å¤‡æ³¨ä¿¡æ¯ä¸èƒ½è¶…过 300 个字符。</target>
4666 <context-group name="null">
4667 <context context-type="linenumber">1</context>
4668 </context-group>
4669 </trans-unit>
4670 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6"> 4507 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
4671 <source>The channel is required.</source> 4508 <source>The channel is required.</source>
4672 <target>必须指定频é“。</target> 4509 <target>必须指定频é“。</target>
@@ -4723,27 +4560,6 @@ When you will upload a video in this channel, the video support field will be au
4723 <context context-type="linenumber">1</context> 4560 <context context-type="linenumber">1</context>
4724 </context-group> 4561 </context-group>
4725 </trans-unit> 4562 </trans-unit>
4726 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069">
4727 <source>Name must be at least 3 characters long.</source>
4728 <target>频é“用户å应至少 3 个字符。</target>
4729 <context-group name="null">
4730 <context context-type="linenumber">1</context>
4731 </context-group>
4732 </trans-unit>
4733 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482">
4734 <source>Name cannot be more than 20 characters long.</source>
4735 <target>频é“用户åä¸èƒ½è¶…过 20 个字符。</target>
4736 <context-group name="null">
4737 <context context-type="linenumber">1</context>
4738 </context-group>
4739 </trans-unit>
4740 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9">
4741 <source>Name should be only lowercase alphanumeric characters.</source>
4742 <target>频é“用户ååªèƒ½ä½¿ç”¨å°å†™å­—æ¯å’Œæ•°å­—。</target>
4743 <context-group name="null">
4744 <context context-type="linenumber">1</context>
4745 </context-group>
4746 </trans-unit>
4747 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 4563 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
4748 <source>Support text must be at least 3 characters long.</source> 4564 <source>Support text must be at least 3 characters long.</source>
4749 <target>支æŒä¿¡æ¯åº”至少 3 个字符。</target> 4565 <target>支æŒä¿¡æ¯åº”至少 3 个字符。</target>
@@ -5549,13 +5365,6 @@ When you will upload a video in this channel, the video support field will be au
5549 <context context-type="linenumber">1</context> 5365 <context context-type="linenumber">1</context>
5550 </context-group> 5366 </context-group>
5551 </trans-unit> 5367 </trans-unit>
5552 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5553 <source>Subscribed</source>
5554 <target>已订阅</target>
5555 <context-group name="null">
5556 <context context-type="linenumber">1</context>
5557 </context-group>
5558 </trans-unit>
5559 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded"> 5368 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
5560 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source> 5369 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
5561 <target>æˆåŠŸè®¢é˜… <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target> 5370 <target>æˆåŠŸè®¢é˜… <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
@@ -5563,9 +5372,9 @@ When you will upload a video in this channel, the video support field will be au
5563 <context context-type="linenumber">1</context> 5372 <context context-type="linenumber">1</context>
5564 </context-group> 5373 </context-group>
5565 </trans-unit> 5374 </trans-unit>
5566 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471"> 5375 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5567 <source>Unsubscribed</source> 5376 <source>Subscribed</source>
5568 <target>已退订</target> 5377 <target>已订阅</target>
5569 <context-group name="null"> 5378 <context-group name="null">
5570 <context context-type="linenumber">1</context> 5379 <context context-type="linenumber">1</context>
5571 </context-group> 5380 </context-group>
@@ -5577,6 +5386,13 @@ When you will upload a video in this channel, the video support field will be au
5577 <context context-type="linenumber">1</context> 5386 <context context-type="linenumber">1</context>
5578 </context-group> 5387 </context-group>
5579 </trans-unit> 5388 </trans-unit>
5389 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
5390 <source>Unsubscribed</source>
5391 <target>已退订</target>
5392 <context-group name="null">
5393 <context context-type="linenumber">1</context>
5394 </context-group>
5395 </trans-unit>
5580 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf"> 5396 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf">
5581 <source>Moderator</source> 5397 <source>Moderator</source>
5582 <target>监察员</target> 5398 <target>监察员</target>
@@ -5633,13 +5449,6 @@ When you will upload a video in this channel, the video support field will be au
5633 <context context-type="linenumber">1</context> 5449 <context context-type="linenumber">1</context>
5634 </context-group> 5450 </context-group>
5635 </trans-unit> 5451 </trans-unit>
5636 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
5637 <source>Info</source>
5638 <target>æ示</target>
5639 <context-group name="null">
5640 <context context-type="linenumber">1</context>
5641 </context-group>
5642 </trans-unit>
5643 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 5452 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
5644 <source>Upload cancelled</source> 5453 <source>Upload cancelled</source>
5645 <target>上传已å–消</target> 5454 <target>上传已å–消</target>
@@ -5647,13 +5456,6 @@ When you will upload a video in this channel, the video support field will be au
5647 <context context-type="linenumber">1</context> 5456 <context context-type="linenumber">1</context>
5648 </context-group> 5457 </context-group>
5649 </trans-unit> 5458 </trans-unit>
5650 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa">
5651 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
5652 <target>éžå¸¸æŠ±æ­‰ï¼ŒPeerTube ä¸æ”¯æŒ 8GB 以上的视频</target>
5653 <context-group name="null">
5654 <context context-type="linenumber">1</context>
5655 </context-group>
5656 </trans-unit>
5657 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee"> 5459 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
5658 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source> 5460 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
5659 <target>此视频已超出您的视频存储总空间(视频大å°ï¼š<x id="INTERPOLATION" equiv-text="{{videoSize}}"/>,当å‰å·²ä½¿ç”¨ï¼š<x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>,总空间:<x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target> 5461 <target>此视频已超出您的视频存储总空间(视频大å°ï¼š<x id="INTERPOLATION" equiv-text="{{videoSize}}"/>,当å‰å·²ä½¿ç”¨ï¼š<x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>,总空间:<x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
diff --git a/client/src/locale/target/angular_zh_Hant_TW.xml b/client/src/locale/target/angular_zh_Hant_TW.xml
index 4779d9cc8..c1aefbb40 100644
--- a/client/src/locale/target/angular_zh_Hant_TW.xml
+++ b/client/src/locale/target/angular_zh_Hant_TW.xml
@@ -497,7 +497,7 @@
497 <source>Password</source> 497 <source>Password</source>
498 <target>密碼</target> 498 <target>密碼</target>
499 <context-group name="null"> 499 <context-group name="null">
500 <context context-type="linenumber">12</context> 500 <context context-type="linenumber">13</context>
501 </context-group> 501 </context-group>
502 </trans-unit> 502 </trans-unit>
503 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda"> 503 <trans-unit id="b87e81682959464211443afc3e23c506865d2eda">
@@ -511,7 +511,7 @@
511 <source>Login</source> 511 <source>Login</source>
512 <target>登入</target> 512 <target>登入</target>
513 <context-group name="null"> 513 <context-group name="null">
514 <context context-type="linenumber">38</context> 514 <context context-type="linenumber">36</context>
515 </context-group> 515 </context-group>
516 </trans-unit> 516 </trans-unit>
517 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681"> 517 <trans-unit id="d2eb6c5d41f70d4b8c0937e7e19e196143b47681">
@@ -539,7 +539,7 @@
539 <source>Send me an email to reset my password</source> 539 <source>Send me an email to reset my password</source>
540 <target>傳é€é›»å­éƒµä»¶çµ¦æˆ‘以é‡è¨­æˆ‘的密碼</target> 540 <target>傳é€é›»å­éƒµä»¶çµ¦æˆ‘以é‡è¨­æˆ‘的密碼</target>
541 <context-group name="null"> 541 <context-group name="null">
542 <context context-type="linenumber">75</context> 542 <context context-type="linenumber">80</context>
543 </context-group> 543 </context-group>
544 </trans-unit> 544 </trans-unit>
545 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa"> 545 <trans-unit id="2ba14c37f3b23553b2602c5e535d0ff4916f24aa">
@@ -606,7 +606,7 @@
606 <source>Signup</source> 606 <source>Signup</source>
607 <target>註冊</target> 607 <target>註冊</target>
608 <context-group name="null"> 608 <context-group name="null">
609 <context context-type="linenumber">88</context> 609 <context context-type="linenumber">78</context>
610 </context-group> 610 </context-group>
611 </trans-unit> 611 </trans-unit>
612 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1"> 612 <trans-unit id="fa48c3ddc2ef8e40e5c317e68bc05ae62c93b0c1">
@@ -674,7 +674,7 @@
674 <source>Change the language</source> 674 <source>Change the language</source>
675 <target>變更語言</target> 675 <target>變更語言</target>
676 <context-group name="null"> 676 <context-group name="null">
677 <context context-type="linenumber">88</context> 677 <context context-type="linenumber">86</context>
678 </context-group> 678 </context-group>
679 </trans-unit> 679 </trans-unit>
680 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6"> 680 <trans-unit id="8c654f49714163eb2991b264e9fd4858e72c04c6">
@@ -685,7 +685,7 @@
685 我的公開個人資料 685 我的公開個人資料
686 </target> 686 </target>
687 <context-group name="null"> 687 <context-group name="null">
688 <context context-type="linenumber">18</context> 688 <context context-type="linenumber">16</context>
689 </context-group> 689 </context-group>
690 </trans-unit> 690 </trans-unit>
691 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb"> 691 <trans-unit id="01d7a5f4ca6470b564031481bc16485b53a8d4fb">
@@ -696,7 +696,7 @@
696 我的帳號 696 我的帳號
697 </target> 697 </target>
698 <context-group name="null"> 698 <context-group name="null">
699 <context context-type="linenumber">22</context> 699 <context context-type="linenumber">20</context>
700 </context-group> 700 </context-group>
701 </trans-unit> 701 </trans-unit>
702 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10"> 702 <trans-unit id="fa9f3da5641dbd73d83395a0bde61bb6d5cefb10">
@@ -707,7 +707,7 @@
707 我的影片 707 我的影片
708 </target> 708 </target>
709 <context-group name="null"> 709 <context-group name="null">
710 <context context-type="linenumber">26</context> 710 <context context-type="linenumber">24</context>
711 </context-group> 711 </context-group>
712 </trans-unit> 712 </trans-unit>
713 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1"> 713 <trans-unit id="b795a1acb4a57ee68e6c5114daa280bf6e0f70e1">
@@ -718,14 +718,14 @@
718 登出 718 登出
719 </target> 719 </target>
720 <context-group name="null"> 720 <context-group name="null">
721 <context context-type="linenumber">30</context> 721 <context context-type="linenumber">28</context>
722 </context-group> 722 </context-group>
723 </trans-unit> 723 </trans-unit>
724 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87"> 724 <trans-unit id="d207cc1965ec0c29e594e0e9917f39bfc276ed87">
725 <source>Create an account</source> 725 <source>Create an account</source>
726 <target>建立帳號</target> 726 <target>建立帳號</target>
727 <context-group name="null"> 727 <context-group name="null">
728 <context context-type="linenumber">39</context> 728 <context context-type="linenumber">37</context>
729 </context-group> 729 </context-group>
730 </trans-unit> 730 </trans-unit>
731 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238"> 731 <trans-unit id="a52dae09be10ca3a65da918533ced3d3f4992238">
@@ -739,49 +739,49 @@
739 <source>Subscriptions</source> 739 <source>Subscriptions</source>
740 <target>訂閱</target> 740 <target>訂閱</target>
741 <context-group name="null"> 741 <context-group name="null">
742 <context context-type="linenumber">47</context> 742 <context context-type="linenumber">45</context>
743 </context-group> 743 </context-group>
744 </trans-unit> 744 </trans-unit>
745 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5"> 745 <trans-unit id="e95ae009d0bdb45fcc656e8b65248cf7396080d5">
746 <source>Overview</source> 746 <source>Overview</source>
747 <target>概覽</target> 747 <target>概覽</target>
748 <context-group name="null"> 748 <context-group name="null">
749 <context context-type="linenumber">52</context> 749 <context context-type="linenumber">50</context>
750 </context-group> 750 </context-group>
751 </trans-unit> 751 </trans-unit>
752 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807"> 752 <trans-unit id="b6b7986bc3721ac483baf20bc9a320529075c807">
753 <source>Trending</source> 753 <source>Trending</source>
754 <target>趨勢</target> 754 <target>趨勢</target>
755 <context-group name="null"> 755 <context-group name="null">
756 <context context-type="linenumber">57</context> 756 <context context-type="linenumber">55</context>
757 </context-group> 757 </context-group>
758 </trans-unit> 758 </trans-unit>
759 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1"> 759 <trans-unit id="8d20c5f5dd30acbe71316544dab774393fd9c3c1">
760 <source>Recently added</source> 760 <source>Recently added</source>
761 <target>最近新增</target> 761 <target>最近新增</target>
762 <context-group name="null"> 762 <context-group name="null">
763 <context context-type="linenumber">62</context> 763 <context context-type="linenumber">60</context>
764 </context-group> 764 </context-group>
765 </trans-unit> 765 </trans-unit>
766 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d"> 766 <trans-unit id="eadc17c3df80143992e2d9028dead3199ae6d79d">
767 <source>Local</source> 767 <source>Local</source>
768 <target>本地</target> 768 <target>本地</target>
769 <context-group name="null"> 769 <context-group name="null">
770 <context context-type="linenumber">67</context> 770 <context context-type="linenumber">65</context>
771 </context-group> 771 </context-group>
772 </trans-unit> 772 </trans-unit>
773 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f"> 773 <trans-unit id="ac0f81713a84217c9bd1d9bb460245d8190b073f">
774 <source>More</source> 774 <source>More</source>
775 <target>更多</target> 775 <target>更多</target>
776 <context-group name="null"> 776 <context-group name="null">
777 <context context-type="linenumber">72</context> 777 <context context-type="linenumber">70</context>
778 </context-group> 778 </context-group>
779 </trans-unit> 779 </trans-unit>
780 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919"> 780 <trans-unit id="b7648e7aced164498aa843b5c4e8f2f1c36a7919">
781 <source>Administration</source> 781 <source>Administration</source>
782 <target>管ç†</target> 782 <target>管ç†</target>
783 <context-group name="null"> 783 <context-group name="null">
784 <context context-type="linenumber">76</context> 784 <context context-type="linenumber">74</context>
785 </context-group> 785 </context-group>
786 </trans-unit> 786 </trans-unit>
787 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a"> 787 <trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a">
@@ -795,14 +795,14 @@
795 <source>Show keyboard shortcuts</source> 795 <source>Show keyboard shortcuts</source>
796 <target>顯示éµç›¤å¿«æ·éµ</target> 796 <target>顯示éµç›¤å¿«æ·éµ</target>
797 <context-group name="null"> 797 <context-group name="null">
798 <context context-type="linenumber">91</context> 798 <context context-type="linenumber">89</context>
799 </context-group> 799 </context-group>
800 </trans-unit> 800 </trans-unit>
801 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768"> 801 <trans-unit id="cf75021ac8cb9efd4f95e8880cf52c9acd265768">
802 <source>Toggle dark interface</source> 802 <source>Toggle dark interface</source>
803 <target>切æ›è‡³æš—色介é¢</target> 803 <target>切æ›è‡³æš—色介é¢</target>
804 <context-group name="null"> 804 <context-group name="null">
805 <context context-type="linenumber">94</context> 805 <context context-type="linenumber">92</context>
806 </context-group> 806 </context-group>
807 </trans-unit> 807 </trans-unit>
808 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599"> 808 <trans-unit id="8aa58cf00d949c509df91c621ab38131df0a7599">
@@ -907,14 +907,14 @@
907 <source>Display unlisted and private videos</source> 907 <source>Display unlisted and private videos</source>
908 <target>顯示未列出與ç§å¯†å½±ç‰‡</target> 908 <target>顯示未列出與ç§å¯†å½±ç‰‡</target>
909 <context-group name="null"> 909 <context-group name="null">
910 <context context-type="linenumber">11</context> 910 <context context-type="linenumber">14</context>
911 </context-group> 911 </context-group>
912 </trans-unit> 912 </trans-unit>
913 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e"> 913 <trans-unit id="c31161d1661884f54fbc5635aad5ce8d4803897e">
914 <source>No results.</source> 914 <source>No results.</source>
915 <target>沒有çµæžœ</target> 915 <target>沒有çµæžœ</target>
916 <context-group name="null"> 916 <context-group name="null">
917 <context context-type="linenumber">17</context> 917 <context context-type="linenumber">20</context>
918 </context-group> 918 </context-group>
919 </trans-unit> 919 </trans-unit>
920 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6"> 920 <trans-unit id="2290d09f4f113351baa9152ca8ad14cd03a11ba6">
@@ -972,13 +972,22 @@
972 <context context-type="linenumber">7</context> 972 <context context-type="linenumber">7</context>
973 </context-group> 973 </context-group>
974 </trans-unit> 974 </trans-unit>
975 <trans-unit id="5849c589454817c1e991639d3091d8da0e8d6bd2"> 975 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
976 <source> 976 <source>
977 About <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> instance 977 Cancel
978</source> 978 </source>
979 <target>關於 <x id="INTERPOLATION" equiv-text="{{ instanceName }}"/> 實體</target> 979 <target>
980 å–消
981 </target>
980 <context-group name="null"> 982 <context-group name="null">
981 <context context-type="linenumber">1</context> 983 <context context-type="linenumber">26</context>
984 </context-group>
985 </trans-unit>
986 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
987 <source>Submit</source>
988 <target>éžäº¤</target>
989 <context-group name="null">
990 <context context-type="linenumber">31</context>
982 </context-group> 991 </context-group>
983 </trans-unit> 992 </trans-unit>
984 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0"> 993 <trans-unit id="eec715de352a6b114713b30b640d319fa78207a0">
@@ -992,41 +1001,14 @@
992 <source>Terms</source> 1001 <source>Terms</source>
993 <target>æ¢æ¬¾</target> 1002 <target>æ¢æ¬¾</target>
994 <context-group name="null"> 1003 <context-group name="null">
995 <context context-type="linenumber">44</context> 1004 <context context-type="linenumber">39</context>
996 </context-group> 1005 </context-group>
997 </trans-unit> 1006 </trans-unit>
998 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27"> 1007 <trans-unit id="9c6e6db693ab265457c6578df179c65694141d27">
999 <source>User registration is allowed and</source> 1008 <source>User registration is allowed and</source>
1000 <target>å…許使用者註冊與</target> 1009 <target>å…許使用者註冊與</target>
1001 <context-group name="null"> 1010 <context-group name="null">
1002 <context context-type="linenumber">25</context> 1011 <context context-type="linenumber">29</context>
1003 </context-group>
1004 </trans-unit>
1005 <trans-unit id="ac324b07e7c3c972f1c33894eda02dc2917eda5e">
1006 <source>
1007 this instance provides a baseline quota of <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> space for the videos of its users.
1008 </source>
1009 <target>此實體æ供了基本é…é¡ <x id="INTERPOLATION" equiv-text="{{ userVideoQuota | bytes: 0 }}"/> 空間給它的使用者的影片。</target>
1010 <context-group name="null">
1011 <context context-type="linenumber">27</context>
1012 </context-group>
1013 </trans-unit>
1014 <trans-unit id="a6865ec6abf6af58f808501d84c8ed6ff8ce46ae">
1015 <source>
1016 this instance provides unlimited space for the videos of its users.
1017 </source>
1018 <target>此實體æ供了無é™çš„影片空間給它的使用者。</target>
1019 <context-group name="null">
1020 <context context-type="linenumber">31</context>
1021 </context-group>
1022 </trans-unit>
1023 <trans-unit id="5c856a6a233b6f6c4cc8eed46436d31d2da63fc1">
1024 <source>
1025 User registration is currently not allowed.
1026 </source>
1027 <target>ç›®å‰ä¸å…許使用者註冊。</target>
1028 <context-group name="null">
1029 <context context-type="linenumber">36</context>
1030 </context-group> 1012 </context-group>
1031 </trans-unit> 1013 </trans-unit>
1032 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc"> 1014 <trans-unit id="a11e3ba2c5aea841de67a3c85892bb61295e94dc">
@@ -1353,49 +1335,49 @@
1353 <source>Short description</source> 1335 <source>Short description</source>
1354 <target>短æè¿°</target> 1336 <target>短æè¿°</target>
1355 <context-group name="null"> 1337 <context-group name="null">
1356 <context context-type="linenumber">22</context> 1338 <context context-type="linenumber">21</context>
1357 </context-group> 1339 </context-group>
1358 </trans-unit> 1340 </trans-unit>
1359 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003"> 1341 <trans-unit id="554488d11165f38b27b8fe230aba8a2e30d57003">
1360 <source>Default client route</source> 1342 <source>Default client route</source>
1361 <target>é è¨­å®¢æˆ¶ç«¯è·¯ç”±</target> 1343 <target>é è¨­å®¢æˆ¶ç«¯è·¯ç”±</target>
1362 <context-group name="null"> 1344 <context-group name="null">
1363 <context context-type="linenumber">55</context> 1345 <context context-type="linenumber">48</context>
1364 </context-group> 1346 </context-group>
1365 </trans-unit> 1347 </trans-unit>
1366 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d"> 1348 <trans-unit id="3fae5a310387c065757fde11f22689b45a7b6f2d">
1367 <source>Videos Overview</source> 1349 <source>Videos Overview</source>
1368 <target>影片概覽</target> 1350 <target>影片概覽</target>
1369 <context-group name="null"> 1351 <context-group name="null">
1370 <context context-type="linenumber">58</context> 1352 <context context-type="linenumber">51</context>
1371 </context-group> 1353 </context-group>
1372 </trans-unit> 1354 </trans-unit>
1373 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948"> 1355 <trans-unit id="1cbeb1eb589bfbe5efce94184cacd3095ca26948">
1374 <source>Videos Trending</source> 1356 <source>Videos Trending</source>
1375 <target>影片趨勢</target> 1357 <target>影片趨勢</target>
1376 <context-group name="null"> 1358 <context-group name="null">
1377 <context context-type="linenumber">59</context> 1359 <context context-type="linenumber">52</context>
1378 </context-group> 1360 </context-group>
1379 </trans-unit> 1361 </trans-unit>
1380 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883"> 1362 <trans-unit id="1861c96217213992e02dcb77e15ea69e718c9883">
1381 <source>Videos Recently Added</source> 1363 <source>Videos Recently Added</source>
1382 <target>最近新增的影片</target> 1364 <target>最近新增的影片</target>
1383 <context-group name="null"> 1365 <context-group name="null">
1384 <context context-type="linenumber">60</context> 1366 <context context-type="linenumber">53</context>
1385 </context-group> 1367 </context-group>
1386 </trans-unit> 1368 </trans-unit>
1387 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f"> 1369 <trans-unit id="b6307f83d9f43bff8d5129a7888e89964ddc3f7f">
1388 <source>Local videos</source> 1370 <source>Local videos</source>
1389 <target>本地影片</target> 1371 <target>本地影片</target>
1390 <context-group name="null"> 1372 <context-group name="null">
1391 <context context-type="linenumber">61</context> 1373 <context context-type="linenumber">54</context>
1392 </context-group> 1374 </context-group>
1393 </trans-unit> 1375 </trans-unit>
1394 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9"> 1376 <trans-unit id="8551afadb69b3fef89e191f507e8ac84e624e8b9">
1395 <source>Policy on videos containing sensitive content</source> 1377 <source>Policy on videos containing sensitive content</source>
1396 <target>包å«æ•æ„Ÿå…§å®¹çš„影片政策</target> 1378 <target>包å«æ•æ„Ÿå…§å®¹çš„影片政策</target>
1397 <context-group name="null"> 1379 <context-group name="null">
1398 <context context-type="linenumber">70</context> 1380 <context context-type="linenumber">61</context>
1399 </context-group> 1381 </context-group>
1400 </trans-unit> 1382 </trans-unit>
1401 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df"> 1383 <trans-unit id="aa3ef567a1ea22c1e4d0acfdc8f80bc636bf12df">
@@ -1430,23 +1412,44 @@
1430 <source>Signup enabled</source> 1412 <source>Signup enabled</source>
1431 <target>已啟用註冊</target> 1413 <target>已啟用註冊</target>
1432 <context-group name="null"> 1414 <context-group name="null">
1433 <context context-type="linenumber">93</context> 1415 <context context-type="linenumber">84</context>
1434 </context-group> 1416 </context-group>
1435 </trans-unit> 1417 </trans-unit>
1436 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7"> 1418 <trans-unit id="90f449b1f4787e6c9731198a96d35399c1b340a7">
1437 <source>Signup requires email verification</source> 1419 <source>Signup requires email verification</source>
1438 <target>註冊需è¦é›»å­éƒµä»¶é©—è­‰</target> 1420 <target>註冊需è¦é›»å­éƒµä»¶é©—è­‰</target>
1439 <context-group name="null"> 1421 <context-group name="null">
1440 <context context-type="linenumber">100</context> 1422 <context context-type="linenumber">91</context>
1441 </context-group> 1423 </context-group>
1442 </trans-unit> 1424 </trans-unit>
1443 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402"> 1425 <trans-unit id="68bda70e0dd4f7f91549462e55f1b2a1602d8402">
1444 <source>Signup limit</source> 1426 <source>Signup limit</source>
1445 <target>é™åˆ¶è¨»å†Š</target> 1427 <target>é™åˆ¶è¨»å†Š</target>
1446 <context-group name="null"> 1428 <context-group name="null">
1429 <context context-type="linenumber">96</context>
1430 </context-group>
1431 </trans-unit>
1432 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1433 <source>Users</source>
1434 <target>使用者</target>
1435 <context-group name="null">
1447 <context context-type="linenumber">105</context> 1436 <context context-type="linenumber">105</context>
1448 </context-group> 1437 </context-group>
1449 </trans-unit> 1438 </trans-unit>
1439 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1440 <source>User default video quota</source>
1441 <target>使用者é è¨­å½±ç‰‡é…é¡</target>
1442 <context-group name="null">
1443 <context context-type="linenumber">109</context>
1444 </context-group>
1445 </trans-unit>
1446 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1447 <source>User default daily upload limit</source>
1448 <target>é è¨­ä½¿ç”¨è€…æ¯æ—¥ä¸Šå‚³é™åˆ¶</target>
1449 <context-group name="null">
1450 <context context-type="linenumber">121</context>
1451 </context-group>
1452 </trans-unit>
1450 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36"> 1453 <trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36">
1451 <source>Import</source> 1454 <source>Import</source>
1452 <target>匯入</target> 1455 <target>匯入</target>
@@ -1458,49 +1461,28 @@
1458 <source>Video import with HTTP URL (i.e. YouTube) enabled</source> 1461 <source>Video import with HTTP URL (i.e. YouTube) enabled</source>
1459 <target>以 HTTP URL 匯入影片(如 YouTube)已啟用</target> 1462 <target>以 HTTP URL 匯入影片(如 YouTube)已啟用</target>
1460 <context-group name="null"> 1463 <context-group name="null">
1461 <context context-type="linenumber">120</context> 1464 <context context-type="linenumber">141</context>
1462 </context-group> 1465 </context-group>
1463 </trans-unit> 1466 </trans-unit>
1464 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e"> 1467 <trans-unit id="05fdf7b5be1c3a7126e3c06d81da3134981b0a9e">
1465 <source>Video import with a torrent file or a magnet URI enabled</source> 1468 <source>Video import with a torrent file or a magnet URI enabled</source>
1466 <target>已啟用種å­æª”案或ç£åŠ›é€£çµåŒ¯å…¥å½±ç‰‡</target> 1469 <target>已啟用種å­æª”案或ç£åŠ›é€£çµåŒ¯å…¥å½±ç‰‡</target>
1467 <context-group name="null"> 1470 <context-group name="null">
1468 <context context-type="linenumber">127</context> 1471 <context context-type="linenumber">148</context>
1469 </context-group> 1472 </context-group>
1470 </trans-unit> 1473 </trans-unit>
1471 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011"> 1474 <trans-unit id="ca2283fc765b9f44b69f0175d685dc2443da6011">
1472 <source>Administrator</source> 1475 <source>Administrator</source>
1473 <target>管ç†å“¡</target> 1476 <target>管ç†å“¡</target>
1474 <context-group name="null"> 1477 <context-group name="null">
1475 <context context-type="linenumber">131</context> 1478 <context context-type="linenumber">155</context>
1476 </context-group> 1479 </context-group>
1477 </trans-unit> 1480 </trans-unit>
1478 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587"> 1481 <trans-unit id="55a0f51e38679d3141841e8333da5779d349c587">
1479 <source>Admin email</source> 1482 <source>Admin email</source>
1480 <target>管ç†é›»å­éƒµä»¶</target> 1483 <target>管ç†é›»å­éƒµä»¶</target>
1481 <context-group name="null"> 1484 <context-group name="null">
1482 <context context-type="linenumber">134</context> 1485 <context context-type="linenumber">158</context>
1483 </context-group>
1484 </trans-unit>
1485 <trans-unit id="4d13a9cd5ed3dcee0eab22cb25198d43886942be">
1486 <source>Users</source>
1487 <target>使用者</target>
1488 <context-group name="null">
1489 <context context-type="linenumber">144</context>
1490 </context-group>
1491 </trans-unit>
1492 <trans-unit id="31b3275d999af45fe64c6824e6e017d2e2704f09">
1493 <source>User default video quota</source>
1494 <target>使用者é è¨­å½±ç‰‡é…é¡</target>
1495 <context-group name="null">
1496 <context context-type="linenumber">147</context>
1497 </context-group>
1498 </trans-unit>
1499 <trans-unit id="f5528147716c4d3286c89defbe63ee0b75da5ffe">
1500 <source>User default daily upload limit</source>
1501 <target>é è¨­ä½¿ç”¨è€…æ¯æ—¥ä¸Šå‚³é™åˆ¶</target>
1502 <context-group name="null">
1503 <context context-type="linenumber">161</context>
1504 </context-group> 1486 </context-group>
1505 </trans-unit> 1487 </trans-unit>
1506 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5"> 1488 <trans-unit id="50247a2f9711ea9e9a85aacc46668131e9b424a5">
@@ -1521,21 +1503,21 @@
1521 <source>Your Twitter username</source> 1503 <source>Your Twitter username</source>
1522 <target>您的 Twitter 使用者å稱</target> 1504 <target>您的 Twitter 使用者å稱</target>
1523 <context-group name="null"> 1505 <context-group name="null">
1524 <context context-type="linenumber">181</context> 1506 <context context-type="linenumber">184</context>
1525 </context-group> 1507 </context-group>
1526 </trans-unit> 1508 </trans-unit>
1527 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c"> 1509 <trans-unit id="6e671e839ca889feef0d8ed525d1a44b4b10870c">
1528 <source>Indicates the Twitter account for the website or platform on which the content was published.</source> 1510 <source>Indicates the Twitter account for the website or platform on which the content was published.</source>
1529 <target>指示發佈影片的網é æˆ–平臺的 Twitter 帳號</target> 1511 <target>指示發佈影片的網é æˆ–平臺的 Twitter 帳號</target>
1530 <context-group name="null"> 1512 <context-group name="null">
1531 <context context-type="linenumber">184</context> 1513 <context context-type="linenumber">187</context>
1532 </context-group> 1514 </context-group>
1533 </trans-unit> 1515 </trans-unit>
1534 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605"> 1516 <trans-unit id="c0716c28b9d4c9e0b2fd6031334394214e5f9605">
1535 <source>Instance whitelisted by Twitter</source> 1517 <source>Instance whitelisted by Twitter</source>
1536 <target>ç”± Twitter 列入白å單的實體</target> 1518 <target>ç”± Twitter 列入白å單的實體</target>
1537 <context-group name="null"> 1519 <context-group name="null">
1538 <context context-type="linenumber">198</context> 1520 <context context-type="linenumber">199</context>
1539 </context-group> 1521 </context-group>
1540 </trans-unit> 1522 </trans-unit>
1541 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5"> 1523 <trans-unit id="419d940613972cc3fae9c8ea0a4306dbf80616e5">
@@ -1549,35 +1531,35 @@
1549 <source>Transcoding</source> 1531 <source>Transcoding</source>
1550 <target>轉æ›ç·¨ç¢¼</target> 1532 <target>轉æ›ç·¨ç¢¼</target>
1551 <context-group name="null"> 1533 <context-group name="null">
1552 <context context-type="linenumber">210</context> 1534 <context context-type="linenumber">215</context>
1553 </context-group> 1535 </context-group>
1554 </trans-unit> 1536 </trans-unit>
1555 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9"> 1537 <trans-unit id="fca29003c4ea1226ff8cbee89481758aab0e2be9">
1556 <source>Transcoding enabled</source> 1538 <source>Transcoding enabled</source>
1557 <target>轉æ›ç·¨ç¢¼å·²å•Ÿç”¨</target> 1539 <target>轉æ›ç·¨ç¢¼å·²å•Ÿç”¨</target>
1558 <context-group name="null"> 1540 <context-group name="null">
1559 <context context-type="linenumber">215</context> 1541 <context context-type="linenumber">221</context>
1560 </context-group> 1542 </context-group>
1561 </trans-unit> 1543 </trans-unit>
1562 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f"> 1544 <trans-unit id="6ef2ab819d4441fa8bddf6759b6936783d06616f">
1563 <source>If you disable transcoding, many videos from your users will not work!</source> 1545 <source>If you disable transcoding, many videos from your users will not work!</source>
1564 <target>若您åœç”¨è½‰æ›ç·¨ç¢¼ï¼Œå¾žæ‚¨çš„使用者們而來的許多影片將會無法é‹ä½œï¼</target> 1546 <target>若您åœç”¨è½‰æ›ç·¨ç¢¼ï¼Œå¾žæ‚¨çš„使用者們而來的許多影片將會無法é‹ä½œï¼</target>
1565 <context-group name="null"> 1547 <context-group name="null">
1566 <context context-type="linenumber">216</context> 1548 <context context-type="linenumber">222</context>
1567 </context-group> 1549 </context-group>
1568 </trans-unit> 1550 </trans-unit>
1569 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2"> 1551 <trans-unit id="a33feadefbb776217c2db96100736314f8b765c2">
1570 <source>Transcoding threads</source> 1552 <source>Transcoding threads</source>
1571 <target>轉æ›ç·¨ç¢¼åŸ·è¡Œç·’</target> 1553 <target>轉æ›ç·¨ç¢¼åŸ·è¡Œç·’</target>
1572 <context-group name="null"> 1554 <context-group name="null">
1573 <context context-type="linenumber">223</context> 1555 <context context-type="linenumber">237</context>
1574 </context-group> 1556 </context-group>
1575 </trans-unit> 1557 </trans-unit>
1576 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500"> 1558 <trans-unit id="5afc7e831e59c325e8fb3e208ec108ff53fb3500">
1577 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source> 1559 <source>Resolution <x id="INTERPOLATION" equiv-text="{{resolution}}"/> enabled</source>
1578 <target>解æžåº¦ <x id="INTERPOLATION" equiv-text="{{resolution}}"/> 已啟用</target> 1560 <target>解æžåº¦ <x id="INTERPOLATION" equiv-text="{{resolution}}"/> 已啟用</target>
1579 <context-group name="null"> 1561 <context-group name="null">
1580 <context context-type="linenumber">239</context> 1562 <context context-type="linenumber">252</context>
1581 </context-group> 1563 </context-group>
1582 </trans-unit> 1564 </trans-unit>
1583 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5"> 1565 <trans-unit id="e9fb2d7685ae280026fe6463731170b067e419d5">
@@ -1592,83 +1574,48 @@
1592 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/> 1574 <x id="START_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;my-help&gt;"/><x id="CLOSE_TAG_MY-HELP" ctype="x-my-help" equiv-text="&lt;/my-help&gt;"/>
1593 </target> 1575 </target>
1594 <context-group name="null"> 1576 <context-group name="null">
1595 <context context-type="linenumber">244</context> 1577 <context context-type="linenumber">260</context>
1596 </context-group> 1578 </context-group>
1597 </trans-unit> 1579 </trans-unit>
1598 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0"> 1580 <trans-unit id="d5bf7bea37daff4e018fd11a1b552512e5cb54c0">
1599 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source> 1581 <source>Some files are not federated (previews, captions). We fetch them directly from the origin instance and cache them.</source>
1600 <target>有一些檔案並未è¯ç›ŸåŒ–(é è¦½ã€å­—幕)。我們會直接從原始實體擷å–它們並快å–。</target> 1582 <target>有一些檔案並未è¯ç›ŸåŒ–(é è¦½ã€å­—幕)。我們會直接從原始實體擷å–它們並快å–。</target>
1601 <context-group name="null"> 1583 <context-group name="null">
1602 <context context-type="linenumber">249</context> 1584 <context context-type="linenumber">265</context>
1603 </context-group> 1585 </context-group>
1604 </trans-unit> 1586 </trans-unit>
1605 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7"> 1587 <trans-unit id="d00f6c2dcb426440a0a8cd8eec12d094fbfaf6f7">
1606 <source>Previews cache size</source> 1588 <source>Previews cache size</source>
1607 <target>é è¦½å¿«å–大å°</target> 1589 <target>é è¦½å¿«å–大å°</target>
1608 <context-group name="null"> 1590 <context-group name="null">
1609 <context context-type="linenumber">254</context> 1591 <context context-type="linenumber">271</context>
1610 </context-group> 1592 </context-group>
1611 </trans-unit> 1593 </trans-unit>
1612 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607"> 1594 <trans-unit id="98970cd72e776308a37dc4e84bebbedffc787607">
1613 <source>Video captions cache size</source> 1595 <source>Video captions cache size</source>
1614 <target>影片字幕快å–大å°</target> 1596 <target>影片字幕快å–大å°</target>
1615 <context-group name="null"> 1597 <context-group name="null">
1616 <context context-type="linenumber">265</context> 1598 <context context-type="linenumber">280</context>
1617 </context-group> 1599 </context-group>
1618 </trans-unit> 1600 </trans-unit>
1619 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c"> 1601 <trans-unit id="e3a65df2560e99864bbde695da3a7bdf743a184c">
1620 <source>Customizations</source> 1602 <source>Customizations</source>
1621 <target>自訂</target> 1603 <target>自訂</target>
1622 <context-group name="null"> 1604 <context-group name="null">
1623 <context context-type="linenumber">275</context> 1605 <context context-type="linenumber">289</context>
1624 </context-group> 1606 </context-group>
1625 </trans-unit> 1607 </trans-unit>
1626 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c"> 1608 <trans-unit id="0da9752916950ce6890d897b835c923a71ad9c5c">
1627 <source>JavaScript</source> 1609 <source>JavaScript</source>
1628 <target>JavaScript</target> 1610 <target>JavaScript</target>
1629 <context-group name="null"> 1611 <context-group name="null">
1630 <context context-type="linenumber">278</context> 1612 <context context-type="linenumber">294</context>
1631 </context-group> 1613 </context-group>
1632 </trans-unit> 1614 </trans-unit>
1633 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c"> 1615 <trans-unit id="fda2339a6e6ba017ee43b560caf660ed4022333c">
1634 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source> 1616 <source>Write directly JavaScript code.&lt;br /&gt;Example: &lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</source>
1635 <target>直接編寫 JavaScript 程å¼ç¢¼ã€‚&lt;br /&gt;範例:&lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</target> 1617 <target>直接編寫 JavaScript 程å¼ç¢¼ã€‚&lt;br /&gt;範例:&lt;pre&gt;console.log('my instance is amazing');&lt;/pre&gt;</target>
1636 <context-group name="null"> 1618 <context-group name="null">
1637 <context context-type="linenumber">281</context>
1638 </context-group>
1639 </trans-unit>
1640 <trans-unit id="3c2a41724fa0abcd1047ed111508367405f229b5">
1641 <source>
1642 Write directly CSS code. Example:&lt;br /&gt;
1643 &lt;pre&gt;
1644 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1645 background-color: red;
1646 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1647 &lt;/pre&gt;
1648
1649 Prepend with &lt;em&gt;#custom-css&lt;/em&gt; to override styles. Example:
1650 &lt;pre&gt;
1651 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1652 color: red;
1653 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1654 &lt;/pre&gt;
1655 </source>
1656 <target>
1657 直接撰寫 CSS 程å¼ç¢¼ã€‚範例:&lt;br /&gt;
1658 &lt;pre&gt;
1659 body <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1660 background-color: red;
1661 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1662 &lt;/pre&gt;
1663
1664 附加 &lt;em&gt;#custom-css&lt;/em&gt; 以覆寫樣å¼ã€‚範例:
1665 &lt;pre&gt;
1666 #custom-css .logged-in-email <x id="INTERPOLATION" equiv-text="{{ '{' }}"/>
1667 color: red;
1668 <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/>
1669 &lt;/pre&gt;
1670 </target>
1671 <context-group name="null">
1672 <context context-type="linenumber">297</context> 1619 <context context-type="linenumber">297</context>
1673 </context-group> 1620 </context-group>
1674 </trans-unit> 1621 </trans-unit>
@@ -1676,21 +1623,21 @@
1676 <source>Advanced configuration</source> 1623 <source>Advanced configuration</source>
1677 <target>進階設定</target> 1624 <target>進階設定</target>
1678 <context-group name="null"> 1625 <context-group name="null">
1679 <context context-type="linenumber">207</context> 1626 <context context-type="linenumber">212</context>
1680 </context-group> 1627 </context-group>
1681 </trans-unit> 1628 </trans-unit>
1682 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8"> 1629 <trans-unit id="dad5a5283e4c853c011a0f03d5a52310338bbff8">
1683 <source>Update configuration</source> 1630 <source>Update configuration</source>
1684 <target>更新設定</target> 1631 <target>更新設定</target>
1685 <context-group name="null"> 1632 <context-group name="null">
1686 <context context-type="linenumber">325</context> 1633 <context context-type="linenumber">340</context>
1687 </context-group> 1634 </context-group>
1688 </trans-unit> 1635 </trans-unit>
1689 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca"> 1636 <trans-unit id="3e459b5c3861d8c80084d21d233b7c8e2edd3cca">
1690 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source> 1637 <source>It seems the configuration is invalid. Please search potential errors in the different tabs.</source>
1691 <target>設定似乎無效。請在ä¸åŒçš„分é ä¸­æœå°‹æ½›åœ¨çš„錯誤。</target> 1638 <target>設定似乎無效。請在ä¸åŒçš„分é ä¸­æœå°‹æ½›åœ¨çš„錯誤。</target>
1692 <context-group name="null"> 1639 <context-group name="null">
1693 <context context-type="linenumber">326</context> 1640 <context context-type="linenumber">341</context>
1694 </context-group> 1641 </context-group>
1695 </trans-unit> 1642 </trans-unit>
1696 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c"> 1643 <trans-unit id="80dbb8ba42b97a9ec035c0ba09f45c07ea07096c">
@@ -1972,11 +1919,25 @@
1972 <context context-type="linenumber">133</context> 1919 <context context-type="linenumber">133</context>
1973 </context-group> 1920 </context-group>
1974 </trans-unit> 1921 </trans-unit>
1922 <trans-unit id="02ba1a65db92d1d0ab4ba380086e9be61891aaa5">
1923 <source>User's email must be verified to login</source>
1924 <target>使用者的電å­éƒµä»¶å¿…須驗證éŽæ‰èƒ½ç™»å…¥</target>
1925 <context-group name="null">
1926 <context context-type="linenumber">72</context>
1927 </context-group>
1928 </trans-unit>
1929 <trans-unit id="79cee9973620b2592ff2824c525aa8ed0b5e2b8b">
1930 <source>User's email is verified / User can login without email verification</source>
1931 <target>使用者的電å­éƒµä»¶å·²é©—è­‰ï¼ä½¿ç”¨è€…å¯ä»¥ä¸é€éŽé›»å­éƒµä»¶é©—證登入</target>
1932 <context-group name="null">
1933 <context context-type="linenumber">76</context>
1934 </context-group>
1935 </trans-unit>
1975 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee"> 1936 <trans-unit id="a9587caabf0dc5d824f817baae1c2f5521d9b1ee">
1976 <source>Ban reason:</source> 1937 <source>Ban reason:</source>
1977 <target>阻擋ç†ç”±ï¼š</target> 1938 <target>阻擋ç†ç”±ï¼š</target>
1978 <context-group name="null"> 1939 <context-group name="null">
1979 <context context-type="linenumber">92</context> 1940 <context context-type="linenumber">95</context>
1980 </context-group> 1941 </context-group>
1981 </trans-unit> 1942 </trans-unit>
1982 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f"> 1943 <trans-unit id="bb863c794307735652d8695143e116eaee8a3c4f">
@@ -2043,7 +2004,7 @@
2043 <source>Actions</source> 2004 <source>Actions</source>
2044 <target>動作</target> 2005 <target>動作</target>
2045 <context-group name="null"> 2006 <context-group name="null">
2046 <context context-type="linenumber">33</context> 2007 <context context-type="linenumber">35</context>
2047 </context-group> 2008 </context-group>
2048 </trans-unit> 2009 </trans-unit>
2049 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2"> 2010 <trans-unit id="e330cbadca2d8639aabf525d5fe7e5b62d324ee2">
@@ -2078,14 +2039,14 @@
2078 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source> 2039 <source>Date <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></source>
2079 <target>日期 <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target> 2040 <target>日期 <x id="START_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;p-sortIcon&gt;"/><x id="CLOSE_TAG_P-SORTICON" ctype="x-p-sortIcon" equiv-text="&lt;/p-sortIcon&gt;"/></target>
2080 <context-group name="null"> 2041 <context-group name="null">
2081 <context context-type="linenumber">10</context> 2042 <context context-type="linenumber">11</context>
2082 </context-group> 2043 </context-group>
2083 </trans-unit> 2044 </trans-unit>
2084 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f"> 2045 <trans-unit id="7963019b5535b51efa399e6a62b163f3e04d296f">
2085 <source>Blacklist reason:</source> 2046 <source>Blacklist reason:</source>
2086 <target>黑åå–®ç†ç”±ï¼š</target> 2047 <target>黑åå–®ç†ç”±ï¼š</target>
2087 <context-group name="null"> 2048 <context-group name="null">
2088 <context context-type="linenumber">41</context> 2049 <context context-type="linenumber">43</context>
2089 </context-group> 2050 </context-group>
2090 </trans-unit> 2051 </trans-unit>
2091 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c"> 2052 <trans-unit id="90868353e7e6f5994109ee1011131cefa992116c">
@@ -2144,69 +2105,6 @@
2144 <context context-type="linenumber">23</context> 2105 <context context-type="linenumber">23</context>
2145 </context-group> 2106 </context-group>
2146 </trans-unit> 2107 </trans-unit>
2147 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
2148 <source>My settings</source>
2149 <target>我的設定</target>
2150 <context-group name="null">
2151 <context context-type="linenumber">3</context>
2152 </context-group>
2153 </trans-unit>
2154 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
2155 <source>My library</source>
2156 <target>我的媒體庫</target>
2157 <context-group name="null">
2158 <context context-type="linenumber">7</context>
2159 </context-group>
2160 </trans-unit>
2161 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
2162 <source>My channels</source>
2163 <target>我的頻é“</target>
2164 <context-group name="null">
2165 <context context-type="linenumber">12</context>
2166 </context-group>
2167 </trans-unit>
2168 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
2169 <source>My videos</source>
2170 <target>我的影片</target>
2171 <context-group name="null">
2172 <context context-type="linenumber">14</context>
2173 </context-group>
2174 </trans-unit>
2175 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
2176 <source>My subscriptions</source>
2177 <target>我的訂閱</target>
2178 <context-group name="null">
2179 <context context-type="linenumber">16</context>
2180 </context-group>
2181 </trans-unit>
2182 <trans-unit id="bd751145ec934c2839fd6acffee05fbf439782ed">
2183 <source>My imports</source>
2184 <target>我的匯入</target>
2185 <context-group name="null">
2186 <context context-type="linenumber">18</context>
2187 </context-group>
2188 </trans-unit>
2189 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
2190 <source>Misc</source>
2191 <target>雜項</target>
2192 <context-group name="null">
2193 <context context-type="linenumber">24</context>
2194 </context-group>
2195 </trans-unit>
2196 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2197 <source>Muted instances</source>
2198 <target>å·²éœéŸ³çš„實體</target>
2199 <context-group name="null">
2200 <context context-type="linenumber">2</context>
2201 </context-group>
2202 </trans-unit>
2203 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
2204 <source>Ownership changes</source>
2205 <target>所有權變更</target>
2206 <context-group name="null">
2207 <context context-type="linenumber">33</context>
2208 </context-group>
2209 </trans-unit>
2210 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48"> 2108 <trans-unit id="9518d3fb042d551167c1701ddeb88a1374cf1e48">
2211 <source>Video quota:</source> 2109 <source>Video quota:</source>
2212 <target>影片é…é¡ï¼š</target> 2110 <target>影片é…é¡ï¼š</target>
@@ -2218,21 +2116,21 @@
2218 <source>Profile</source> 2116 <source>Profile</source>
2219 <target>簡介</target> 2117 <target>簡介</target>
2220 <context-group name="null"> 2118 <context-group name="null">
2221 <context context-type="linenumber">8</context> 2119 <context context-type="linenumber">7</context>
2222 </context-group> 2120 </context-group>
2223 </trans-unit> 2121 </trans-unit>
2224 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925"> 2122 <trans-unit id="b5398623f87ee72ed23f5023918db1707771e925">
2225 <source>Video settings</source> 2123 <source>Video settings</source>
2226 <target>影片設定</target> 2124 <target>影片設定</target>
2227 <context-group name="null"> 2125 <context-group name="null">
2228 <context context-type="linenumber">15</context> 2126 <context context-type="linenumber">16</context>
2229 </context-group> 2127 </context-group>
2230 </trans-unit> 2128 </trans-unit>
2231 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735"> 2129 <trans-unit id="c74e3202d080780c6415d0e9209c1c859438b735">
2232 <source>Danger zone</source> 2130 <source>Danger zone</source>
2233 <target>å±éšªå€åŸŸ</target> 2131 <target>å±éšªå€åŸŸ</target>
2234 <context-group name="null"> 2132 <context-group name="null">
2235 <context context-type="linenumber">18</context> 2133 <context context-type="linenumber">19</context>
2236 </context-group> 2134 </context-group>
2237 </trans-unit> 2135 </trans-unit>
2238 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf"> 2136 <trans-unit id="2dc22fcebf6aaa76196d2def33a827a34bf910bf">
@@ -2260,13 +2158,6 @@
2260 <context context-type="linenumber">35</context> 2158 <context context-type="linenumber">35</context>
2261 </context-group> 2159 </context-group>
2262 </trans-unit> 2160 </trans-unit>
2263 <trans-unit id="71c77bb8cecdf11ec3eead24dd1ba506573fa9cd">
2264 <source>Submit</source>
2265 <target>éžäº¤</target>
2266 <context-group name="null">
2267 <context context-type="linenumber">24</context>
2268 </context-group>
2269 </trans-unit>
2270 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79"> 2161 <trans-unit id="8057bddbed23d6cd911df8cc3a4ec24d1f258b79">
2271 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source> 2162 <source><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> views</source>
2272 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> 次檢視</target> 2163 <target><x id="INTERPOLATION" equiv-text="{{ video.createdAt | myFromNow }}"/> - <x id="INTERPOLATION_1" equiv-text="{{ video.views | myNumberFormatter }}"/> 次檢視</target>
@@ -2425,6 +2316,13 @@ When you will upload a video in this channel, the video support field will be au
2425 <context context-type="linenumber">47</context> 2316 <context context-type="linenumber">47</context>
2426 </context-group> 2317 </context-group>
2427 </trans-unit> 2318 </trans-unit>
2319 <trans-unit id="2bc7533f8c8e7d183950ba1094a0acd9efc22e5e">
2320 <source>Muted instances</source>
2321 <target>å·²éœéŸ³çš„實體</target>
2322 <context-group name="null">
2323 <context context-type="linenumber">2</context>
2324 </context-group>
2325 </trans-unit>
2428 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9"> 2326 <trans-unit id="739516c2ca75843d5aec9cf0e6b3e4335c4227b9">
2429 <source>Change password</source> 2327 <source>Change password</source>
2430 <target>變更密碼</target> 2328 <target>變更密碼</target>
@@ -2628,6 +2526,13 @@ When you will upload a video in this channel, the video support field will be au
2628 <context context-type="linenumber">159</context> 2526 <context context-type="linenumber">159</context>
2629 </context-group> 2527 </context-group>
2630 </trans-unit> 2528 </trans-unit>
2529 <trans-unit id="385811ab5a5c3e96e0db46c9ce1fc3147d8cd4c7">
2530 <source>Sorry, but something went wrong</source>
2531 <target>抱歉,ä¸éŽå¥½åƒæœ‰ä»€éº¼æ±è¥¿å‡ºéŒ¯äº†</target>
2532 <context-group name="null">
2533 <context context-type="linenumber">49</context>
2534 </context-group>
2535 </trans-unit>
2631 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2"> 2536 <trans-unit id="63d6bf87c9f30441175648dfd3ef6a19292287c2">
2632 <source> 2537 <source>
2633 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video. 2538 Congratulations, the video behind <x id="INTERPOLATION" equiv-text="{{ targetUrl }}"/> will be imported! You can already add information about this video.
@@ -2662,14 +2567,14 @@ When you will upload a video in this channel, the video support field will be au
2662 <source>Publish will be available when upload is finished</source> 2567 <source>Publish will be available when upload is finished</source>
2663 <target>上傳完æˆæ™‚å°‡å¯ç™¼ä½ˆ</target> 2568 <target>上傳完æˆæ™‚å°‡å¯ç™¼ä½ˆ</target>
2664 <context-group name="null"> 2569 <context-group name="null">
2665 <context context-type="linenumber">53</context> 2570 <context context-type="linenumber">58</context>
2666 </context-group> 2571 </context-group>
2667 </trans-unit> 2572 </trans-unit>
2668 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3"> 2573 <trans-unit id="223aae0477f79f0bc4436c1c57619415f04cbbb3">
2669 <source>Publish</source> 2574 <source>Publish</source>
2670 <target>發佈</target> 2575 <target>發佈</target>
2671 <context-group name="null"> 2576 <context-group name="null">
2672 <context context-type="linenumber">60</context> 2577 <context context-type="linenumber">65</context>
2673 </context-group> 2578 </context-group>
2674 </trans-unit> 2579 </trans-unit>
2675 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b"> 2580 <trans-unit id="2fcbf437e001f47974d45bd03a19e0d9245fdb3b">
@@ -2850,14 +2755,14 @@ When you will upload a video in this channel, the video support field will be au
2850 <source>Wait transcoding before publishing the video</source> 2755 <source>Wait transcoding before publishing the video</source>
2851 <target>正等待發佈影片å‰çš„轉æ›ç·¨ç¢¼</target> 2756 <target>正等待發佈影片å‰çš„轉æ›ç·¨ç¢¼</target>
2852 <context-group name="null"> 2757 <context-group name="null">
2853 <context context-type="linenumber">130</context> 2758 <context context-type="linenumber">131</context>
2854 </context-group> 2759 </context-group>
2855 </trans-unit> 2760 </trans-unit>
2856 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63"> 2761 <trans-unit id="24f468ce1148a096477d8dd0d00f0d1fd88d6c63">
2857 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source> 2762 <source>If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends.</source>
2858 <target>如果您決定ä¸è¦ç­‰å¾…在發佈影片å‰çš„轉æ›ç·¨ç¢¼ï¼Œå®ƒå¯èƒ½æœƒåœ¨è½‰æ›ç·¨ç¢¼çµæŸå‰éƒ½ç„¡æ³•æ’­æ”¾ã€‚</target> 2763 <target>如果您決定ä¸è¦ç­‰å¾…在發佈影片å‰çš„轉æ›ç·¨ç¢¼ï¼Œå®ƒå¯èƒ½æœƒåœ¨è½‰æ›ç·¨ç¢¼çµæŸå‰éƒ½ç„¡æ³•æ’­æ”¾ã€‚</target>
2859 <context-group name="null"> 2764 <context-group name="null">
2860 <context context-type="linenumber">131</context> 2765 <context context-type="linenumber">132</context>
2861 </context-group> 2766 </context-group>
2862 </trans-unit> 2767 </trans-unit>
2863 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7"> 2768 <trans-unit id="c7742322b1d3dbc921362058d1747c7ec2adbec7">
@@ -2871,49 +2776,49 @@ When you will upload a video in this channel, the video support field will be au
2871 <source>Add another caption</source> 2776 <source>Add another caption</source>
2872 <target>新增其他字幕</target> 2777 <target>新增其他字幕</target>
2873 <context-group name="null"> 2778 <context-group name="null">
2874 <context context-type="linenumber">146</context> 2779 <context context-type="linenumber">147</context>
2875 </context-group> 2780 </context-group>
2876 </trans-unit> 2781 </trans-unit>
2877 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed"> 2782 <trans-unit id="a46a7503167b77b3ec4e28274a3d1dda637617ed">
2878 <source>See the subtitle file</source> 2783 <source>See the subtitle file</source>
2879 <target>檢視字幕檔案</target> 2784 <target>檢視字幕檔案</target>
2880 <context-group name="null"> 2785 <context-group name="null">
2881 <context context-type="linenumber">155</context> 2786 <context context-type="linenumber">156</context>
2882 </context-group> 2787 </context-group>
2883 </trans-unit> 2788 </trans-unit>
2884 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee"> 2789 <trans-unit id="e687f6387adbaf61ce650b58f0e60ca42d843cee">
2885 <source>Already uploaded ✔</source> 2790 <source>Already uploaded ✔</source>
2886 <target>已上傳 ✔</target> 2791 <target>已上傳 ✔</target>
2887 <context-group name="null"> 2792 <context-group name="null">
2888 <context context-type="linenumber">159</context> 2793 <context context-type="linenumber">160</context>
2889 </context-group> 2794 </context-group>
2890 </trans-unit> 2795 </trans-unit>
2891 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad"> 2796 <trans-unit id="ca4588e185413b2fc77dbe35c861cc540b11b9ad">
2892 <source>Will be created on update</source> 2797 <source>Will be created on update</source>
2893 <target>將在更新時建立</target> 2798 <target>將在更新時建立</target>
2894 <context-group name="null"> 2799 <context-group name="null">
2895 <context context-type="linenumber">167</context> 2800 <context context-type="linenumber">168</context>
2896 </context-group> 2801 </context-group>
2897 </trans-unit> 2802 </trans-unit>
2898 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9"> 2803 <trans-unit id="308a79679d012938a625e41fdd4b804fe42b57b9">
2899 <source>Cancel create</source> 2804 <source>Cancel create</source>
2900 <target>å–消建立</target> 2805 <target>å–消建立</target>
2901 <context-group name="null"> 2806 <context-group name="null">
2902 <context context-type="linenumber">169</context> 2807 <context context-type="linenumber">170</context>
2903 </context-group> 2808 </context-group>
2904 </trans-unit> 2809 </trans-unit>
2905 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393"> 2810 <trans-unit id="b6bfdd386cb0b560d697c93555d8cd8cab00c393">
2906 <source>Will be deleted on update</source> 2811 <source>Will be deleted on update</source>
2907 <target>將在更新時刪除</target> 2812 <target>將在更新時刪除</target>
2908 <context-group name="null"> 2813 <context-group name="null">
2909 <context context-type="linenumber">175</context> 2814 <context context-type="linenumber">176</context>
2910 </context-group> 2815 </context-group>
2911 </trans-unit> 2816 </trans-unit>
2912 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c"> 2817 <trans-unit id="88395fc0137e46a9853cf16762bf5a87687d0d0c">
2913 <source>Cancel deletion</source> 2818 <source>Cancel deletion</source>
2914 <target>å–消刪除</target> 2819 <target>å–消刪除</target>
2915 <context-group name="null"> 2820 <context-group name="null">
2916 <context context-type="linenumber">177</context> 2821 <context context-type="linenumber">178</context>
2917 </context-group> 2822 </context-group>
2918 </trans-unit> 2823 </trans-unit>
2919 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0"> 2824 <trans-unit id="82f867b2607d45ba36de11d4c8b53d7177122ee0">
@@ -2924,28 +2829,28 @@ When you will upload a video in this channel, the video support field will be au
2924 ç¾åœ¨æ²’有字幕。 2829 ç¾åœ¨æ²’有字幕。
2925 </target> 2830 </target>
2926 <context-group name="null"> 2831 <context-group name="null">
2927 <context context-type="linenumber">182</context> 2832 <context context-type="linenumber">183</context>
2928 </context-group> 2833 </context-group>
2929 </trans-unit> 2834 </trans-unit>
2930 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93"> 2835 <trans-unit id="0c720e0dd9e6c60095f961cb714f47e8c0090f93">
2931 <source>Captions</source> 2836 <source>Captions</source>
2932 <target>字幕</target> 2837 <target>字幕</target>
2933 <context-group name="null"> 2838 <context-group name="null">
2934 <context context-type="linenumber">139</context> 2839 <context context-type="linenumber">140</context>
2935 </context-group> 2840 </context-group>
2936 </trans-unit> 2841 </trans-unit>
2937 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513"> 2842 <trans-unit id="1dd793abd1cb8d16a7a2cb71ca5549a7111ee513">
2938 <source>Upload thumbnail</source> 2843 <source>Upload thumbnail</source>
2939 <target>上傳縮圖</target> 2844 <target>上傳縮圖</target>
2940 <context-group name="null"> 2845 <context-group name="null">
2941 <context context-type="linenumber">195</context> 2846 <context context-type="linenumber">196</context>
2942 </context-group> 2847 </context-group>
2943 </trans-unit> 2848 </trans-unit>
2944 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639"> 2849 <trans-unit id="9df3f57e251c077bef7e7da81677cb971c55b639">
2945 <source>Upload preview</source> 2850 <source>Upload preview</source>
2946 <target>上傳é è¦½</target> 2851 <target>上傳é è¦½</target>
2947 <context-group name="null"> 2852 <context-group name="null">
2948 <context context-type="linenumber">202</context> 2853 <context context-type="linenumber">203</context>
2949 </context-group> 2854 </context-group>
2950 </trans-unit> 2855 </trans-unit>
2951 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604"> 2856 <trans-unit id="b5629d298ff1a69b8db19a4ba2995c76b52da604">
@@ -2959,14 +2864,14 @@ When you will upload a video in this channel, the video support field will be au
2959 <source>Short text to tell people how they can support you (membership platform...).</source> 2864 <source>Short text to tell people how they can support you (membership platform...).</source>
2960 <target>告訴人們他們å¯ä»¥å¦‚何支æ´æ‚¨ï¼ˆæˆå“¡å¹³è‡ºç­‰ï¼‰çš„短文</target> 2865 <target>告訴人們他們å¯ä»¥å¦‚何支æ´æ‚¨ï¼ˆæˆå“¡å¹³è‡ºç­‰ï¼‰çš„短文</target>
2961 <context-group name="null"> 2866 <context-group name="null">
2962 <context context-type="linenumber">209</context> 2867 <context context-type="linenumber">210</context>
2963 </context-group> 2868 </context-group>
2964 </trans-unit> 2869 </trans-unit>
2965 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1"> 2870 <trans-unit id="d91da0abc638c05e52adea253d0813f3584da4b1">
2966 <source>Advanced settings</source> 2871 <source>Advanced settings</source>
2967 <target>進階設定</target> 2872 <target>進階設定</target>
2968 <context-group name="null"> 2873 <context-group name="null">
2969 <context context-type="linenumber">190</context> 2874 <context context-type="linenumber">191</context>
2970 </context-group> 2875 </context-group>
2971 </trans-unit> 2876 </trans-unit>
2972 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0"> 2877 <trans-unit id="2335f0bd17c63d835b50cfbbcea6c459cb1314c0">
@@ -3033,17 +2938,6 @@ When you will upload a video in this channel, the video support field will be au
3033 <context context-type="linenumber">3</context> 2938 <context context-type="linenumber">3</context>
3034 </context-group> 2939 </context-group>
3035 </trans-unit> 2940 </trans-unit>
3036 <trans-unit id="fb8aad312b72bbb7e5a1e2cc0b55fae8962bf0fb">
3037 <source>
3038 Cancel
3039 </source>
3040 <target>
3041 å–消
3042 </target>
3043 <context-group name="null">
3044 <context context-type="linenumber">19</context>
3045 </context-group>
3046 </trans-unit>
3047 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9"> 2941 <trans-unit id="0bd8b27f60a1f098a53e06328426d818e3508ff9">
3048 <source>Share</source> 2942 <source>Share</source>
3049 <target>分享</target> 2943 <target>分享</target>
@@ -3428,13 +3322,6 @@ When you will upload a video in this channel, the video support field will be au
3428 <context context-type="linenumber">14</context> 3322 <context context-type="linenumber">14</context>
3429 </context-group> 3323 </context-group>
3430 </trans-unit> 3324 </trans-unit>
3431 <trans-unit id="814d28bf9dcbd3122254e664b446ac8e0442bc08">
3432 <source>Error getting about from server</source>
3433 <target>å–得關於伺æœå™¨çš„錯誤</target>
3434 <context-group name="null">
3435 <context context-type="linenumber">1</context>
3436 </context-group>
3437 </trans-unit>
3438 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968"> 3325 <trans-unit id="37b56526e384f843a15323dc730b484a97b4c968">
3439 <source>No description</source> 3326 <source>No description</source>
3440 <target>沒有æè¿°</target> 3327 <target>沒有æè¿°</target>
@@ -3456,13 +3343,6 @@ When you will upload a video in this channel, the video support field will be au
3456 <context context-type="linenumber">1</context> 3343 <context context-type="linenumber">1</context>
3457 </context-group> 3344 </context-group>
3458 </trans-unit> 3345 </trans-unit>
3459 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
3460 <source>Error</source>
3461 <target>錯誤</target>
3462 <context-group name="null">
3463 <context context-type="linenumber">1</context>
3464 </context-group>
3465 </trans-unit>
3466 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6"> 3346 <trans-unit id="d9fc2b03f04056671d7d4ffcac7197189d959cd6">
3467 <source>240p</source> 3347 <source>240p</source>
3468 <target>240p</target> 3348 <target>240p</target>
@@ -3505,13 +3385,6 @@ When you will upload a video in this channel, the video support field will be au
3505 <context context-type="linenumber">1</context> 3385 <context context-type="linenumber">1</context>
3506 </context-group> 3386 </context-group>
3507 </trans-unit> 3387 </trans-unit>
3508 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
3509 <source>Success</source>
3510 <target>æˆåŠŸ</target>
3511 <context-group name="null">
3512 <context context-type="linenumber">1</context>
3513 </context-group>
3514 </trans-unit>
3515 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048"> 3388 <trans-unit id="b9e64712e3e5c342ce9cd32eec6cd7d6c00f4048">
3516 <source>Configuration updated.</source> 3389 <source>Configuration updated.</source>
3517 <target>設定已更新。</target> 3390 <target>設定已更新。</target>
@@ -3778,6 +3651,13 @@ When you will upload a video in this channel, the video support field will be au
3778 <context context-type="linenumber">1</context> 3651 <context context-type="linenumber">1</context>
3779 </context-group> 3652 </context-group>
3780 </trans-unit> 3653 </trans-unit>
3654 <trans-unit id="910ed85f550272401b134a40d019ab3359fe883f">
3655 <source>Set Email as Verified</source>
3656 <target>設定電å­éƒµä»¶ç‚ºå·²é©—è­‰</target>
3657 <context-group name="null">
3658 <context context-type="linenumber">1</context>
3659 </context-group>
3660 </trans-unit>
3781 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf"> 3661 <trans-unit id="ac401df84c5fa471700c3368de51c969ccb8bacf">
3782 <source>You cannot ban root.</source> 3662 <source>You cannot ban root.</source>
3783 <target>您ä¸èƒ½é˜»æ“‹ root。</target> 3663 <target>您ä¸èƒ½é˜»æ“‹ root。</target>
@@ -3820,6 +3700,13 @@ When you will upload a video in this channel, the video support field will be au
3820 <context context-type="linenumber">1</context> 3700 <context context-type="linenumber">1</context>
3821 </context-group> 3701 </context-group>
3822 </trans-unit> 3702 </trans-unit>
3703 <trans-unit id="f4a8f2ef1fbfc19e1e049e69f63c40063c0d0650">
3704 <source><x id="INTERPOLATION" equiv-text="{{num}}"/> users email set as verified.</source>
3705 <target><x id="INTERPOLATION" equiv-text="{{num}}"/> 個使用者電å­éƒµä»¶è¨­å®šç‚ºå·²é©—證。</target>
3706 <context-group name="null">
3707 <context context-type="linenumber">1</context>
3708 </context-group>
3709 </trans-unit>
3823 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de"> 3710 <trans-unit id="2667ca38672421a0a7a22343d2a0060ee41246de">
3824 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source> 3711 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> unmuted.</source>
3825 <target>帳號 <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> 已解除éœéŸ³ã€‚</target> 3712 <target>帳號 <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> 已解除éœéŸ³ã€‚</target>
@@ -3932,23 +3819,16 @@ When you will upload a video in this channel, the video support field will be au
3932 <context context-type="linenumber">1</context> 3819 <context context-type="linenumber">1</context>
3933 </context-group> 3820 </context-group>
3934 </trans-unit> 3821 </trans-unit>
3935 <trans-unit id="d5adc9efad0469fc3e1503d68c4ec2ff4453a814"> 3822 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2">
3936 <source>Do you really want to delete <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/>? It will delete all videos uploaded in this channel too.</source> 3823 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source>
3937 <target>您真的想è¦åˆªé™¤ <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> 嗎?這也會刪除所有上傳到這個頻é“的影片。</target> 3824 <target>å½±ç‰‡é »é“ <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> 已刪除。</target>
3938 <context-group name="null">
3939 <context context-type="linenumber">1</context>
3940 </context-group>
3941 </trans-unit>
3942 <trans-unit id="703dee7f3e693f9c77ef17c46f9fa71999609f8e">
3943 <source>Please type the name of the video channel to confirm</source>
3944 <target>請輸入影片頻é“çš„å稱以確èª</target>
3945 <context-group name="null"> 3825 <context-group name="null">
3946 <context context-type="linenumber">1</context> 3826 <context context-type="linenumber">1</context>
3947 </context-group> 3827 </context-group>
3948 </trans-unit> 3828 </trans-unit>
3949 <trans-unit id="a81a33275b683729ad938b6102e7e34a057537a2"> 3829 <trans-unit id="d02888c485d3aeab6de628508f4a00312a722894">
3950 <source>Video channel <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> deleted.</source> 3830 <source>My videos</source>
3951 <target>å½±ç‰‡é »é“ <x id="INTERPOLATION" equiv-text="{{videoChannelName}}"/> 已刪除。</target> 3831 <target>我的影片</target>
3952 <context-group name="null"> 3832 <context-group name="null">
3953 <context context-type="linenumber">1</context> 3833 <context context-type="linenumber">1</context>
3954 </context-group> 3834 </context-group>
@@ -4023,16 +3903,44 @@ When you will upload a video in this channel, the video support field will be au
4023 <context context-type="linenumber">1</context> 3903 <context context-type="linenumber">1</context>
4024 </context-group> 3904 </context-group>
4025 </trans-unit> 3905 </trans-unit>
4026 <trans-unit id="807cf11e6ac1cde912496f764c176bdfdd6b7e19"> 3906 <trans-unit id="4ef4f031c147fb9ee0168bc6eacb78de180d7432">
4027 <source>Channels</source> 3907 <source>My library</source>
4028 <target>é »é“</target> 3908 <target>我的媒體庫</target>
3909 <context-group name="null">
3910 <context context-type="linenumber">1</context>
3911 </context-group>
3912 </trans-unit>
3913 <trans-unit id="8dd18d9047c4b2dc9786550dfd8fa99f3b14e17f">
3914 <source>My channels</source>
3915 <target>我的頻é“</target>
3916 <context-group name="null">
3917 <context context-type="linenumber">1</context>
3918 </context-group>
3919 </trans-unit>
3920 <trans-unit id="29038e66547b3ba70701fb34eda68834a56f17d9">
3921 <source>My subscriptions</source>
3922 <target>我的訂閱</target>
3923 <context-group name="null">
3924 <context context-type="linenumber">1</context>
3925 </context-group>
3926 </trans-unit>
3927 <trans-unit id="46aa32e581922d6d2c3d7bc4c87209ad5808b029">
3928 <source>Misc</source>
3929 <target>雜項</target>
3930 <context-group name="null">
3931 <context context-type="linenumber">1</context>
3932 </context-group>
3933 </trans-unit>
3934 <trans-unit id="73022f1676784c4f9b8cdbb322e52b02ccc800b7">
3935 <source>Ownership changes</source>
3936 <target>所有權變更</target>
4029 <context-group name="null"> 3937 <context-group name="null">
4030 <context context-type="linenumber">1</context> 3938 <context context-type="linenumber">1</context>
4031 </context-group> 3939 </context-group>
4032 </trans-unit> 3940 </trans-unit>
4033 <trans-unit id="4bc7db3e3f8ae777dd480e2019af97fd8c1be47d"> 3941 <trans-unit id="efad4be364b8fb5c73cbfcc7acccd542f9d84ad6">
4034 <source>Video imports</source> 3942 <source>My settings</source>
4035 <target>影片匯入</target> 3943 <target>我的設定</target>
4036 <context-group name="null"> 3944 <context-group name="null">
4037 <context context-type="linenumber">1</context> 3945 <context context-type="linenumber">1</context>
4038 </context-group> 3946 </context-group>
@@ -4158,6 +4066,13 @@ When you will upload a video in this channel, the video support field will be au
4158 <context context-type="linenumber">1</context> 4066 <context context-type="linenumber">1</context>
4159 </context-group> 4067 </context-group>
4160 </trans-unit> 4068 </trans-unit>
4069 <trans-unit id="6080b77234e92ad41bb52653b239c4c4f851317d">
4070 <source>Error</source>
4071 <target>錯誤</target>
4072 <context-group name="null">
4073 <context context-type="linenumber">1</context>
4074 </context-group>
4075 </trans-unit>
4161 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87"> 4076 <trans-unit id="e31bbf15d6ba5c7c0f17f89a98029cff0bd40b87">
4162 <source>You need to reconnect.</source> 4077 <source>You need to reconnect.</source>
4163 <target>您需è¦é‡æ–°é€£ç·šã€‚</target> 4078 <target>您需è¦é‡æ–°é€£ç·šã€‚</target>
@@ -4179,6 +4094,20 @@ When you will upload a video in this channel, the video support field will be au
4179 <context context-type="linenumber">1</context> 4094 <context context-type="linenumber">1</context>
4180 </context-group> 4095 </context-group>
4181 </trans-unit> 4096 </trans-unit>
4097 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
4098 <source>Info</source>
4099 <target>資訊</target>
4100 <context-group name="null">
4101 <context context-type="linenumber">1</context>
4102 </context-group>
4103 </trans-unit>
4104 <trans-unit id="1e035e6ccfab771cad4226b2ad230cb0d4a88cba">
4105 <source>Success</source>
4106 <target>æˆåŠŸ</target>
4107 <context-group name="null">
4108 <context context-type="linenumber">1</context>
4109 </context-group>
4110 </trans-unit>
4182 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe"> 4111 <trans-unit id="247071f6c9233b7e5bc1d8f46795ab6b032f1fbe">
4183 <source>Incorrect username or password.</source> 4112 <source>Incorrect username or password.</source>
4184 <target>ä¸æ­£ç¢ºçš„使用者å稱或密碼。</target> 4113 <target>ä¸æ­£ç¢ºçš„使用者å稱或密碼。</target>
@@ -4396,6 +4325,20 @@ When you will upload a video in this channel, the video support field will be au
4396 <context context-type="linenumber">1</context> 4325 <context context-type="linenumber">1</context>
4397 </context-group> 4326 </context-group>
4398 </trans-unit> 4327 </trans-unit>
4328 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4329 <source>Email is required.</source>
4330 <target>é›»å­éƒµä»¶å¿…填。</target>
4331 <context-group name="null">
4332 <context context-type="linenumber">1</context>
4333 </context-group>
4334 </trans-unit>
4335 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4336 <source>Email must be valid.</source>
4337 <target>é›»å­éƒµä»¶å¿…須為有效電å­éƒµä»¶ã€‚</target>
4338 <context-group name="null">
4339 <context context-type="linenumber">1</context>
4340 </context-group>
4341 </trans-unit>
4399 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149"> 4342 <trans-unit id="5db300f6fba918a35597160183205ede13e8e149">
4400 <source>Username is required.</source> 4343 <source>Username is required.</source>
4401 <target>使用者å稱必填。</target> 4344 <target>使用者å稱必填。</target>
@@ -4417,41 +4360,6 @@ When you will upload a video in this channel, the video support field will be au
4417 <context context-type="linenumber">1</context> 4360 <context context-type="linenumber">1</context>
4418 </context-group> 4361 </context-group>
4419 </trans-unit> 4362 </trans-unit>
4420 <trans-unit id="05ad6b99d9bf7b51968aa0b0b939e8627a329bea">
4421 <source>Username must be at least 3 characters long.</source>
4422 <target>使用者å稱必須至少 3 個字元長。</target>
4423 <context-group name="null">
4424 <context context-type="linenumber">1</context>
4425 </context-group>
4426 </trans-unit>
4427 <trans-unit id="d4b11fd0ddeea39b33f911d3aac1e82799cdaaef">
4428 <source>Username cannot be more than 20 characters long.</source>
4429 <target>使用者å稱ä¸èƒ½å¤šæ–¼ 20 個字元。</target>
4430 <context-group name="null">
4431 <context context-type="linenumber">1</context>
4432 </context-group>
4433 </trans-unit>
4434 <trans-unit id="5acbe0aa7a7157b1f09057a98ba01ab578a303a9">
4435 <source>Username should be only lowercase alphanumeric characters.</source>
4436 <target>使用者å稱應該僅有å°å¯«è‹±æ•¸å­—元。</target>
4437 <context-group name="null">
4438 <context context-type="linenumber">1</context>
4439 </context-group>
4440 </trans-unit>
4441 <trans-unit id="b6f52e19f074f77866fa03fabe1ddd5cdae346f0">
4442 <source>Email is required.</source>
4443 <target>é›»å­éƒµä»¶å¿…填。</target>
4444 <context-group name="null">
4445 <context context-type="linenumber">1</context>
4446 </context-group>
4447 </trans-unit>
4448 <trans-unit id="bef8a36c3dffff15fb5faf3d20bdbbbc1af824c1">
4449 <source>Email must be valid.</source>
4450 <target>é›»å­éƒµä»¶å¿…須為有效電å­éƒµä»¶ã€‚</target>
4451 <context-group name="null">
4452 <context context-type="linenumber">1</context>
4453 </context-group>
4454 </trans-unit>
4455 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0"> 4363 <trans-unit id="1fe26e49476ac701885abc59127e96a3760847f0">
4456 <source>Password must be at least 6 characters long.</source> 4364 <source>Password must be at least 6 characters long.</source>
4457 <target>密碼必須至少 6 個字元長。</target> 4365 <target>密碼必須至少 6 個字元長。</target>
@@ -4515,20 +4423,6 @@ When you will upload a video in this channel, the video support field will be au
4515 <context context-type="linenumber">1</context> 4423 <context context-type="linenumber">1</context>
4516 </context-group> 4424 </context-group>
4517 </trans-unit> 4425 </trans-unit>
4518 <trans-unit id="bdeb1a8e69e137572df795d64120ea85069b7674">
4519 <source>Display name must be at least 3 characters long.</source>
4520 <target>顯示å稱必須至少 3 個字元長。</target>
4521 <context-group name="null">
4522 <context context-type="linenumber">1</context>
4523 </context-group>
4524 </trans-unit>
4525 <trans-unit id="e81bda510399d52f26a44a15c3dbf4d6205d90a9">
4526 <source>Display name cannot be more than 120 characters long.</source>
4527 <target>顯示å稱ä¸èƒ½å¤šæ–¼ 120 個字元。</target>
4528 <context-group name="null">
4529 <context context-type="linenumber">1</context>
4530 </context-group>
4531 </trans-unit>
4532 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae"> 4426 <trans-unit id="d531c2261dc0c2739bd7cbb2bb175946b7eeb3ae">
4533 <source>Description must be at least 3 characters long.</source> 4427 <source>Description must be at least 3 characters long.</source>
4534 <target>æ述必須至少 3 個字元長。</target> 4428 <target>æ述必須至少 3 個字元長。</target>
@@ -4578,13 +4472,6 @@ When you will upload a video in this channel, the video support field will be au
4578 <context context-type="linenumber">1</context> 4472 <context context-type="linenumber">1</context>
4579 </context-group> 4473 </context-group>
4580 </trans-unit> 4474 </trans-unit>
4581 <trans-unit id="7de2178ed1036844fb1c3ad8b7899a039fcdcdb9">
4582 <source>Report reason cannot be more than 300 characters long.</source>
4583 <target>回報ç†ç”±ä¸èƒ½å¤šæ–¼ 300 個字元。</target>
4584 <context-group name="null">
4585 <context context-type="linenumber">1</context>
4586 </context-group>
4587 </trans-unit>
4588 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118"> 4475 <trans-unit id="2fa41debd17a206d4a2a5e8d14bcd7055f6e5118">
4589 <source>Moderation comment is required.</source> 4476 <source>Moderation comment is required.</source>
4590 <target>管ç†è©•è«–必填。</target> 4477 <target>管ç†è©•è«–必填。</target>
@@ -4599,13 +4486,6 @@ When you will upload a video in this channel, the video support field will be au
4599 <context context-type="linenumber">1</context> 4486 <context context-type="linenumber">1</context>
4600 </context-group> 4487 </context-group>
4601 </trans-unit> 4488 </trans-unit>
4602 <trans-unit id="89d0b662dde0871cf17244e79b2cb62cd517e44f">
4603 <source>Moderation comment cannot be more than 300 characters long.</source>
4604 <target>管ç†è©•è«–無法多於 300 個字元。</target>
4605 <context-group name="null">
4606 <context context-type="linenumber">1</context>
4607 </context-group>
4608 </trans-unit>
4609 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6"> 4489 <trans-unit id="94b831c7e3684258f88e099c6cd3b8f73f8a2de6">
4610 <source>The channel is required.</source> 4490 <source>The channel is required.</source>
4611 <target>é »é“必填。</target> 4491 <target>é »é“必填。</target>
@@ -4662,27 +4542,6 @@ When you will upload a video in this channel, the video support field will be au
4662 <context context-type="linenumber">1</context> 4542 <context context-type="linenumber">1</context>
4663 </context-group> 4543 </context-group>
4664 </trans-unit> 4544 </trans-unit>
4665 <trans-unit id="06b5d33d89bb8e6a5013dbd3c07c44389a6f1069">
4666 <source>Name must be at least 3 characters long.</source>
4667 <target>å稱必須至少 3 個字元。</target>
4668 <context-group name="null">
4669 <context context-type="linenumber">1</context>
4670 </context-group>
4671 </trans-unit>
4672 <trans-unit id="a35f2514e29113179795cdb27bca8a2e99c43482">
4673 <source>Name cannot be more than 20 characters long.</source>
4674 <target>å稱ä¸èƒ½è¶…éŽ 20 個字元。</target>
4675 <context-group name="null">
4676 <context context-type="linenumber">1</context>
4677 </context-group>
4678 </trans-unit>
4679 <trans-unit id="807f79894e0c31beca2db09ca4aff57dfaaf3bb9">
4680 <source>Name should be only lowercase alphanumeric characters.</source>
4681 <target>å稱應該åªæœ‰å°å¯«è‹±æ•¸å­—元。</target>
4682 <context-group name="null">
4683 <context context-type="linenumber">1</context>
4684 </context-group>
4685 </trans-unit>
4686 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b"> 4545 <trans-unit id="e7182e21e9566cc81c83f92727461322f71fd69b">
4687 <source>Support text must be at least 3 characters long.</source> 4546 <source>Support text must be at least 3 characters long.</source>
4688 <target>支æ´æ–‡å­—必須至少 3 個字元長。</target> 4547 <target>支æ´æ–‡å­—必須至少 3 個字元長。</target>
@@ -5362,6 +5221,13 @@ When you will upload a video in this channel, the video support field will be au
5362 <context context-type="linenumber">1</context> 5221 <context context-type="linenumber">1</context>
5363 </context-group> 5222 </context-group>
5364 </trans-unit> 5223 </trans-unit>
5224 <trans-unit id="534202c90c6dcadd2989fc72c5030d5483e26096">
5225 <source>User <x id="INTERPOLATION" equiv-text="{{username}}"/> email set as verified</source>
5226 <target>使用者 <x id="INTERPOLATION" equiv-text="{{username}}"/> çš„é›»å­éƒµä»¶è¨­å®šç‚ºå·²é©—è­‰</target>
5227 <context-group name="null">
5228 <context context-type="linenumber">1</context>
5229 </context-group>
5230 </trans-unit>
5365 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249"> 5231 <trans-unit id="33a6319f765848a22a155cef9f1d8e645202e249">
5366 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source> 5232 <source>Account <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> muted.</source>
5367 <target>帳號 <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> 已解除éœéŸ³ã€‚</target> 5233 <target>帳號 <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/> 已解除éœéŸ³ã€‚</target>
@@ -5488,13 +5354,6 @@ When you will upload a video in this channel, the video support field will be au
5488 <context context-type="linenumber">1</context> 5354 <context context-type="linenumber">1</context>
5489 </context-group> 5355 </context-group>
5490 </trans-unit> 5356 </trans-unit>
5491 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5492 <source>Subscribed</source>
5493 <target>已訂閱</target>
5494 <context-group name="null">
5495 <context context-type="linenumber">1</context>
5496 </context-group>
5497 </trans-unit>
5498 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded"> 5357 <trans-unit id="58639b3f0be657475928fb49c4a7cbd16aa44ded">
5499 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source> 5358 <source>Subscribed to <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></source>
5500 <target>訂閱 <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target> 5359 <target>訂閱 <x id="INTERPOLATION" equiv-text="{{nameWithHost}}"/></target>
@@ -5502,9 +5361,9 @@ When you will upload a video in this channel, the video support field will be au
5502 <context context-type="linenumber">1</context> 5361 <context context-type="linenumber">1</context>
5503 </context-group> 5362 </context-group>
5504 </trans-unit> 5363 </trans-unit>
5505 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471"> 5364 <trans-unit id="1cadbf82f0e91611321c5abd282f0c23d8ccbfa1">
5506 <source>Unsubscribed</source> 5365 <source>Subscribed</source>
5507 <target>å·²å–消訂閱</target> 5366 <target>已訂閱</target>
5508 <context-group name="null"> 5367 <context-group name="null">
5509 <context context-type="linenumber">1</context> 5368 <context context-type="linenumber">1</context>
5510 </context-group> 5369 </context-group>
@@ -5516,6 +5375,13 @@ When you will upload a video in this channel, the video support field will be au
5516 <context context-type="linenumber">1</context> 5375 <context context-type="linenumber">1</context>
5517 </context-group> 5376 </context-group>
5518 </trans-unit> 5377 </trans-unit>
5378 <trans-unit id="294395337b767af84f952ac28d58d54a13a11471">
5379 <source>Unsubscribed</source>
5380 <target>å·²å–消訂閱</target>
5381 <context-group name="null">
5382 <context context-type="linenumber">1</context>
5383 </context-group>
5384 </trans-unit>
5519 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf"> 5385 <trans-unit id="38c877fb0a5fdcadc379256953ad2d1eb8233fdf">
5520 <source>Moderator</source> 5386 <source>Moderator</source>
5521 <target>主æŒäºº</target> 5387 <target>主æŒäºº</target>
@@ -5544,6 +5410,20 @@ When you will upload a video in this channel, the video support field will be au
5544 <context context-type="linenumber">1</context> 5410 <context context-type="linenumber">1</context>
5545 </context-group> 5411 </context-group>
5546 </trans-unit> 5412 </trans-unit>
5413 <trans-unit id="21565881ad1dff3c98738b9535b3515cec140609">
5414 <source>Welcome! Now please check your emails to verify your account and complete signup.</source>
5415 <target>æ­¡è¿Žï¼ç¾åœ¨è«‹æª¢æŸ¥æ‚¨çš„é›»å­éƒµä»¶ä»¥é©—證您的帳號並完æˆè¨»å†Šã€‚</target>
5416 <context-group name="null">
5417 <context context-type="linenumber">1</context>
5418 </context-group>
5419 </trans-unit>
5420 <trans-unit id="14200e26888a07633c0f177020dce8f3ec7311a6">
5421 <source>You are now logged in as <x id="INTERPOLATION" equiv-text="{{username}}"/>!</source>
5422 <target>您ç¾åœ¨ç™»å…¥ç‚º <x id="INTERPOLATION" equiv-text="{{username}}"/>ï¼</target>
5423 <context-group name="null">
5424 <context context-type="linenumber">1</context>
5425 </context-group>
5426 </trans-unit>
5547 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb"> 5427 <trans-unit id="320c9c3482a0ebe46da42ce9e0cbdc5ba26ea8bb">
5548 <source>Video to import updated.</source> 5428 <source>Video to import updated.</source>
5549 <target>è¦åŒ¯å…¥çš„影片已更新。</target> 5429 <target>è¦åŒ¯å…¥çš„影片已更新。</target>
@@ -5572,13 +5452,6 @@ When you will upload a video in this channel, the video support field will be au
5572 <context context-type="linenumber">1</context> 5452 <context context-type="linenumber">1</context>
5573 </context-group> 5453 </context-group>
5574 </trans-unit> 5454 </trans-unit>
5575 <trans-unit id="321e4419a943044e674beb55b8039f42a9761ca5">
5576 <source>Info</source>
5577 <target>資訊</target>
5578 <context-group name="null">
5579 <context context-type="linenumber">1</context>
5580 </context-group>
5581 </trans-unit>
5582 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9"> 5455 <trans-unit id="c5cb19aeb6447deda40cc1227ceca1359ab955e9">
5583 <source>Upload cancelled</source> 5456 <source>Upload cancelled</source>
5584 <target>å·²å–消上傳</target> 5457 <target>å·²å–消上傳</target>
@@ -5586,13 +5459,6 @@ When you will upload a video in this channel, the video support field will be au
5586 <context context-type="linenumber">1</context> 5459 <context context-type="linenumber">1</context>
5587 </context-group> 5460 </context-group>
5588 </trans-unit> 5461 </trans-unit>
5589 <trans-unit id="c55f41189ac6ad3003cce813245f4508284ed0aa">
5590 <source>We are sorry but PeerTube cannot handle videos &gt; 8GB</source>
5591 <target>我們很抱歉,但 PeerTube 無法處ç†å¤§æ–¼ 8GB 的影片</target>
5592 <context-group name="null">
5593 <context context-type="linenumber">1</context>
5594 </context-group>
5595 </trans-unit>
5596 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee"> 5462 <trans-unit id="a6019e856f511dbe1fe658790c71c594b26930ee">
5597 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source> 5463 <source>Your video quota is exceeded with this video (video size: <x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>, quota: <x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</source>
5598 <target>您的影片é…é¡å·²å› æ­¤å½±ç‰‡è¶…éŽï¼ˆå½±ç‰‡å¤§å°ï¼š<x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>,é…é¡ï¼š<x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target> 5464 <target>您的影片é…é¡å·²å› æ­¤å½±ç‰‡è¶…éŽï¼ˆå½±ç‰‡å¤§å°ï¼š<x id="INTERPOLATION" equiv-text="{{videoSize}}"/>, used: <x id="INTERPOLATION_1" equiv-text="{{videoQuotaUsed}}"/>,é…é¡ï¼š<x id="INTERPOLATION_2" equiv-text="{{videoQuota}}"/>)</target>
diff --git a/client/src/locale/target/iso639_nl_NL.xml b/client/src/locale/target/iso639_nl_NL.xml
index 9c0e2fd9e..b3a4ff541 100644
--- a/client/src/locale/target/iso639_nl_NL.xml
+++ b/client/src/locale/target/iso639_nl_NL.xml
@@ -5,7 +5,7 @@
5 <body> 5 <body>
6 <trans-unit id="Afar"> 6 <trans-unit id="Afar">
7 <source>Afar</source> 7 <source>Afar</source>
8 <target>Afar</target> 8 <target>Ver</target>
9 </trans-unit> 9 </trans-unit>
10 <trans-unit id="Abkhazian"> 10 <trans-unit id="Abkhazian">
11 <source>Abkhazian</source> 11 <source>Abkhazian</source>
@@ -43,6 +43,10 @@
43 <source>Avaric</source> 43 <source>Avaric</source>
44 <target>Avaars</target> 44 <target>Avaars</target>
45 </trans-unit> 45 </trans-unit>
46 <trans-unit id="Kotava">
47 <source>Kotava</source>
48 <target>Kotava</target>
49 </trans-unit>
46 <trans-unit id="Aymara"> 50 <trans-unit id="Aymara">
47 <source>Aymara</source> 51 <source>Aymara</source>
48 <target>Aymara</target> 52 <target>Aymara</target>
@@ -167,6 +171,10 @@
167 <source>English</source> 171 <source>English</source>
168 <target>Engels</target> 172 <target>Engels</target>
169 </trans-unit> 173 </trans-unit>
174 <trans-unit id="Esperanto">
175 <source>Esperanto</source>
176 <target>Esperanto</target>
177 </trans-unit>
170 <trans-unit id="Estonian"> 178 <trans-unit id="Estonian">
171 <source>Estonian</source> 179 <source>Estonian</source>
172 <target>Ests</target> 180 <target>Ests</target>
@@ -311,6 +319,10 @@
311 <source>Javanese</source> 319 <source>Javanese</source>
312 <target>Javaans</target> 320 <target>Javaans</target>
313 </trans-unit> 321 </trans-unit>
322 <trans-unit id="Lojban">
323 <source>Lojban</source>
324 <target>Lojban</target>
325 </trans-unit>
314 <trans-unit id="Japanese"> 326 <trans-unit id="Japanese">
315 <source>Japanese</source> 327 <source>Japanese</source>
316 <target>Japans</target> 328 <target>Japans</target>
@@ -495,6 +507,10 @@
495 <source>Nyanja</source> 507 <source>Nyanja</source>
496 <target>Nyanja</target> 508 <target>Nyanja</target>
497 </trans-unit> 509 </trans-unit>
510 <trans-unit id="Occitan">
511 <source>Occitan</source>
512 <target>Occitan</target>
513 </trans-unit>
498 <trans-unit id="Ojibwa"> 514 <trans-unit id="Ojibwa">
499 <source>Ojibwa</source> 515 <source>Ojibwa</source>
500 <target>Ojibwe</target> 516 <target>Ojibwe</target>
@@ -671,6 +687,10 @@
671 <source>Tigrinya</source> 687 <source>Tigrinya</source>
672 <target>Tigrinya</target> 688 <target>Tigrinya</target>
673 </trans-unit> 689 </trans-unit>
690 <trans-unit id="Klingon">
691 <source>Klingon</source>
692 <target>Klingon</target>
693 </trans-unit>
674 <trans-unit id="Tonga (Tonga Islands)"> 694 <trans-unit id="Tonga (Tonga Islands)">
675 <source>Tonga (Tonga Islands)</source> 695 <source>Tonga (Tonga Islands)</source>
676 <target>Tongaans</target> 696 <target>Tongaans</target>
diff --git a/client/src/locale/target/iso639_pl_PL.xml b/client/src/locale/target/iso639_pl_PL.xml
deleted file mode 100644
index b483f5ce8..000000000
--- a/client/src/locale/target/iso639_pl_PL.xml
+++ /dev/null
@@ -1,695 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!--XLIFF document generated by Zanata. Visit http://zanata.org for more infomation.-->
3<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" xmlns:xyz="urn:appInfo:Items" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd" version="1.1">
4 <file source-language="en-US" datatype="plaintext" original="" target-language="pl-PL">
5 <body>
6 <trans-unit id="Afar">
7 <source>Afar</source>
8 <target>Afar</target>
9 </trans-unit>
10 <trans-unit id="Abkhazian">
11 <source>Abkhazian</source>
12 <target>Abchaski</target>
13 </trans-unit>
14 <trans-unit id="Afrikaans">
15 <source>Afrikaans</source>
16 <target>Afrikaans</target>
17 </trans-unit>
18 <trans-unit id="Akan">
19 <source>Akan</source>
20 <target>Akan</target>
21 </trans-unit>
22 <trans-unit id="Amharic">
23 <source>Amharic</source>
24 <target>Amharski</target>
25 </trans-unit>
26 <trans-unit id="Arabic">
27 <source>Arabic</source>
28 <target>Arabski</target>
29 </trans-unit>
30 <trans-unit id="Aragonese">
31 <source>Aragonese</source>
32 </trans-unit>
33 <trans-unit id="American Sign Language">
34 <source>American Sign Language</source>
35 <target>Amerykański Język Migowy</target>
36 </trans-unit>
37 <trans-unit id="Assamese">
38 <source>Assamese</source>
39 </trans-unit>
40 <trans-unit id="Avaric">
41 <source>Avaric</source>
42 <target>Awarski</target>
43 </trans-unit>
44 <trans-unit id="Kotava">
45 <source>Kotava</source>
46 </trans-unit>
47 <trans-unit id="Aymara">
48 <source>Aymara</source>
49 </trans-unit>
50 <trans-unit id="Azerbaijani">
51 <source>Azerbaijani</source>
52 </trans-unit>
53 <trans-unit id="Bashkir">
54 <source>Bashkir</source>
55 <target>Baszkirski</target>
56 </trans-unit>
57 <trans-unit id="Bambara">
58 <source>Bambara</source>
59 <target>Bambara</target>
60 </trans-unit>
61 <trans-unit id="Belarusian">
62 <source>Belarusian</source>
63 <target>Białoruski</target>
64 </trans-unit>
65 <trans-unit id="Bengali">
66 <source>Bengali</source>
67 <target>Bengalski</target>
68 </trans-unit>
69 <trans-unit id="British Sign Language">
70 <source>British Sign Language</source>
71 <target>Brytyjski Język Migowy</target>
72 </trans-unit>
73 <trans-unit id="Bislama">
74 <source>Bislama</source>
75 <target>Bislama</target>
76 </trans-unit>
77 <trans-unit id="Tibetan">
78 <source>Tibetan</source>
79 <target>Tybetański</target>
80 </trans-unit>
81 <trans-unit id="Bosnian">
82 <source>Bosnian</source>
83 <target>Bośniacki</target>
84 </trans-unit>
85 <trans-unit id="Breton">
86 <source>Breton</source>
87 <target>Bretoński</target>
88 </trans-unit>
89 <trans-unit id="Bulgarian">
90 <source>Bulgarian</source>
91 <target>Bułgarski</target>
92 </trans-unit>
93 <trans-unit id="Brazilian Sign Language">
94 <source>Brazilian Sign Language</source>
95 </trans-unit>
96 <trans-unit id="Catalan">
97 <source>Catalan</source>
98 <target>Kataloński</target>
99 </trans-unit>
100 <trans-unit id="Czech">
101 <source>Czech</source>
102 <target>Czeski</target>
103 </trans-unit>
104 <trans-unit id="Chamorro">
105 <source>Chamorro</source>
106 </trans-unit>
107 <trans-unit id="Chechen">
108 <source>Chechen</source>
109 </trans-unit>
110 <trans-unit id="Chuvash">
111 <source>Chuvash</source>
112 </trans-unit>
113 <trans-unit id="Cornish">
114 <source>Cornish</source>
115 <target>Kornijski</target>
116 </trans-unit>
117 <trans-unit id="Corsican">
118 <source>Corsican</source>
119 <target>Korsykański</target>
120 </trans-unit>
121 <trans-unit id="Cree">
122 <source>Cree</source>
123 <target>Kri</target>
124 </trans-unit>
125 <trans-unit id="Czech Sign Language">
126 <source>Czech Sign Language</source>
127 <target>Czeski Język Migowy</target>
128 </trans-unit>
129 <trans-unit id="Chinese Sign Language">
130 <source>Chinese Sign Language</source>
131 <target>Chiński Język Migowy</target>
132 </trans-unit>
133 <trans-unit id="Welsh">
134 <source>Welsh</source>
135 <target>Walijski</target>
136 </trans-unit>
137 <trans-unit id="Danish">
138 <source>Danish</source>
139 <target>Duński</target>
140 </trans-unit>
141 <trans-unit id="German">
142 <source>German</source>
143 <target>Niemiecki</target>
144 </trans-unit>
145 <trans-unit id="Dhivehi">
146 <source>Dhivehi</source>
147 </trans-unit>
148 <trans-unit id="Danish Sign Language">
149 <source>Danish Sign Language</source>
150 <target>Duński Język Migowy</target>
151 </trans-unit>
152 <trans-unit id="Dzongkha">
153 <source>Dzongkha</source>
154 <target>Dzongkha</target>
155 </trans-unit>
156 <trans-unit id="Modern Greek (1453-)">
157 <source>Modern Greek (1453-)</source>
158 <target>Nowogrecki (1453-)</target>
159 </trans-unit>
160 <trans-unit id="English">
161 <source>English</source>
162 <target>Angielski</target>
163 </trans-unit>
164 <trans-unit id="Esperanto">
165 <source>Esperanto</source>
166 </trans-unit>
167 <trans-unit id="Estonian">
168 <source>Estonian</source>
169 <target>Estoński</target>
170 </trans-unit>
171 <trans-unit id="Basque">
172 <source>Basque</source>
173 <target>Baskijski</target>
174 </trans-unit>
175 <trans-unit id="Ewe">
176 <source>Ewe</source>
177 <target>Ewe</target>
178 </trans-unit>
179 <trans-unit id="Faroese">
180 <source>Faroese</source>
181 </trans-unit>
182 <trans-unit id="Persian">
183 <source>Persian</source>
184 <target>Perski</target>
185 </trans-unit>
186 <trans-unit id="Fijian">
187 <source>Fijian</source>
188 <target>Fidżyjski</target>
189 </trans-unit>
190 <trans-unit id="Finnish">
191 <source>Finnish</source>
192 <target>Fiński</target>
193 </trans-unit>
194 <trans-unit id="French">
195 <source>French</source>
196 <target>Francuski</target>
197 </trans-unit>
198 <trans-unit id="Western Frisian">
199 <source>Western Frisian</source>
200 </trans-unit>
201 <trans-unit id="French Sign Language">
202 <source>French Sign Language</source>
203 <target>Francuski Język Migowy</target>
204 </trans-unit>
205 <trans-unit id="Fulah">
206 <source>Fulah</source>
207 <target>Ful</target>
208 </trans-unit>
209 <trans-unit id="Scottish Gaelic">
210 <source>Scottish Gaelic</source>
211 </trans-unit>
212 <trans-unit id="Irish">
213 <source>Irish</source>
214 <target>Irlandzki</target>
215 </trans-unit>
216 <trans-unit id="Galician">
217 <source>Galician</source>
218 <target>Galicyjski</target>
219 </trans-unit>
220 <trans-unit id="Manx">
221 <source>Manx</source>
222 </trans-unit>
223 <trans-unit id="Guarani">
224 <source>Guarani</source>
225 </trans-unit>
226 <trans-unit id="German Sign Language">
227 <source>German Sign Language</source>
228 <target>Niemiecki Język Migowy</target>
229 </trans-unit>
230 <trans-unit id="Gujarati">
231 <source>Gujarati</source>
232 </trans-unit>
233 <trans-unit id="Haitian">
234 <source>Haitian</source>
235 </trans-unit>
236 <trans-unit id="Hausa">
237 <source>Hausa</source>
238 <target>Hausa</target>
239 </trans-unit>
240 <trans-unit id="Serbo-Croatian">
241 <source>Serbo-Croatian</source>
242 <target>Serbsko-Chorwacki</target>
243 </trans-unit>
244 <trans-unit id="Hebrew">
245 <source>Hebrew</source>
246 </trans-unit>
247 <trans-unit id="Herero">
248 <source>Herero</source>
249 </trans-unit>
250 <trans-unit id="Hindi">
251 <source>Hindi</source>
252 <target>Hindi</target>
253 </trans-unit>
254 <trans-unit id="Hiri Motu">
255 <source>Hiri Motu</source>
256 </trans-unit>
257 <trans-unit id="Croatian">
258 <source>Croatian</source>
259 <target>Chorwacki</target>
260 </trans-unit>
261 <trans-unit id="Hungarian">
262 <source>Hungarian</source>
263 <target>Węgierski</target>
264 </trans-unit>
265 <trans-unit id="Armenian">
266 <source>Armenian</source>
267 <target>Ormański</target>
268 </trans-unit>
269 <trans-unit id="Igbo">
270 <source>Igbo</source>
271 <target>Igbo</target>
272 </trans-unit>
273 <trans-unit id="Sichuan Yi">
274 <source>Sichuan Yi</source>
275 </trans-unit>
276 <trans-unit id="Inuktitut">
277 <source>Inuktitut</source>
278 </trans-unit>
279 <trans-unit id="Indonesian">
280 <source>Indonesian</source>
281 <target>Indonezyjski</target>
282 </trans-unit>
283 <trans-unit id="Inupiaq">
284 <source>Inupiaq</source>
285 </trans-unit>
286 <trans-unit id="Icelandic">
287 <source>Icelandic</source>
288 <target>Islandzki</target>
289 </trans-unit>
290 <trans-unit id="Italian">
291 <source>Italian</source>
292 <target>WÅ‚oski</target>
293 </trans-unit>
294 <trans-unit id="Javanese">
295 <source>Javanese</source>
296 <target>Jawajski</target>
297 </trans-unit>
298 <trans-unit id="Lojban">
299 <source>Lojban</source>
300 </trans-unit>
301 <trans-unit id="Japanese">
302 <source>Japanese</source>
303 <target>Japoński</target>
304 </trans-unit>
305 <trans-unit id="Japanese Sign Language">
306 <source>Japanese Sign Language</source>
307 <target>Japoński Język Migowy</target>
308 </trans-unit>
309 <trans-unit id="Kalaallisut">
310 <source>Kalaallisut</source>
311 </trans-unit>
312 <trans-unit id="Kannada">
313 <source>Kannada</source>
314 </trans-unit>
315 <trans-unit id="Kashmiri">
316 <source>Kashmiri</source>
317 </trans-unit>
318 <trans-unit id="Georgian">
319 <source>Georgian</source>
320 </trans-unit>
321 <trans-unit id="Kanuri">
322 <source>Kanuri</source>
323 </trans-unit>
324 <trans-unit id="Kazakh">
325 <source>Kazakh</source>
326 </trans-unit>
327 <trans-unit id="Khmer">
328 <source>Khmer</source>
329 </trans-unit>
330 <trans-unit id="Kikuyu">
331 <source>Kikuyu</source>
332 </trans-unit>
333 <trans-unit id="Kinyarwanda">
334 <source>Kinyarwanda</source>
335 </trans-unit>
336 <trans-unit id="Kirghiz">
337 <source>Kirghiz</source>
338 </trans-unit>
339 <trans-unit id="Komi">
340 <source>Komi</source>
341 <target>Komi</target>
342 </trans-unit>
343 <trans-unit id="Kongo">
344 <source>Kongo</source>
345 <target>Kongo</target>
346 </trans-unit>
347 <trans-unit id="Korean">
348 <source>Korean</source>
349 <target>Koreański</target>
350 </trans-unit>
351 <trans-unit id="Kuanyama">
352 <source>Kuanyama</source>
353 </trans-unit>
354 <trans-unit id="Kurdish">
355 <source>Kurdish</source>
356 <target>Kurdyjski</target>
357 </trans-unit>
358 <trans-unit id="Lao">
359 <source>Lao</source>
360 <target>Laotański</target>
361 </trans-unit>
362 <trans-unit id="Latvian">
363 <source>Latvian</source>
364 <target>Åotewski</target>
365 </trans-unit>
366 <trans-unit id="Limburgan">
367 <source>Limburgan</source>
368 </trans-unit>
369 <trans-unit id="Lingala">
370 <source>Lingala</source>
371 </trans-unit>
372 <trans-unit id="Lithuanian">
373 <source>Lithuanian</source>
374 <target>Litewski</target>
375 </trans-unit>
376 <trans-unit id="Luxembourgish">
377 <source>Luxembourgish</source>
378 <target>Luksemburski</target>
379 </trans-unit>
380 <trans-unit id="Luba-Katanga">
381 <source>Luba-Katanga</source>
382 </trans-unit>
383 <trans-unit id="Ganda">
384 <source>Ganda</source>
385 </trans-unit>
386 <trans-unit id="Marshallese">
387 <source>Marshallese</source>
388 </trans-unit>
389 <trans-unit id="Malayalam">
390 <source>Malayalam</source>
391 </trans-unit>
392 <trans-unit id="Marathi">
393 <source>Marathi</source>
394 </trans-unit>
395 <trans-unit id="Macedonian">
396 <source>Macedonian</source>
397 </trans-unit>
398 <trans-unit id="Malagasy">
399 <source>Malagasy</source>
400 </trans-unit>
401 <trans-unit id="Maltese">
402 <source>Maltese</source>
403 </trans-unit>
404 <trans-unit id="Mongolian">
405 <source>Mongolian</source>
406 </trans-unit>
407 <trans-unit id="Maori">
408 <source>Maori</source>
409 </trans-unit>
410 <trans-unit id="Malay (macrolanguage)">
411 <source>Malay (macrolanguage)</source>
412 </trans-unit>
413 <trans-unit id="Burmese">
414 <source>Burmese</source>
415 </trans-unit>
416 <trans-unit id="Nauru">
417 <source>Nauru</source>
418 <target>Naurański</target>
419 </trans-unit>
420 <trans-unit id="Navajo">
421 <source>Navajo</source>
422 </trans-unit>
423 <trans-unit id="South Ndebele">
424 <source>South Ndebele</source>
425 </trans-unit>
426 <trans-unit id="North Ndebele">
427 <source>North Ndebele</source>
428 </trans-unit>
429 <trans-unit id="Ndonga">
430 <source>Ndonga</source>
431 </trans-unit>
432 <trans-unit id="Nepali (macrolanguage)">
433 <source>Nepali (macrolanguage)</source>
434 </trans-unit>
435 <trans-unit id="Dutch">
436 <source>Dutch</source>
437 <target>Holenderski</target>
438 </trans-unit>
439 <trans-unit id="Norwegian Nynorsk">
440 <source>Norwegian Nynorsk</source>
441 <target>Norweski Nynorsk</target>
442 </trans-unit>
443 <trans-unit id="Norwegian Bokmål">
444 <source>Norwegian Bokmål</source>
445 <target>Norweski Bokmål</target>
446 </trans-unit>
447 <trans-unit id="Norwegian">
448 <source>Norwegian</source>
449 <target>Norweski</target>
450 </trans-unit>
451 <trans-unit id="Nyanja">
452 <source>Nyanja</source>
453 </trans-unit>
454 <trans-unit id="Occitan">
455 <source>Occitan</source>
456 </trans-unit>
457 <trans-unit id="Ojibwa">
458 <source>Ojibwa</source>
459 </trans-unit>
460 <trans-unit id="Oriya (macrolanguage)">
461 <source>Oriya (macrolanguage)</source>
462 </trans-unit>
463 <trans-unit id="Oromo">
464 <source>Oromo</source>
465 <target>Oromo</target>
466 </trans-unit>
467 <trans-unit id="Ossetian">
468 <source>Ossetian</source>
469 </trans-unit>
470 <trans-unit id="Panjabi">
471 <source>Panjabi</source>
472 </trans-unit>
473 <trans-unit id="Pakistan Sign Language">
474 <source>Pakistan Sign Language</source>
475 </trans-unit>
476 <trans-unit id="Polish">
477 <source>Polish</source>
478 <target>Polski</target>
479 </trans-unit>
480 <trans-unit id="Portuguese">
481 <source>Portuguese</source>
482 <target>Portugalski</target>
483 </trans-unit>
484 <trans-unit id="Pushto">
485 <source>Pushto</source>
486 <target>Paszto</target>
487 </trans-unit>
488 <trans-unit id="Quechua">
489 <source>Quechua</source>
490 </trans-unit>
491 <trans-unit id="Romansh">
492 <source>Romansh</source>
493 <target>Romansz</target>
494 </trans-unit>
495 <trans-unit id="Romanian">
496 <source>Romanian</source>
497 <target>Rumuński</target>
498 </trans-unit>
499 <trans-unit id="Russian Sign Language">
500 <source>Russian Sign Language</source>
501 <target>Rosyjski Język Migowy</target>
502 </trans-unit>
503 <trans-unit id="Rundi">
504 <source>Rundi</source>
505 <target>Rundi</target>
506 </trans-unit>
507 <trans-unit id="Russian">
508 <source>Russian</source>
509 <target>Rosyjski</target>
510 </trans-unit>
511 <trans-unit id="Sango">
512 <source>Sango</source>
513 <target>Sango</target>
514 </trans-unit>
515 <trans-unit id="Saudi Arabian Sign Language">
516 <source>Saudi Arabian Sign Language</source>
517 </trans-unit>
518 <trans-unit id="South African Sign Language">
519 <source>South African Sign Language</source>
520 </trans-unit>
521 <trans-unit id="Sinhala">
522 <source>Sinhala</source>
523 </trans-unit>
524 <trans-unit id="Slovak">
525 <source>Slovak</source>
526 <target>SÅ‚owacki</target>
527 </trans-unit>
528 <trans-unit id="Slovenian">
529 <source>Slovenian</source>
530 <target>Słoweński</target>
531 </trans-unit>
532 <trans-unit id="Northern Sami">
533 <source>Northern Sami</source>
534 </trans-unit>
535 <trans-unit id="Samoan">
536 <source>Samoan</source>
537 <target>Samoański</target>
538 </trans-unit>
539 <trans-unit id="Shona">
540 <source>Shona</source>
541 <target>Shona</target>
542 </trans-unit>
543 <trans-unit id="Sindhi">
544 <source>Sindhi</source>
545 <target>Sindhi</target>
546 </trans-unit>
547 <trans-unit id="Somali">
548 <source>Somali</source>
549 <target>Somalijski</target>
550 </trans-unit>
551 <trans-unit id="Southern Sotho">
552 <source>Southern Sotho</source>
553 </trans-unit>
554 <trans-unit id="Spanish">
555 <source>Spanish</source>
556 <target>Hiszpański</target>
557 </trans-unit>
558 <trans-unit id="Albanian">
559 <source>Albanian</source>
560 </trans-unit>
561 <trans-unit id="Sardinian">
562 <source>Sardinian</source>
563 </trans-unit>
564 <trans-unit id="Serbian">
565 <source>Serbian</source>
566 <target>Serbski</target>
567 </trans-unit>
568 <trans-unit id="Swati">
569 <source>Swati</source>
570 </trans-unit>
571 <trans-unit id="Sundanese">
572 <source>Sundanese</source>
573 </trans-unit>
574 <trans-unit id="Swahili (macrolanguage)">
575 <source>Swahili (macrolanguage)</source>
576 </trans-unit>
577 <trans-unit id="Swedish">
578 <source>Swedish</source>
579 <target>Szwedzki</target>
580 </trans-unit>
581 <trans-unit id="Swedish Sign Language">
582 <source>Swedish Sign Language</source>
583 <target>Szwedzki Język Migowy</target>
584 </trans-unit>
585 <trans-unit id="Tahitian">
586 <source>Tahitian</source>
587 </trans-unit>
588 <trans-unit id="Tamil">
589 <source>Tamil</source>
590 <target>Tamilski</target>
591 </trans-unit>
592 <trans-unit id="Tatar">
593 <source>Tatar</source>
594 <target>Tatarski</target>
595 </trans-unit>
596 <trans-unit id="Telugu">
597 <source>Telugu</source>
598 <target>Telugu</target>
599 </trans-unit>
600 <trans-unit id="Tajik">
601 <source>Tajik</source>
602 <target>Tadżycki</target>
603 </trans-unit>
604 <trans-unit id="Tagalog">
605 <source>Tagalog</source>
606 <target>Tagalski</target>
607 </trans-unit>
608 <trans-unit id="Thai">
609 <source>Thai</source>
610 <target>Tajski</target>
611 </trans-unit>
612 <trans-unit id="Tigrinya">
613 <source>Tigrinya</source>
614 </trans-unit>
615 <trans-unit id="Klingon">
616 <source>Klingon</source>
617 </trans-unit>
618 <trans-unit id="Tonga (Tonga Islands)">
619 <source>Tonga (Tonga Islands)</source>
620 </trans-unit>
621 <trans-unit id="Tswana">
622 <source>Tswana</source>
623 </trans-unit>
624 <trans-unit id="Tsonga">
625 <source>Tsonga</source>
626 </trans-unit>
627 <trans-unit id="Turkmen">
628 <source>Turkmen</source>
629 <target>Turkmeński</target>
630 </trans-unit>
631 <trans-unit id="Turkish">
632 <source>Turkish</source>
633 <target>Turecki</target>
634 </trans-unit>
635 <trans-unit id="Twi">
636 <source>Twi</source>
637 <target>Twi</target>
638 </trans-unit>
639 <trans-unit id="Uighur">
640 <source>Uighur</source>
641 </trans-unit>
642 <trans-unit id="Ukrainian">
643 <source>Ukrainian</source>
644 <target>Ukraiński</target>
645 </trans-unit>
646 <trans-unit id="Urdu">
647 <source>Urdu</source>
648 <target>Urdu</target>
649 </trans-unit>
650 <trans-unit id="Uzbek">
651 <source>Uzbek</source>
652 <target>Uzbecki</target>
653 </trans-unit>
654 <trans-unit id="Venda">
655 <source>Venda</source>
656 <target>Venda</target>
657 </trans-unit>
658 <trans-unit id="Vietnamese">
659 <source>Vietnamese</source>
660 <target>Wietnamski</target>
661 </trans-unit>
662 <trans-unit id="Walloon">
663 <source>Walloon</source>
664 <target>Waloński</target>
665 </trans-unit>
666 <trans-unit id="Wolof">
667 <source>Wolof</source>
668 <target>Wolof</target>
669 </trans-unit>
670 <trans-unit id="Xhosa">
671 <source>Xhosa</source>
672 <target>Xhosa</target>
673 </trans-unit>
674 <trans-unit id="Yiddish">
675 <source>Yiddish</source>
676 <target>Jidysz</target>
677 </trans-unit>
678 <trans-unit id="Yoruba">
679 <source>Yoruba</source>
680 <target>Joruba</target>
681 </trans-unit>
682 <trans-unit id="Zhuang">
683 <source>Zhuang</source>
684 <target>Zhuang</target>
685 </trans-unit>
686 <trans-unit id="Chinese">
687 <source>Chinese</source>
688 <target>Chiński</target>
689 </trans-unit>
690 <trans-unit id="Zulu">
691 <source>Zulu</source>
692 <target>Zulu</target>
693 </trans-unit>
694 </body>
695 </file></xliff> \ No newline at end of file
diff --git a/client/src/locale/target/player_ar_001.xml b/client/src/locale/target/player_ar_001.xml
index f81c084d4..4e3a12ad7 100644
--- a/client/src/locale/target/player_ar_001.xml
+++ b/client/src/locale/target/player_ar_001.xml
@@ -81,7 +81,7 @@
81 </trans-unit> 81 </trans-unit>
82 <trans-unit id="Subtitles"> 82 <trans-unit id="Subtitles">
83 <source>Subtitles</source> 83 <source>Subtitles</source>
84 <target>ترجمة</target> 84 <target>الترجمات</target>
85 </trans-unit> 85 </trans-unit>
86 <trans-unit id="subtitles off"> 86 <trans-unit id="subtitles off">
87 <source>subtitles off</source> 87 <source>subtitles off</source>
diff --git a/client/src/locale/target/player_it_IT.json b/client/src/locale/target/player_it_IT.json
new file mode 100644
index 000000000..add193bfe
--- /dev/null
+++ b/client/src/locale/target/player_it_IT.json
@@ -0,0 +1 @@
{"Audio Player":"Riproduttore Audio","Video Player":"Riproduttore Video","Play":"Play","Pause":"Pausa","Replay":"Replay","Current Time":"Posizione attuale","Duration":"Durata","Remaining Time":"Tempo rimanente","Stream Type":"Tipo dello Streaming","LIVE":"LIVE","Loaded":"Caricato","Progress":"Stato","Progress Bar":"Barra di progresso","progress bar timing: currentTime={1} duration={2}":"{1} di {2}","Fullscreen":"Schermo intero","Non-Fullscreen":"Chiudi schermo intero","Mute":"Muto","Unmute":"Audio ","Playback Rate":"Velocità di riproduzione","Subtitles":"Sottotitoli","subtitles off":"Senza sottotitoli","Captions":"Sottotitoli per non udenti","captions off":"Senza sottotitoli per non udenti","Chapters":"Capitoli","Descriptions":"Descrizioni","descriptions off":"Descrizioni disattivate","Audio Track":"Traccia Audio","Volume Level":"Volume","You aborted the media playback":"La riproduzione del filmato è stata interrotta","A network error caused the media download to fail part-way.":"Il download del filmato è stato interrotto a causa di un problema rete.","The media could not be loaded, either because the server or network failed or because the format is not supported.":"Il filmato non può essere caricato a causa di un errore nel server o nella rete o perché il formato non viene supportato.","The media playback was aborted due to a corruption problem or because the media used features your browser did not support.":"La riproduzione del filmato è stata interrotta a causa di un file danneggiato o per l’utilizzo di impostazioni non supportate dal browser.","No compatible source was found for this media.":"Non ci sono fonti compatibili per questo filmato.","The media is encrypted and we do not have the keys to decrypt it.":"Il filmato è crittato e non disponiamo delle chiavi per decrittarlo","Play Video":"Riproduci Video","Close":"Chiudi","Close Modal Dialog":"Chiudi finestra di dialogo","Modal Window":"Finestra di dialogo","This is a modal window":"Questa è una finestra di dialogo","This modal can be closed by pressing the Escape key or activating the close button.":"Questa finestra di dialogo può essere chiusa premendo Esc o cliccando sul pulsante chiudi.",", opens captions settings dialog":", apri la finestra delle impostazioni delle didascalie",", opens subtitles settings dialog":", apri la finestra delle impostazioni dei sottotitoli",", opens descriptions settings dialog":", apri la finestra delle impostazioni delle descrizioni",", selected":", selezionati","captions settings":"impostazioni delle didascalie","subtitles settings":"impostazioni dei sottotitoli","descriptions settings":"impostazioni delle descrizioni","Text":"Testo","White":"Bianco","Black":"Nero","Red":"Rosso","Green":"Verde","Blue":"Blu","Yellow":"Giallo","Magenta":"Magenta","Cyan":"Ciano","Background":"Sfondo","Window":"Finestra","Transparent":"Trasparente","Semi-Transparent":"Semi-Trasparente","Opaque":"Opaco","Font Size":"Dimensione del Testo","Text Edge Style":"Stile dei Bordi del Testo","None":"Nessuno","Raised":"In Rilievo","Depressed":"Incavato","Uniform":"Uniforme","Dropshadow":"Ombreggiatura","Font Family":"Stile del Testo","Proportional Sans-Serif":"Senza Grazie Proporzionale","Monospace Sans-Serif":"Senza Grazie Monospazio","Proportional Serif":"Con Grazie Proporzionale","Monospace Serif":"Con Grazie Monospazio","Casual":"Casuale","Script":"Codice","Small Caps":"Maiuscoletto","Reset":"Ripristina","restore all settings to the default values":"ripristina tutte le impostazioni ai valori predefiniti","Done":"Fatto","Caption Settings Dialog":"Finestra delle Impostazioni dei Sottotitoli","Beginning of dialog window. Escape will cancel and close the window.":"Apertura della finestra di dialogo. Premendo ESC si annullerà e si chiuderà la finestra.","End of dialog window.":"Chiusura della finestra di dialogo.","{1} is loading.":"{1} è in caricamento.","Quality":"Qualità","Auto":"Auto","Speed":"Velocità","Subtitles/CC":"Sottotitoli/CC","peers":"nodi","Go to the video page":"Vai alla pagina del video","Settings":"Impostazioni","Uses P2P, others may know you are watching this video.":"Usa P2P, altri potrebbero sapere che stai guardando questo video.","Copy the video URL":"Copia l'URL del video","Copy the video URL at the current time":"Copia l'URL del video della posizione corrente","Copy embed code":"Copia il codice per incorporare"} \ No newline at end of file
diff --git a/client/src/locale/target/player_nl_NL.xml b/client/src/locale/target/player_nl_NL.xml
index 5b689f2a2..45bc76a55 100644
--- a/client/src/locale/target/player_nl_NL.xml
+++ b/client/src/locale/target/player_nl_NL.xml
@@ -347,6 +347,10 @@
347 <source>Speed</source> 347 <source>Speed</source>
348 <target>Snelheid</target> 348 <target>Snelheid</target>
349 </trans-unit> 349 </trans-unit>
350 <trans-unit id="Subtitles/CC">
351 <source>Subtitles/CC</source>
352 <target>Ondertiteling/CC</target>
353 </trans-unit>
350 <trans-unit id="peers"> 354 <trans-unit id="peers">
351 <source>peers</source> 355 <source>peers</source>
352 <target>peers</target> 356 <target>peers</target>
diff --git a/client/src/locale/target/player_pl_PL.json b/client/src/locale/target/player_pl_PL.json
new file mode 100644
index 000000000..2178a137d
--- /dev/null
+++ b/client/src/locale/target/player_pl_PL.json
@@ -0,0 +1 @@
{"Audio Player":"Odtwarzacz audio","Video Player":"Odtwarzacz wideo","Play":"Odtwórz","Pause":"Wstrzymaj","Replay":"Powtórz","Current Time":"Obecny czas","Duration":"Czas trwania","Remaining Time":"Pozostały czas","Stream Type":"Rodzaj strumienia","LIVE":"NA ŻYWO","Loaded":"Załadowano","Progress":"Postęp","Progress Bar":"Pasek postępu","progress bar timing: currentTime={1} duration={2}":"{1} z {2}","Fullscreen":"Pełny ekran","Non-Fullscreen":"Bez pełnego ekranu","Mute":"Wycisz","Unmute":"Cofnij wyciszenie","Playback Rate":"Szybkość odtwarzania","Subtitles":"Napisy","subtitles off":"napisy są wyłączone","Captions":"CC","captions off":"CC są wyłączone","Chapters":"Rozdziały","Descriptions":"Opisy","descriptions off":"opisy są wyłączone","Audio Track":"Ścieżka dźwiękowa","Volume Level":"Poziom głośności","You aborted the media playback":"Przerwałeś odtwarzanie zawartości mulimedialnej","A network error caused the media download to fail part-way.":"Błąd sieci spowodował, że zawartość multimedialna została pobrana tylko częściowo.","The media could not be loaded, either because the server or network failed or because the format is not supported.":"Nie udało się załadować zawartości multimedialnej z powodu błędy sieci lub serwera lub ponieważ format nie jest obsługiwany.","The media playback was aborted due to a corruption problem or because the media used features your browser did not support.":"Odtwarzanie zostało przerwane ze względu na uszkodzenie pliku lub przez brak wsparcia funkcji multimediów przez Twoją przeglądarkę.","No compatible source was found for this media.":"Nie znaleziono kompatybilnego źródła dla tego media.","The media is encrypted and we do not have the keys to decrypt it.":"Zawartość multimedialna jest zaszyfrowana, a klucz do jej odszyfrowania jest nieznany.","Play Video":"Odtwórz film","Close":"Zamknij","Close Modal Dialog":"Zamknij okno modalne","Modal Window":"Okno modalne","This is a modal window":"To jest okno modalne","This modal can be closed by pressing the Escape key or activating the close button.":"To okno może zostać zamknięte klawiszem Escape lub przyciskiem zamykania.",", opens captions settings dialog":", otwiera okno ustawień CC",", opens subtitles settings dialog":", otwiera okno ustawień napisów",", opens descriptions settings dialog":", otwiera okno ustawień opisów",", selected":", zaznaczone","captions settings":"ustawienia CC","subtitles settings":"ustawienia napisów","descriptions settings":"ustawienia opisów","Text":"Tekst","White":"Biały","Black":"Czarny","Red":"Czerwony","Green":"Zielony","Blue":"Niebieski","Yellow":"Żółty","Magenta":"Magenta","Cyan":"Cyjanowy","Background":"Tło","Window":"Okno","Transparent":"Przezroczyste","Semi-Transparent":"Półprzezroczyste","Opaque":"Widoczne","Font Size":"Rozmiar czcionki","Text Edge Style":"Styl krawędzi tekstu","None":"Brak","Raised":"Wypukłe","Depressed":"Wgłębione","Uniform":"Jednolity","Dropshadow":"Cień","Font Family":"Rodzina czcionek","Proportional Sans-Serif":"Proporcjonalne bezszeryfowe","Monospace Sans-Serif":"Bezszeryfowe o stałej szerokości","Proportional Serif":"Proporcjonalne szeryfowe","Monospace Serif":"Szeryfowe o stałej szerokości","Casual":"Ozdobne","Script":"Pismo odręczne","Small Caps":"Kapitaliki","Reset":"Resetuj","restore all settings to the default values":"przywróć wszystkie ustawienia do wartości domyślnych","Done":"Gotowe","Caption Settings Dialog":"Okno ustawień napisów","Beginning of dialog window. Escape will cancel and close the window.":"Początek okna dialogowego. Przycisk Escape anuluje i zamknie okno.","End of dialog window.":"Koniec okna dialogowego.","{1} is loading.":"{1} ładuje się.","Quality":"Jakość","Auto":"Automatyczna","Speed":"Prędkość","Subtitles/CC":"Napisy/CC","peers":"peers","Go to the video page":"Przejdź na stronę filmu","Settings":"Ustawienia","Uses P2P, others may know you are watching this video.":"Korzysta z P2P, inni mogą dowiedzieć się, że oglądasz ten film.","Copy the video URL":"Skopiuj adres URL filmu","Copy the video URL at the current time":"Skopiuj adres URL filmu z obecnym czasem","Copy embed code":"Skopiuj kod do osadzenia"} \ No newline at end of file
diff --git a/client/src/locale/target/player_pl_PL.xml b/client/src/locale/target/player_pl_PL.xml
deleted file mode 100644
index 2affa5948..000000000
--- a/client/src/locale/target/player_pl_PL.xml
+++ /dev/null
@@ -1,383 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!--XLIFF document generated by Zanata. Visit http://zanata.org for more infomation.-->
3<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" xmlns:xyz="urn:appInfo:Items" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd" version="1.1">
4 <file source-language="en-US" datatype="plaintext" original="" target-language="pl-PL">
5 <body>
6 <trans-unit id="Audio Player">
7 <source>Audio Player</source>
8 <target>Odtwarzacz audio</target>
9 </trans-unit>
10 <trans-unit id="Video Player">
11 <source>Video Player</source>
12 <target>Odtwarzacz wideo</target>
13 </trans-unit>
14 <trans-unit id="Play">
15 <source>Play</source>
16 <target>Odtwórz</target>
17 </trans-unit>
18 <trans-unit id="Pause">
19 <source>Pause</source>
20 <target>Wstrzymaj</target>
21 </trans-unit>
22 <trans-unit id="Replay">
23 <source>Replay</source>
24 <target>Powtórz</target>
25 </trans-unit>
26 <trans-unit id="Current Time">
27 <source>Current Time</source>
28 <target>Obecny czas</target>
29 </trans-unit>
30 <trans-unit id="Duration">
31 <source>Duration</source>
32 <target>Czas trwania</target>
33 </trans-unit>
34 <trans-unit id="Remaining Time">
35 <source>Remaining Time</source>
36 <target>Pozostały czas</target>
37 </trans-unit>
38 <trans-unit id="Stream Type">
39 <source>Stream Type</source>
40 <target>Rodzaj strumienia</target>
41 </trans-unit>
42 <trans-unit id="LIVE">
43 <source>LIVE</source>
44 <target>NA ŻYWO</target>
45 </trans-unit>
46 <trans-unit id="Loaded">
47 <source>Loaded</source>
48 <target>Załadowano</target>
49 </trans-unit>
50 <trans-unit id="Progress">
51 <source>Progress</source>
52 <target>Postęp</target>
53 </trans-unit>
54 <trans-unit id="Progress Bar">
55 <source>Progress Bar</source>
56 <target>Pasek postępu</target>
57 </trans-unit>
58 <trans-unit id="progress bar timing: currentTime={1} duration={2}">
59 <source>{1} of {2}</source>
60 <target>{1} z {2}</target>
61 </trans-unit>
62 <trans-unit id="Fullscreen">
63 <source>Fullscreen</source>
64 <target>Pełny ekran</target>
65 </trans-unit>
66 <trans-unit id="Non-Fullscreen">
67 <source>Non-Fullscreen</source>
68 <target>Bez pełnego ekranu</target>
69 </trans-unit>
70 <trans-unit id="Mute">
71 <source>Mute</source>
72 <target>Wycisz</target>
73 </trans-unit>
74 <trans-unit id="Unmute">
75 <source>Unmute</source>
76 <target>Cofnij wyciszenie</target>
77 </trans-unit>
78 <trans-unit id="Playback Rate">
79 <source>Playback Rate</source>
80 <target>Szybkość odtwarzania</target>
81 </trans-unit>
82 <trans-unit id="Subtitles">
83 <source>Subtitles</source>
84 <target>Napisy</target>
85 </trans-unit>
86 <trans-unit id="subtitles off">
87 <source>subtitles off</source>
88 <target>napisy są wyłączone</target>
89 </trans-unit>
90 <trans-unit id="Captions">
91 <source>Captions</source>
92 <target>CC</target>
93 </trans-unit>
94 <trans-unit id="captions off">
95 <source>captions off</source>
96 <target>CC są wyłączone</target>
97 </trans-unit>
98 <trans-unit id="Chapters">
99 <source>Chapters</source>
100 <target>Rozdziały</target>
101 </trans-unit>
102 <trans-unit id="Descriptions">
103 <source>Descriptions</source>
104 <target>Opisy</target>
105 </trans-unit>
106 <trans-unit id="descriptions off">
107 <source>descriptions off</source>
108 <target>opisy są wyłączone</target>
109 </trans-unit>
110 <trans-unit id="Audio Track">
111 <source>Audio Track</source>
112 <target>Ścieżka dźwiękowa</target>
113 </trans-unit>
114 <trans-unit id="Volume Level">
115 <source>Volume Level</source>
116 <target>Poziom głośności</target>
117 </trans-unit>
118 <trans-unit id="You aborted the media playback">
119 <source>You aborted the media playback</source>
120 <target>Przerwałeś odtwarzanie zawartości mulimedialnej</target>
121 </trans-unit>
122 <trans-unit id="A network error caused the media download to fail part-way.">
123 <source>A network error caused the media download to fail part-way.</source>
124 <target>Błąd sieci spowodował, że zawartość multimedialna została pobrana tylko częściowo.</target>
125 </trans-unit>
126 <trans-unit id="The media could not be loaded, either because the server or network failed or because the format is not supported.">
127 <source>The media could not be loaded, either because the server or network failed or because the format is not supported.</source>
128 <target>Nie udało się załadować zawartości multimedialnej z powodu błędy sieci lub serwera lub ponieważ format nie jest obsługiwany.</target>
129 </trans-unit>
130 <trans-unit id="The media playback was aborted due to a corruption problem or because the media used features your browser did not support.">
131 <source>The media playback was aborted due to a corruption problem or because the media used features your browser did not support.</source>
132 <target>Odtwarzanie zostało przerwane ze względu na uszkodzenie pliku lub przez brak wsparcia funkcji multimediów przez Twoją przeglądarkę.</target>
133 </trans-unit>
134 <trans-unit id="No compatible source was found for this media.">
135 <source>No compatible source was found for this media.</source>
136 <target>Nie znaleziono kompatybilnego źródła dla tego media.</target>
137 </trans-unit>
138 <trans-unit id="The media is encrypted and we do not have the keys to decrypt it.">
139 <source>The media is encrypted and we do not have the keys to decrypt it.</source>
140 <target>Zawartość multimedialna jest zaszyfrowana, a klucz do jej odszyfrowania jest nieznany.</target>
141 </trans-unit>
142 <trans-unit id="Play Video">
143 <source>Play Video</source>
144 <target>Odtwórz film</target>
145 </trans-unit>
146 <trans-unit id="Close">
147 <source>Close</source>
148 <target>Zamknij</target>
149 </trans-unit>
150 <trans-unit id="Close Modal Dialog">
151 <source>Close Modal Dialog</source>
152 <target>Zamknij okno modalne</target>
153 </trans-unit>
154 <trans-unit id="Modal Window">
155 <source>Modal Window</source>
156 <target>Okno modalne</target>
157 </trans-unit>
158 <trans-unit id="This is a modal window">
159 <source>This is a modal window</source>
160 <target>To jest okno modalne</target>
161 </trans-unit>
162 <trans-unit id="This modal can be closed by pressing the Escape key or activating the close button.">
163 <source>This modal can be closed by pressing the Escape key or activating the close button.</source>
164 <target>To okno może zostać zamknięte klawiszem Escape lub przyciskiem zamykania.</target>
165 </trans-unit>
166 <trans-unit id=", opens captions settings dialog">
167 <source>, opens captions settings dialog</source>
168 <target>, otwiera okno ustawień CC</target>
169 </trans-unit>
170 <trans-unit id=", opens subtitles settings dialog">
171 <source>, opens subtitles settings dialog</source>
172 <target>, otwiera okno ustawień napisów</target>
173 </trans-unit>
174 <trans-unit id=", opens descriptions settings dialog">
175 <source>, opens descriptions settings dialog</source>
176 <target>, otwiera okno ustawień opisów</target>
177 </trans-unit>
178 <trans-unit id=", selected">
179 <source>, selected</source>
180 <target>, zaznaczone</target>
181 </trans-unit>
182 <trans-unit id="captions settings">
183 <source>captions settings</source>
184 <target>ustawienia CC</target>
185 </trans-unit>
186 <trans-unit id="subtitles settings">
187 <source>subititles settings</source>
188 <target>ustawienia napisów</target>
189 </trans-unit>
190 <trans-unit id="descriptions settings">
191 <source>descriptions settings</source>
192 <target>ustawienia opisów</target>
193 </trans-unit>
194 <trans-unit id="Text">
195 <source>Text</source>
196 <target>Tekst</target>
197 </trans-unit>
198 <trans-unit id="White">
199 <source>White</source>
200 <target>Biały</target>
201 </trans-unit>
202 <trans-unit id="Black">
203 <source>Black</source>
204 <target>Czarny</target>
205 </trans-unit>
206 <trans-unit id="Red">
207 <source>Red</source>
208 <target>Czerwony</target>
209 </trans-unit>
210 <trans-unit id="Green">
211 <source>Green</source>
212 <target>Zielony</target>
213 </trans-unit>
214 <trans-unit id="Blue">
215 <source>Blue</source>
216 <target>Niebieski</target>
217 </trans-unit>
218 <trans-unit id="Yellow">
219 <source>Yellow</source>
220 <target>Żółty</target>
221 </trans-unit>
222 <trans-unit id="Magenta">
223 <source>Magenta</source>
224 <target>Magenta</target>
225 </trans-unit>
226 <trans-unit id="Cyan">
227 <source>Cyan</source>
228 <target>Cyjanowy</target>
229 </trans-unit>
230 <trans-unit id="Background">
231 <source>Background</source>
232 <target>TÅ‚o</target>
233 </trans-unit>
234 <trans-unit id="Window">
235 <source>Window</source>
236 <target>Okno</target>
237 </trans-unit>
238 <trans-unit id="Transparent">
239 <source>Transparent</source>
240 <target>Przezroczyste</target>
241 </trans-unit>
242 <trans-unit id="Semi-Transparent">
243 <source>Semi-Transparent</source>
244 <target>Półprzezroczyste</target>
245 </trans-unit>
246 <trans-unit id="Opaque">
247 <source>Opaque</source>
248 <target>Widoczne</target>
249 </trans-unit>
250 <trans-unit id="Font Size">
251 <source>Font Size</source>
252 <target>Rozmiar czcionki</target>
253 </trans-unit>
254 <trans-unit id="Text Edge Style">
255 <source>Text Edge Style</source>
256 <target>Styl krawędzi tekstu</target>
257 </trans-unit>
258 <trans-unit id="None">
259 <source>None</source>
260 <target>Brak</target>
261 </trans-unit>
262 <trans-unit id="Raised">
263 <source>Raised</source>
264 <target>Wypukłe</target>
265 </trans-unit>
266 <trans-unit id="Depressed">
267 <source>Depressed</source>
268 <target>Wgłębione</target>
269 </trans-unit>
270 <trans-unit id="Uniform">
271 <source>Uniform</source>
272 <target>Jednolity</target>
273 </trans-unit>
274 <trans-unit id="Dropshadow">
275 <source>Dropshadow</source>
276 <target>Cień</target>
277 </trans-unit>
278 <trans-unit id="Font Family">
279 <source>Font Family</source>
280 <target>Rodzina czcionek</target>
281 </trans-unit>
282 <trans-unit id="Proportional Sans-Serif">
283 <source>Proportional Sans-Serif</source>
284 <target>Proporcjonalne bezszeryfowe</target>
285 </trans-unit>
286 <trans-unit id="Monospace Sans-Serif">
287 <source>Monospace Sans-Serif</source>
288 <target>Bezszeryfowe o stałej szerokości</target>
289 </trans-unit>
290 <trans-unit id="Proportional Serif">
291 <source>Proportional Serif</source>
292 <target>Proporcjonalne szeryfowe</target>
293 </trans-unit>
294 <trans-unit id="Monospace Serif">
295 <source>Monospace Serif</source>
296 <target>Szeryfowe o stałej szerokości</target>
297 </trans-unit>
298 <trans-unit id="Casual">
299 <source>Casual</source>
300 <target>Ozdobne</target>
301 </trans-unit>
302 <trans-unit id="Script">
303 <source>Script</source>
304 <target>Pismo odręczne</target>
305 </trans-unit>
306 <trans-unit id="Small Caps">
307 <source>Small Caps</source>
308 <target>Kapitaliki</target>
309 </trans-unit>
310 <trans-unit id="Reset">
311 <source>Reset</source>
312 <target>Resetuj</target>
313 </trans-unit>
314 <trans-unit id="restore all settings to the default values">
315 <source>restore all settings to the default values</source>
316 <target>przywróć wszystkie ustawienia do wartości domyślnych</target>
317 </trans-unit>
318 <trans-unit id="Done">
319 <source>Done</source>
320 <target>Gotowe</target>
321 </trans-unit>
322 <trans-unit id="Caption Settings Dialog">
323 <source>Caption Settings Dialog</source>
324 <target>Okno ustawień napisów</target>
325 </trans-unit>
326 <trans-unit id="Beginning of dialog window. Escape will cancel and close the window.">
327 <source>Beginning of dialog window. Escape will cancel and close the window.</source>
328 <target>PoczÄ…tek okna dialogowego. Przycisk Escape anuluje i zamknie okno.</target>
329 </trans-unit>
330 <trans-unit id="End of dialog window.">
331 <source>End of dialog window.</source>
332 <target>Koniec okna dialogowego.</target>
333 </trans-unit>
334 <trans-unit id="{1} is loading.">
335 <source>{1} is loading.</source>
336 <target>{1} Å‚aduje siÄ™.</target>
337 </trans-unit>
338 <trans-unit id="Quality">
339 <source>Quality</source>
340 <target>Jakość</target>
341 </trans-unit>
342 <trans-unit id="Auto">
343 <source>Auto</source>
344 <target>Automatyczna</target>
345 </trans-unit>
346 <trans-unit id="Speed">
347 <source>Speed</source>
348 <target>Prędkość</target>
349 </trans-unit>
350 <trans-unit id="Subtitles/CC">
351 <source>Subtitles/CC</source>
352 <target>Napisy/CC</target>
353 </trans-unit>
354 <trans-unit id="peers">
355 <source>peers</source>
356 <target>peers</target>
357 </trans-unit>
358 <trans-unit id="Go to the video page">
359 <source>Go to the video page</source>
360 <target>Przejdź na stronę filmu</target>
361 </trans-unit>
362 <trans-unit id="Settings">
363 <source>Settings</source>
364 <target>Ustawienia</target>
365 </trans-unit>
366 <trans-unit id="Uses P2P, others may know you are watching this video.">
367 <source>Uses P2P, others may know you are watching this video.</source>
368 <target>Korzysta z P2P, inni mogą dowiedzieć się, że oglądasz ten film.</target>
369 </trans-unit>
370 <trans-unit id="Copy the video URL">
371 <source>Copy the video URL</source>
372 <target>Skopiuj adres URL filmu</target>
373 </trans-unit>
374 <trans-unit id="Copy the video URL at the current time">
375 <source>Copy the video URL at the current time</source>
376 <target>Skopiuj adres URL filmu z obecnym czasem</target>
377 </trans-unit>
378 <trans-unit id="Copy embed code">
379 <source>Copy embed code</source>
380 <target>Skopiuj kod do osadzenia</target>
381 </trans-unit>
382 </body>
383 </file></xliff> \ No newline at end of file
diff --git a/client/src/locale/target/player_ru_RU.json b/client/src/locale/target/player_ru_RU.json
new file mode 100644
index 000000000..e2d8d4980
--- /dev/null
+++ b/client/src/locale/target/player_ru_RU.json
@@ -0,0 +1 @@
{"Audio Player":"Ðудиоплеер","Video Player":"Видеоплеер","Play":"ВоÑпроизвеÑти","Pause":"Пауза","Replay":"ВоÑпроизвеÑти Ñнова","Current Time":"Текущий момент","Duration":"ПродолжительноÑÑ‚ÑŒ","Remaining Time":"ОÑтавшееÑÑ Ð²Ñ€ÐµÐ¼Ñ","Stream Type":"Тип потока","LIVE":"ПрÑмой Ñфир","Loaded":"Загружено","Progress":"Ход выполнениÑ","Progress Bar":"Индикатор выполнениÑ","progress bar timing: currentTime={1} duration={2}":"{1} из {2}","Fullscreen":"Полный Ñкран","Non-Fullscreen":"Окно","Mute":"Без звука","Unmute":"Со звуком","Playback Rate":" СкороÑÑ‚ÑŒ воÑпроизведениÑ","Subtitles":"Субтитры","subtitles off":"Без Ñубтитров","Captions":"Сопроводительные надпиÑи","captions off":"Без Ñопроводительных надпиÑей","Chapters":"Главы","Descriptions":"ОпиÑание","descriptions off":"без опиÑаний","Audio Track":"Ðудиодорожка","Volume Level":"ГромкоÑÑ‚ÑŒ","You aborted the media playback":"Ð’Ñ‹ отменили воÑпроизведение медиафайла","A network error caused the media download to fail part-way.":"Ошибка Ñети Ñтала причиной неудачного воÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¼ÐµÐ´Ð¸Ð°Ñ„Ð°Ð¹Ð»Ð°","The media could not be loaded, either because the server or network failed or because the format is not supported.":"Медиафайл не может быть воÑпроизведен: ошибки Ñервера или Ñети; или не поддерживаетÑÑ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚ медиафайла","The media playback was aborted due to a corruption problem or because the media used features your browser did not support.":"ВоÑпроизведение отменено: файл иÑпорчен или иÑпользует инÑтрументы, которые ваш навигатор не поддерживает ","No compatible source was found for this media.":"Ðе найдено ÑовмеÑтимого иÑточника Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð¼ÐµÐ´Ð¸Ð°Ñ„Ð°Ð¹Ð»Ð°","The media is encrypted and we do not have the keys to decrypt it.":"Этот медиафайл зашифрован и у Ð½Ð°Ñ Ð½ÐµÑ‚ ключей Ð´Ð»Ñ ÐµÐ³Ð¾ раÑшифровки ","Play Video":"ВоÑпроизвеÑти видео","Close":"Закрыть","Close Modal Dialog":"Закрыть модальное диалоговое окно","Modal Window":"Модальное окно","This is a modal window":"Это модальное окно","This modal can be closed by pressing the Escape key or activating the close button.":"Это модальное окно можно закрыть нажав на кнопку Escape или на кнопку закрыть",", opens captions settings dialog":", открывает окно наÑтроек Ñопроводительных надпиÑей",", opens subtitles settings dialog":", открывает окно наÑтроек Ñубтитров",", opens descriptions settings dialog":", открывает окно наÑтроек опиÑаний",", selected":", выделено ","captions settings":"ÐаÑтройки Ñопроводительных надпиÑей","subtitles settings":"ÐаÑтройки Ñубтитров","descriptions settings":"ÐаÑтройки опиÑаний ","Text":"ТекÑÑ‚","White":"Белый","Black":"Черный","Red":"КраÑный","Green":"Зеленый","Blue":"Синий","Yellow":"Желтый","Magenta":"Пурпурный ","Cyan":"Голубой","Background":"Фон","Window":"Окно","Transparent":"Прозрачный","Semi-Transparent":"Полупрозрачный ","Opaque":"Ðепрозрачный","Font Size":"Размер шрифта ","None":"ОтÑутÑтвует","Uniform":"Однообразный","Dropshadow":"ÐŸÐ°Ð´Ð°ÑŽÑ‰Ð°Ñ Ñ‚ÐµÐ½ÑŒ","Font Family":"Шрифт","Proportional Sans-Serif":"Пропорциональный без заÑечек","Monospace Sans-Serif":"ФикÑированной ширины без заÑечек","Proportional Serif":"Пропорциональный Ñ Ð·Ð°Ñечками","Monospace Serif":"ФикÑированной ширины Ñ Ð·Ð°Ñечками","Casual":"Свободный","Script":"рукопиÑный шрифт","Small Caps":" Уменьшенные заглавные буквы","Reset":"ВоÑÑтановить ","restore all settings to the default values":"ВоÑÑтановить наÑтройки по умолчанию ","Done":"Выполнено","Caption Settings Dialog":"Окно наÑтроек Ñопроводительных надпиÑей","Beginning of dialog window. Escape will cancel and close the window.":"Ðачало диалогового окна. Клавиша Escape отменит дейÑтвие и закроет окно","End of dialog window.":"Конец диалогового окна","{1} is loading.":"{1} в процеÑÑе загрузки","Quality":"КачеÑтво","Auto":"Ðвто","Speed":"СкороÑÑ‚ÑŒ","Subtitles/CC":"Субтитры","peers":"Партнер","Go to the video page":"Перейти на Ñтраницу Ñ Ð²Ð¸Ð´ÐµÐ¾","Settings":"ÐаÑтройки","Uses P2P, others may know you are watching this video.":"ИÑпользует P2P, другие могут знать, что вы проÑматриваете Ñто видео.","Copy the video URL":"Скопировать URL видео","Copy the video URL at the current time":"Скопировать URL видео на текущем моменте ","Copy embed code":"Скопировать вÑтроенный код"} \ No newline at end of file
diff --git a/client/src/locale/target/server_cs_CZ.json b/client/src/locale/target/server_cs_CZ.json
index 060658c80..e013a910f 100644
--- a/client/src/locale/target/server_cs_CZ.json
+++ b/client/src/locale/target/server_cs_CZ.json
@@ -1 +1 @@
{"Music":"Hudba","Films":"Filmy","Vehicles":"Auta","Art":"UmÄ›ní","Sports":"Sport","Travels":"Cestování","Gaming":"Hry","People":"Lidé","Comedy":"Komedie","Entertainment":"Zábava","News & Politics":"Zprávy a politika","How To":"Jak na to","Education":"Výukové","Activism":"Aktivismus","Science & Technology":"VÄ›da a technologie","Animals":"Zvířata","Kids":"DÄ›ti","Food":"Jídlo a vaÅ™ení","Attribution":"UveÄte autora","Attribution - Share Alike":"UveÄte autora - Zachovejte licenci","Attribution - No Derivatives":"UveÄte autora - Nezpracovávejte","Attribution - Non Commercial":"UveÄte autora - NeÅ¡iÅ™te dílo komerÄnÄ›","Attribution - Non Commercial - Share Alike":"UveÄte autora - NeÅ¡iÅ™te dílo komerÄnÄ› - Zachovejte licenci","Attribution - Non Commercial - No Derivatives":"UveÄte autora - NeÅ¡iÅ™te dílo komerÄnÄ› - Nezpracovávejte","Public Domain Dedication":"Volné dílo","Public":"VeÅ™ejné","Unlisted":"Nezobrazeno","Private":"Soukromé","Published":"Publikované","Pending":"ÄŒekající","Success":"ÚspÄ›ch","Failed":"NeúspÄ›ch","Misc":"Různé","Unknown":"Neznámé","Afar":"AfarÅ¡tina","Abkhazian":"AbcházÅ¡tina","Afrikaans":"AfrikánÅ¡tina","Akan":"AkanÅ¡tina","Amharic":"AmharÅ¡tina","Arabic":"ArabÅ¡tina","Aragonese":"AragonÅ¡tina","American Sign Language":"Americká znaková Å™eÄ","Assamese":"ÃsámÅ¡tina","Avaric":"AvarÅ¡tina","Kotava":"Kotava","Aymara":"AjmarÅ¡tina","Azerbaijani":"ÃzerbájdžánÅ¡tina","Bashkir":"BaÅ¡kirÅ¡tina","Bambara":"BambarÅ¡tina","Belarusian":"BÄ›loruÅ¡tina","Bengali":"BengálÅ¡tina","British Sign Language":"Britská znaková Å™eÄ","Bislama":"BislamÅ¡tina","Tibetan":"TibetÅ¡tina","Bosnian":"BosenÅ¡tina","Breton":"BretonÅ¡tina","Bulgarian":"BulharÅ¡tina","Brazilian Sign Language":"Brazilská znaková Å™eÄ","Catalan":"KatalánÅ¡tina","Czech":"ÄŒeÅ¡tina","Chamorro":"Chamorro","Chechen":"ÄŒeÄenÅ¡tina","Chuvash":"ÄŒuvaÅ¡tina","Cornish":"KornÅ¡tina","Corsican":"KorsiÄtina","Cree":"KríjÅ¡tina","Czech Sign Language":"ÄŒeská znaková Å™eÄ","Chinese Sign Language":"Čínská znaková Å™eÄ","Welsh":"VelÅ¡tina","Danish":"DánÅ¡tina","German":"NÄ›mÄina","Dhivehi":"MaledivÅ¡tina","Danish Sign Language":"Dánská znaková Å™eÄ","Dzongkha":"Dzongkä","Modern Greek (1453-)":"Moderní Å™eÄtina","English":"AngliÄtina","Esperanto":"Esperanto","Estonian":"EstonÅ¡tina","Basque":"BaskiÄtina","Ewe":"EveÅ¡tina","Faroese":"FaerÅ¡tina","Persian":"PerÅ¡tina","Fijian":"FidžijÅ¡tina","Finnish":"FinÅ¡tina","French":"FrancouzÅ¡tina","Western Frisian":"Západofríština","French Sign Language":"Francouzská znaková Å™eÄ","Fulah":"FulbÅ¡tina","Scottish Gaelic":"Skotská gaelÅ¡tina","Irish":"IrÅ¡tina","Galician":"GalicijÅ¡tina","Manx":"ManÅ¡tina","Guarani":"GuaranÅ¡tina","German Sign Language":"NÄ›mecká znaková Å™eÄ","Gujarati":"GudžarátÅ¡tina","Haitian":"Haitská kreolÅ¡tina","Hausa":"HauÅ¡tina","Serbo-Croatian":"SrcbochorvatÅ¡inta","Hebrew":"HebrejÅ¡tina","Herero":"Herero","Hindi":"HindÅ¡tina","Hiri Motu":"Hiri Motu","Croatian":"ChorvatÅ¡tina","Hungarian":"MaÄarÅ¡tina","Armenian":"ArménÅ¡tina","Igbo":"IgboÅ¡tina","Sichuan Yi":"Nuosu","Inuktitut":"InuktitutÅ¡tina","Indonesian":"Indonéština","Inupiaq":"Inupiaq","Icelandic":"IslandÅ¡tina","Italian":"ItalÅ¡tina","Javanese":"JavánÅ¡tina","Lojban":"Lojban","Japanese":"JaponÅ¡tina","Japanese Sign Language":"Japonská znaková Å™eÄ","Kalaallisut":"GrónÅ¡tina","Kannada":"KannadÅ¡tina","Kashmiri":"KaÅ¡mírÅ¡tina","Georgian":"GruzínÅ¡tina","Kanuri":"KanurijÅ¡tina","Kazakh":"KazaÅ¡tina","Khmer":"KhmerÅ¡tina","Kikuyu":"KikujÅ¡tina","Kinyarwanda":"RwandÅ¡tina","Kirghiz":"KyrgyzÅ¡tina","Komi":"Komi","Kongo":"Konžština","Korean":"KorejÅ¡tina","Kuanyama":"Kuanyama","Kurdish":"KurdÅ¡tina","Lao":"LaoÅ¡tina","Latvian":"LotyÅ¡tina","Limburgan":"LimburÅ¡tina","Lingala":"NgalÅ¡tina","Lithuanian":"LitevÅ¡tina","Luxembourgish":"LucemburÅ¡tina","Luba-Katanga":"Luba-Katanga","Ganda":"GandÅ¡tina","Marshallese":"MaršálÅ¡tina","Malayalam":"MalajálamÅ¡tina","Marathi":"MaráthÅ¡tina","Macedonian":"MakedonÅ¡tina","Malagasy":"MalgaÅ¡tina","Maltese":"MaltÅ¡tina","Mongolian":"MongolÅ¡tina","Maori":"MaorÅ¡tina","Malay (macrolanguage)":"MalajÅ¡tina","Burmese":"BarmÅ¡tina","Nauru":"NaurÅ¡tina","Navajo":"Navažština","South Ndebele":"Jižní ndebelÅ¡tina","North Ndebele":"Severní ndebelÅ¡tina","Ndonga":"NdondÅ¡tina","Nepali (macrolanguage)":"NepálÅ¡tina","Dutch":"DánÅ¡tina","Norwegian Nynorsk":"NorÅ¡tina Nynorsk","Norwegian BokmÃ¥l":"NorÅ¡tina BokmÃ¥l","Norwegian":"NorÅ¡tina ","Nyanja":"ÄŒiÄevÅ¡tina","Occitan":"OkcitánÅ¡tina","Ojibwa":"Ojibwa","Oriya (macrolanguage)":"UrijÅ¡tina","Oromo":"OromÅ¡tina","Ossetian":"OsetÅ¡tina","Panjabi":"PaňdžábÅ¡tina","Pakistan Sign Language":"Pakistánská znaková Å™eÄ","Polish":"PolÅ¡tina","Portuguese":"PortugalÅ¡tina","Pushto":"PaÅ¡tÅ¡tina","Quechua":"KeÄuánÅ¡tina","Romansh":"RétorománÅ¡tina","Romanian":"RumunÅ¡tina","Russian Sign Language":"Ruská znaková Å™eÄ","Rundi":"Kirundi","Russian":"RuÅ¡tina","Sango":"Sango","Saudi Arabian Sign Language":"Saudská arabská znaková Å™eÄ","South African Sign Language":"Jihoafrická znaková Å™eÄ","Sinhala":"SinhálÅ¡tina","Slovak":"SlovenÅ¡tina","Slovenian":"SlovinÅ¡tina","Northern Sami":"Severní sámÅ¡tina","Samoan":"SamojÅ¡tina","Shona":"Shona","Sindhi":"SindhÅ¡tina","Somali":"SomálÅ¡tina","Southern Sotho":"Jižní sotÅ¡tina","Spanish":"Å panÄ›lÅ¡tina","Albanian":"AlbánÅ¡tina","Sardinian":"SardínÅ¡tina","Serbian":"SrbÅ¡tina","Swati":"Swati","Sundanese":"SundÅ¡tina","Swahili (macrolanguage)":"SvahilÅ¡tina","Swedish":"Å védÅ¡tina","Swedish Sign Language":"Å védská znaková Å™eÄ","Tahitian":"TahitÅ¡tina","Tamil":"TamilÅ¡tina","Tatar":"TatarÅ¡tina","Telugu":"TelugÅ¡tina","Tajik":"TádžiÄtina","Tagalog":"Tagalog","Thai":"ThajÅ¡tina","Tigrinya":"Tigrinya","Klingon":"KlingonÅ¡tina","Tonga (Tonga Islands)":"TongánÅ¡tina","Tswana":"SetswanÅ¡tina","Tsonga":"TsongÅ¡tina","Turkmen":"TurkmenÅ¡tina","Turkish":"TureÄtina","Twi":"Twi","Uighur":"UjgurÅ¡tina","Ukrainian":"UkrajinÅ¡tina","Urdu":"UrdÅ¡tina","Uzbek":"UzbeÄtina","Venda":"VendÅ¡tina","Vietnamese":"VietnamÅ¡tina","Walloon":"ValonÅ¡tina","Wolof":"Wolof ","Xhosa":"XhoÅ¡tina","Yiddish":"JidiÅ¡","Yoruba":"JorubÅ¡tina","Zhuang":"ÄŒuangÅ¡tina","Chinese":"ČínÅ¡tina","Zulu":"ZuluÅ¡tina"} \ No newline at end of file {"Music":"Hudba","Films":"Filmy","Vehicles":"Auta","Art":"UmÄ›ní","Sports":"Sport","Travels":"Cestování","Gaming":"Hry","People":"Lidé","Comedy":"Komedie","Entertainment":"Zábava","News & Politics":"Zprávy a politika","How To":"Jak na to","Education":"Výukové","Activism":"Aktivismus","Science & Technology":"VÄ›da a technologie","Animals":"Zvířata","Kids":"DÄ›ti","Food":"Jídlo a vaÅ™ení","Attribution":"UveÄte autora","Attribution - Share Alike":"UveÄte autora - Zachovejte licenci","Attribution - No Derivatives":"UveÄte autora - Nezpracovávejte","Attribution - Non Commercial":"UveÄte autora - NeÅ¡iÅ™te dílo komerÄnÄ›","Attribution - Non Commercial - Share Alike":"UveÄte autora - NeÅ¡iÅ™te dílo komerÄnÄ› - Zachovejte licenci","Attribution - Non Commercial - No Derivatives":"UveÄte autora - NeÅ¡iÅ™te dílo komerÄnÄ› - Nezpracovávejte","Public Domain Dedication":"Volné dílo","Public":"VeÅ™ejné","Unlisted":"Nezobrazeno","Private":"Soukromé","Published":"Publikované","To transcode":"K transkódování","To import":"To import","Pending":"ÄŒekající","Success":"ÚspÄ›ch","Failed":"NeúspÄ›ch","Misc":"Různé","Unknown":"Neznámé","Afar":"AfarÅ¡tina","Abkhazian":"AbcházÅ¡tina","Afrikaans":"AfrikánÅ¡tina","Akan":"AkanÅ¡tina","Amharic":"AmharÅ¡tina","Arabic":"ArabÅ¡tina","Aragonese":"AragonÅ¡tina","American Sign Language":"Americká znaková Å™eÄ","Assamese":"ÃsámÅ¡tina","Avaric":"AvarÅ¡tina","Kotava":"Kotava","Aymara":"AjmarÅ¡tina","Azerbaijani":"ÃzerbájdžánÅ¡tina","Bashkir":"BaÅ¡kirÅ¡tina","Bambara":"BambarÅ¡tina","Belarusian":"BÄ›loruÅ¡tina","Bengali":"BengálÅ¡tina","British Sign Language":"Britská znaková Å™eÄ","Bislama":"BislamÅ¡tina","Tibetan":"TibetÅ¡tina","Bosnian":"BosenÅ¡tina","Breton":"BretonÅ¡tina","Bulgarian":"BulharÅ¡tina","Brazilian Sign Language":"Brazilská znaková Å™eÄ","Catalan":"KatalánÅ¡tina","Czech":"ÄŒeÅ¡tina","Chamorro":"Chamorro","Chechen":"ÄŒeÄenÅ¡tina","Chuvash":"ÄŒuvaÅ¡tina","Cornish":"KornÅ¡tina","Corsican":"KorsiÄtina","Cree":"KríjÅ¡tina","Czech Sign Language":"ÄŒeská znaková Å™eÄ","Chinese Sign Language":"Čínská znaková Å™eÄ","Welsh":"VelÅ¡tina","Danish":"DánÅ¡tina","German":"NÄ›mÄina","Dhivehi":"MaledivÅ¡tina","Danish Sign Language":"Dánská znaková Å™eÄ","Dzongkha":"Dzongkä","Modern Greek (1453-)":"Moderní Å™eÄtina","English":"AngliÄtina","Esperanto":"Esperanto","Estonian":"EstonÅ¡tina","Basque":"BaskiÄtina","Ewe":"EveÅ¡tina","Faroese":"FaerÅ¡tina","Persian":"PerÅ¡tina","Fijian":"FidžijÅ¡tina","Finnish":"FinÅ¡tina","French":"FrancouzÅ¡tina","Western Frisian":"Západofríština","French Sign Language":"Francouzská znaková Å™eÄ","Fulah":"FulbÅ¡tina","Scottish Gaelic":"Skotská gaelÅ¡tina","Irish":"IrÅ¡tina","Galician":"GalicijÅ¡tina","Manx":"ManÅ¡tina","Guarani":"GuaranÅ¡tina","German Sign Language":"NÄ›mecká znaková Å™eÄ","Gujarati":"GudžarátÅ¡tina","Haitian":"Haitská kreolÅ¡tina","Hausa":"HauÅ¡tina","Serbo-Croatian":"SrcbochorvatÅ¡inta","Hebrew":"HebrejÅ¡tina","Herero":"Herero","Hindi":"HindÅ¡tina","Hiri Motu":"Hiri Motu","Croatian":"ChorvatÅ¡tina","Hungarian":"MaÄarÅ¡tina","Armenian":"ArménÅ¡tina","Igbo":"IgboÅ¡tina","Sichuan Yi":"Nuosu","Inuktitut":"InuktitutÅ¡tina","Indonesian":"Indonéština","Inupiaq":"Inupiaq","Icelandic":"IslandÅ¡tina","Italian":"ItalÅ¡tina","Javanese":"JavánÅ¡tina","Lojban":"Lojban","Japanese":"JaponÅ¡tina","Japanese Sign Language":"Japonská znaková Å™eÄ","Kalaallisut":"GrónÅ¡tina","Kannada":"KannadÅ¡tina","Kashmiri":"KaÅ¡mírÅ¡tina","Georgian":"GruzínÅ¡tina","Kanuri":"KanurijÅ¡tina","Kazakh":"KazaÅ¡tina","Khmer":"KhmerÅ¡tina","Kikuyu":"KikujÅ¡tina","Kinyarwanda":"RwandÅ¡tina","Kirghiz":"KyrgyzÅ¡tina","Komi":"Komi","Kongo":"Konžština","Korean":"KorejÅ¡tina","Kuanyama":"Kuanyama","Kurdish":"KurdÅ¡tina","Lao":"LaoÅ¡tina","Latvian":"LotyÅ¡tina","Limburgan":"LimburÅ¡tina","Lingala":"NgalÅ¡tina","Lithuanian":"LitevÅ¡tina","Luxembourgish":"LucemburÅ¡tina","Luba-Katanga":"Luba-Katanga","Ganda":"GandÅ¡tina","Marshallese":"MaršálÅ¡tina","Malayalam":"MalajálamÅ¡tina","Marathi":"MaráthÅ¡tina","Macedonian":"MakedonÅ¡tina","Malagasy":"MalgaÅ¡tina","Maltese":"MaltÅ¡tina","Mongolian":"MongolÅ¡tina","Maori":"MaorÅ¡tina","Malay (macrolanguage)":"MalajÅ¡tina","Burmese":"BarmÅ¡tina","Nauru":"NaurÅ¡tina","Navajo":"Navažština","South Ndebele":"Jižní ndebelÅ¡tina","North Ndebele":"Severní ndebelÅ¡tina","Ndonga":"NdondÅ¡tina","Nepali (macrolanguage)":"NepálÅ¡tina","Dutch":"DánÅ¡tina","Norwegian Nynorsk":"NorÅ¡tina Nynorsk","Norwegian BokmÃ¥l":"NorÅ¡tina BokmÃ¥l","Norwegian":"NorÅ¡tina ","Nyanja":"ÄŒiÄevÅ¡tina","Occitan":"OkcitánÅ¡tina","Ojibwa":"Ojibwa","Oriya (macrolanguage)":"UrijÅ¡tina","Oromo":"OromÅ¡tina","Ossetian":"OsetÅ¡tina","Panjabi":"PaňdžábÅ¡tina","Pakistan Sign Language":"Pakistánská znaková Å™eÄ","Polish":"PolÅ¡tina","Portuguese":"PortugalÅ¡tina","Pushto":"PaÅ¡tÅ¡tina","Quechua":"KeÄuánÅ¡tina","Romansh":"RétorománÅ¡tina","Romanian":"RumunÅ¡tina","Russian Sign Language":"Ruská znaková Å™eÄ","Rundi":"Kirundi","Russian":"RuÅ¡tina","Sango":"Sango","Saudi Arabian Sign Language":"Saudská arabská znaková Å™eÄ","South African Sign Language":"Jihoafrická znaková Å™eÄ","Sinhala":"SinhálÅ¡tina","Slovak":"SlovenÅ¡tina","Slovenian":"SlovinÅ¡tina","Northern Sami":"Severní sámÅ¡tina","Samoan":"SamojÅ¡tina","Shona":"Shona","Sindhi":"SindhÅ¡tina","Somali":"SomálÅ¡tina","Southern Sotho":"Jižní sotÅ¡tina","Spanish":"Å panÄ›lÅ¡tina","Albanian":"AlbánÅ¡tina","Sardinian":"SardínÅ¡tina","Serbian":"SrbÅ¡tina","Swati":"Swati","Sundanese":"SundÅ¡tina","Swahili (macrolanguage)":"SvahilÅ¡tina","Swedish":"Å védÅ¡tina","Swedish Sign Language":"Å védská znaková Å™eÄ","Tahitian":"TahitÅ¡tina","Tamil":"TamilÅ¡tina","Tatar":"TatarÅ¡tina","Telugu":"TelugÅ¡tina","Tajik":"TádžiÄtina","Tagalog":"Tagalog","Thai":"ThajÅ¡tina","Tigrinya":"Tigrinya","Klingon":"KlingonÅ¡tina","Tonga (Tonga Islands)":"TongánÅ¡tina","Tswana":"SetswanÅ¡tina","Tsonga":"TsongÅ¡tina","Turkmen":"TurkmenÅ¡tina","Turkish":"TureÄtina","Twi":"Twi","Uighur":"UjgurÅ¡tina","Ukrainian":"UkrajinÅ¡tina","Urdu":"UrdÅ¡tina","Uzbek":"UzbeÄtina","Venda":"VendÅ¡tina","Vietnamese":"VietnamÅ¡tina","Walloon":"ValonÅ¡tina","Wolof":"Wolof ","Xhosa":"XhoÅ¡tina","Yiddish":"JidiÅ¡","Yoruba":"JorubÅ¡tina","Zhuang":"ÄŒuangÅ¡tina","Chinese":"ČínÅ¡tina","Zulu":"ZuluÅ¡tina"} \ No newline at end of file
diff --git a/client/src/locale/target/server_fr_FR.json b/client/src/locale/target/server_fr_FR.json
index eebc2f96e..64762b575 100644
--- a/client/src/locale/target/server_fr_FR.json
+++ b/client/src/locale/target/server_fr_FR.json
@@ -1 +1 @@
{"Music":"Musiques","Films":"Films","Vehicles":"Transport","Art":"Art","Sports":"Sports","Travels":"Voyages","Gaming":"Jeux vidéos","People":"Personnalités","Comedy":"Humour","Entertainment":"Divertissement","News & Politics":"Actualité & Politique","How To":"Tutoriels","Education":"Éducation","Activism":"Militantisme","Science & Technology":"Science & Technologie","Animals":"Animaux","Kids":"Enfants","Food":"Cuisine","Attribution":"Attribution","Attribution - Share Alike":"Attribution - Partage dans les mêmes conditions","Attribution - No Derivatives":"Attribution - Pas d’œuvre dérivée","Attribution - Non Commercial":"Attribution - Utilisation non commerciale","Attribution - Non Commercial - Share Alike":"Attribution - Utilisation non commerciale - Partage dans les mêmes conditions","Attribution - Non Commercial - No Derivatives":"Attribution - Utilisation non commerciale - Pas d’œuvre dérivée","Public Domain Dedication":"Domaine public","Public":"Publique","Unlisted":"Non listée","Private":"Privée","Published":"Publiée","To transcode":"À transcoder","To import":"À importer","Pending":"En cours","Success":"Succès","Failed":"Échoué","Misc":"Divers","Unknown":"Inconnu","Afar":"Afar","Abkhazian":"Abkhaze","Afrikaans":"Afrikaans","Akan":"Akan","Amharic":"Amharique","Arabic":"Arabe","Aragonese":"Aragonais","American Sign Language":"Langue des signes américaine","Assamese":"Assamais","Avaric":"Avar","Kotava":"Kotava","Aymara":"Aymara","Azerbaijani":"Azéri","Bashkir":"Bachkir","Bambara":"Bambara","Belarusian":"Biélorusse","Bengali":"Bengali","British Sign Language":"Langue des signes britannique","Bislama":"Bichlamar","Tibetan":"Tibétain","Bosnian":"Bosniaque","Breton":"Breton","Bulgarian":"Bulgare","Brazilian Sign Language":"Langue des signes brésilienne","Catalan":"Catalan","Czech":"Tchèque","Chamorro":"Chamorro","Chechen":"Tchétchène","Chuvash":"Tchouvache","Cornish":"Cornique","Corsican":"Corse","Cree":"Cree","Czech Sign Language":"Langue des signes tchèque","Chinese Sign Language":"Langue des signes chinoise","Welsh":"Gallois","Danish":"Danois","German":"Allemand","Dhivehi":"Maldivien","Danish Sign Language":"Langue des signes danoise","Dzongkha":"Dzongkha","Modern Greek (1453-)":"Grec moderne (après 1453)","English":"Anglais","Esperanto":"Espéranto","Estonian":"Estonien","Basque":"Basque","Ewe":"Éwé","Faroese":"Féroïen","Persian":"Persan","Fijian":"Fidjien","Finnish":"Finnois","French":"Français","Western Frisian":"Frison occidental","French Sign Language":"Langue des signes française","Fulah":"Peul","Scottish Gaelic":"Gaélique","Irish":"Irlandais","Galician":"Galicien","Manx":"Manx","Guarani":"Guarani","German Sign Language":"Langue des signes allemande","Gujarati":"Goudjrati","Haitian":"Haïtien","Hausa":"Haoussa","Serbo-Croatian":"Serbo-croate","Hebrew":"Hébreu","Herero":"Herero","Hindi":"Hindi","Hiri Motu":"Hiri motu","Croatian":"Croate","Hungarian":"Hongrois","Armenian":"Arménien","Igbo":"Igbo","Sichuan Yi":"Yi de Sichuan","Inuktitut":"Inuktitut","Indonesian":"Indonésien","Inupiaq":"Inupiaq","Icelandic":"Islandais","Italian":"Italien","Javanese":"Javanais","Lojban":"Lojban","Japanese":"Japonais","Japanese Sign Language":"Langue des signes japonaise","Kalaallisut":"Groenlandais","Kannada":"Kannada","Kashmiri":"Kashmiri","Georgian":"Géorgien","Kanuri":"Kanouri","Kazakh":"Kazakh","Khmer":"Khmer central","Kikuyu":"Kikuyu","Kinyarwanda":"Rwanda","Kirghiz":"Kirghiz","Komi":"Kom","Kongo":"Kongo","Korean":"Coréen","Kuanyama":"Kuanyama","Kurdish":"Kurde","Lao":"Lao","Latvian":"Letton","Limburgan":"Limbourgeois","Lingala":"Lingala","Lithuanian":"Lituanien","Luxembourgish":"Luxembourgeois","Luba-Katanga":"Luba-katanga","Ganda":"Ganda","Marshallese":"Marshall","Malayalam":"Malayalam","Marathi":"Marathe","Macedonian":"Macédonien","Malagasy":"Malgache","Maltese":"Maltais","Mongolian":"Mongol","Maori":"Maori","Malay (macrolanguage)":"Malais","Burmese":"Birman","Nauru":"Nauruan","Navajo":"Navaho","South Ndebele":"Ndébélé du Sud","North Ndebele":"Ndébélé du Nord","Ndonga":"Ndonga","Nepali (macrolanguage)":"Népalais","Dutch":"Néerlandais","Norwegian Nynorsk":"Norvégien nynorsk","Norwegian Bokmål":"Norvégien bokmål","Norwegian":"Norvégien","Nyanja":"Chichewa","Occitan":"Occitane","Ojibwa":"Ojibwa","Oriya (macrolanguage)":"Oriya","Oromo":"Galla","Ossetian":"Ossète","Panjabi":"Pendjabi","Pakistan Sign Language":"Langue des signes pakistanaise","Polish":"Polonais","Portuguese":"Portugais","Pushto":"Pachto","Quechua":"Quechua","Romansh":"Romanche","Romanian":"Roumain","Russian Sign Language":"Langue des signes russe","Rundi":"Rundi","Russian":"Russe","Sango":"Sango","Saudi Arabian Sign Language":"Langue des signes saoudienne","South African Sign Language":"Langue des signes sud-africaine","Sinhala":"Singhalais","Slovak":"Slovaque","Slovenian":"Slovène","Northern Sami":"Sami du Nord","Samoan":"Samoan","Shona":"Shona","Sindhi":"Sindhi","Somali":"Somali","Southern Sotho":"Sotho du Sud","Spanish":"Espagnol","Albanian":"Albanais","Sardinian":"Sarde","Serbian":"Serbe","Swati":"Swati","Sundanese":"Soundanais","Swahili (macrolanguage)":"Swahili","Swedish":"Suédois","Swedish Sign Language":"Langue des signes suédoise","Tahitian":"Tahitien","Tamil":"Tamoul","Tatar":"Tatar","Telugu":"Télougou","Tajik":"Tadjik","Tagalog":"Tagalog","Thai":"Thaï","Tigrinya":"Tigrigna","Klingon":"Klingon","Tonga (Tonga Islands)":"Tongan (Îles Tonga)","Tswana":"Tswana","Tsonga":"Tsonga","Turkmen":"Turkmène","Turkish":"Turc","Twi":"Twi","Uighur":"Ouïgour","Ukrainian":"Ukrainien","Urdu":"Ourdou","Uzbek":"Ouszbek","Venda":"Venda","Vietnamese":"Vietnamien","Walloon":"Wallon","Wolof":"Wolof","Xhosa":"Xhosa","Yiddish":"Yiddish","Yoruba":"Yoruba","Zhuang":"Zhuang","Chinese":"Chinois","Zulu":"Zoulou"} \ No newline at end of file {"Music":"Musiques","Films":"Films","Vehicles":"Transport","Art":"Art","Sports":"Sports","Travels":"Voyages","Gaming":"Jeux vidéos","People":"Personnalités","Comedy":"Humour","Entertainment":"Divertissement","News & Politics":"Actualité & Politique","How To":"Tutoriels","Education":"Éducation","Activism":"Militantisme","Science & Technology":"Science & Technologie","Animals":"Animaux","Kids":"Enfants","Food":"Cuisine","Attribution":"Attribution","Attribution - Share Alike":"Attribution - Partage dans les mêmes conditions","Attribution - No Derivatives":"Attribution - Pas d’œuvre dérivée","Attribution - Non Commercial":"Attribution - Utilisation non commerciale","Attribution - Non Commercial - Share Alike":"Attribution - Utilisation non commerciale - Partage dans les mêmes conditions","Attribution - Non Commercial - No Derivatives":"Attribution - Utilisation non commerciale - Pas d’œuvre dérivée","Public Domain Dedication":"Domaine public","Public":"Publique","Unlisted":"Non listée","Private":"Privée","Published":"Publiée","To transcode":"À transcoder","To import":"À importer","Pending":"En cours","Success":"Succès","Failed":"Échoué","This video does not exist.":"Cette vidéo n'existe pas.","We cannot fetch the video. Please try again later.":"Nous ne pouvons pas récupérer la vidéo. Merci de réessayer plus tard.","Sorry":"Désolé","This video is not available because the remote instance is not responding.":"Cette vidéo n'est pas disponible car l'instance distante ne répond pas.","Misc":"Divers","Unknown":"Inconnu","Afar":"Afar","Abkhazian":"Abkhaze","Afrikaans":"Afrikaans","Akan":"Akan","Amharic":"Amharique","Arabic":"Arabe","Aragonese":"Aragonais","American Sign Language":"Langue des signes américaine","Assamese":"Assamais","Avaric":"Avar","Kotava":"Kotava","Aymara":"Aymara","Azerbaijani":"Azéri","Bashkir":"Bachkir","Bambara":"Bambara","Belarusian":"Biélorusse","Bengali":"Bengali","British Sign Language":"Langue des signes britannique","Bislama":"Bichlamar","Tibetan":"Tibétain","Bosnian":"Bosniaque","Breton":"Breton","Bulgarian":"Bulgare","Brazilian Sign Language":"Langue des signes brésilienne","Catalan":"Catalan","Czech":"Tchèque","Chamorro":"Chamorro","Chechen":"Tchétchène","Chuvash":"Tchouvache","Cornish":"Cornique","Corsican":"Corse","Cree":"Cree","Czech Sign Language":"Langue des signes tchèque","Chinese Sign Language":"Langue des signes chinoise","Welsh":"Gallois","Danish":"Danois","German":"Allemand","Dhivehi":"Maldivien","Danish Sign Language":"Langue des signes danoise","Dzongkha":"Dzongkha","Modern Greek (1453-)":"Grec moderne (après 1453)","English":"Anglais","Esperanto":"Espéranto","Estonian":"Estonien","Basque":"Basque","Ewe":"Éwé","Faroese":"Féroïen","Persian":"Persan","Fijian":"Fidjien","Finnish":"Finnois","French":"Français","Western Frisian":"Frison occidental","French Sign Language":"Langue des signes française","Fulah":"Peul","Scottish Gaelic":"Gaélique","Irish":"Irlandais","Galician":"Galicien","Manx":"Manx","Guarani":"Guarani","German Sign Language":"Langue des signes allemande","Gujarati":"Goudjrati","Haitian":"Haïtien","Hausa":"Haoussa","Serbo-Croatian":"Serbo-croate","Hebrew":"Hébreu","Herero":"Herero","Hindi":"Hindi","Hiri Motu":"Hiri motu","Croatian":"Croate","Hungarian":"Hongrois","Armenian":"Arménien","Igbo":"Igbo","Sichuan Yi":"Yi de Sichuan","Inuktitut":"Inuktitut","Indonesian":"Indonésien","Inupiaq":"Inupiaq","Icelandic":"Islandais","Italian":"Italien","Javanese":"Javanais","Lojban":"Lojban","Japanese":"Japonais","Japanese Sign Language":"Langue des signes japonaise","Kalaallisut":"Groenlandais","Kannada":"Kannada","Kashmiri":"Kashmiri","Georgian":"Géorgien","Kanuri":"Kanouri","Kazakh":"Kazakh","Khmer":"Khmer central","Kikuyu":"Kikuyu","Kinyarwanda":"Rwanda","Kirghiz":"Kirghiz","Komi":"Kom","Kongo":"Kongo","Korean":"Coréen","Kuanyama":"Kuanyama","Kurdish":"Kurde","Lao":"Lao","Latvian":"Letton","Limburgan":"Limbourgeois","Lingala":"Lingala","Lithuanian":"Lituanien","Luxembourgish":"Luxembourgeois","Luba-Katanga":"Luba-katanga","Ganda":"Ganda","Marshallese":"Marshall","Malayalam":"Malayalam","Marathi":"Marathe","Macedonian":"Macédonien","Malagasy":"Malgache","Maltese":"Maltais","Mongolian":"Mongol","Maori":"Maori","Malay (macrolanguage)":"Malais","Burmese":"Birman","Nauru":"Nauruan","Navajo":"Navaho","South Ndebele":"Ndébélé du Sud","North Ndebele":"Ndébélé du Nord","Ndonga":"Ndonga","Nepali (macrolanguage)":"Népalais","Dutch":"Néerlandais","Norwegian Nynorsk":"Norvégien nynorsk","Norwegian Bokmål":"Norvégien bokmål","Norwegian":"Norvégien","Nyanja":"Chichewa","Occitan":"Occitane","Ojibwa":"Ojibwa","Oriya (macrolanguage)":"Oriya","Oromo":"Galla","Ossetian":"Ossète","Panjabi":"Pendjabi","Pakistan Sign Language":"Langue des signes pakistanaise","Polish":"Polonais","Portuguese":"Portugais","Pushto":"Pachto","Quechua":"Quechua","Romansh":"Romanche","Romanian":"Roumain","Russian Sign Language":"Langue des signes russe","Rundi":"Rundi","Russian":"Russe","Sango":"Sango","Saudi Arabian Sign Language":"Langue des signes saoudienne","South African Sign Language":"Langue des signes sud-africaine","Sinhala":"Singhalais","Slovak":"Slovaque","Slovenian":"Slovène","Northern Sami":"Sami du Nord","Samoan":"Samoan","Shona":"Shona","Sindhi":"Sindhi","Somali":"Somali","Southern Sotho":"Sotho du Sud","Spanish":"Espagnol","Albanian":"Albanais","Sardinian":"Sarde","Serbian":"Serbe","Swati":"Swati","Sundanese":"Soundanais","Swahili (macrolanguage)":"Swahili","Swedish":"Suédois","Swedish Sign Language":"Langue des signes suédoise","Tahitian":"Tahitien","Tamil":"Tamoul","Tatar":"Tatar","Telugu":"Télougou","Tajik":"Tadjik","Tagalog":"Tagalog","Thai":"Thaï","Tigrinya":"Tigrigna","Klingon":"Klingon","Tonga (Tonga Islands)":"Tongan (Îles Tonga)","Tswana":"Tswana","Tsonga":"Tsonga","Turkmen":"Turkmène","Turkish":"Turc","Twi":"Twi","Uighur":"Ouïgour","Ukrainian":"Ukrainien","Urdu":"Ourdou","Uzbek":"Ouszbek","Venda":"Venda","Vietnamese":"Vietnamien","Walloon":"Wallon","Wolof":"Wolof","Xhosa":"Xhosa","Yiddish":"Yiddish","Yoruba":"Yoruba","Zhuang":"Zhuang","Chinese":"Chinois","Zulu":"Zoulou"} \ No newline at end of file
diff --git a/client/src/locale/target/server_it_IT.json b/client/src/locale/target/server_it_IT.json
new file mode 100644
index 000000000..6586f622e
--- /dev/null
+++ b/client/src/locale/target/server_it_IT.json
@@ -0,0 +1 @@
{"Music":"Musica","Films":"Film","Vehicles":"Veicoli","Art":"Arte","Sports":"Sport","Travels":"Viaggi","Gaming":"Giochi","People":"Persone","Comedy":"Commedia","Entertainment":"Intrattenimento","News & Politics":"Notizie & Politica","How To":"Come fare","Education":"Educazione","Activism":"Attivismo","Science & Technology":"Scienza & Tecnologia","Animals":"Animali","Kids":"Bambini","Food":"Cibo","Attribution":"Attribuzione","Attribution - Share Alike":"Attribuzione - Condividi Allo Stesso Modo","Attribution - No Derivatives":"Attribuzione - Non Opere Derivate","Attribution - Non Commercial":"Attribuzione - Non Commerciale","Attribution - Non Commercial - Share Alike":"Attribuzione - Non Commerciale - Condividi Allo Stesso Modo","Attribution - Non Commercial - No Derivatives":"Attribuzione - Non Commerciale - Non Opere Derivate","Public Domain Dedication":"Pubblico Dominio","Public":"Pubblico","Unlisted":"Non elencato","Private":"Privato","Published":"Pubblicato","To transcode":"Da codificare","To import":"Da importare","Pending":"In sospeso","Success":"Successo","Failed":"Fallito","Misc":"Altro","Unknown":"Sconosciuto","Afar":"Afar","Abkhazian":"Abcaso","Afrikaans":"Afrikaans","Akan":"Akan","Amharic":"Amarico","Arabic":"Arabo","Aragonese":"Aragonese","American Sign Language":"Lingua dei Segni Americana","Assamese":"Assamese","Avaric":"Avarico","Kotava":"Kotava","Aymara":"Aymara","Azerbaijani":"Azero","Bashkir":"Bashkir","Bambara":"Bambara","Belarusian":"Bielorusso","Bengali":"Bengalese","British Sign Language":"Lingua dei Segni Britannica","Bislama":"Bislama","Tibetan":"Tibetano","Bosnian":"Bosniaco","Breton":"Bretone","Bulgarian":"Bulgaro","Brazilian Sign Language":"Lingua dei Segni Brasiliana","Catalan":"Catalano","Czech":"Ceco","Chamorro":"Chamorro","Chechen":"Ceceno","Chuvash":"Ciuvascio","Cornish":"Cornico","Corsican":"Corso","Cree":"Cree","Czech Sign Language":"Lingua dei Segni Ceca","Chinese Sign Language":"Lingua dei Segni Cinese","Welsh":"Gallese","Danish":"Danese","German":"Tedesco","Dhivehi":"Dhivehi","Danish Sign Language":"Lingua dei Segni Danese","Dzongkha":"Dzongkha","Modern Greek (1453-)":"Greco Moderno (1453-)","English":"Inglese","Esperanto":"Esperanto","Estonian":"Estone","Basque":"Basco","Ewe":"Ewe","Faroese":"Faroese","Persian":"Persiano","Fijian":"Fijiano","Finnish":"Finlandese","French":"Francese","Western Frisian":"Frisone Occidentale","French Sign Language":"Lingua dei Segni Francese","Fulah":"Fula","Scottish Gaelic":"Gaelico Scozzese","Irish":"Irlandese","Galician":"Galiziano","Manx":"Mannese","Guarani":"Guarani","German Sign Language":"Lingua dei Segni Tedesca","Gujarati":"Gujarati","Haitian":"Haitiano","Hausa":"Hausa","Serbo-Croatian":"Serbocroato","Hebrew":"Ebraico","Herero":"Herero","Hindi":"Hindi","Hiri Motu":"Hiri Motu","Croatian":"Croato","Hungarian":"Ungherese","Armenian":"Armeno","Igbo":"Igbo","Sichuan Yi":"Sichuan Yi","Inuktitut":"Inuktitut","Indonesian":"Indonesiano","Inupiaq":"Inupiaq","Icelandic":"Islandese","Italian":"Italiano","Javanese":"Giavanese","Lojban":"Lojban","Japanese":"Giapponese","Japanese Sign Language":"Lingua dei Segni Giapponese","Kalaallisut":"Kalaallisut","Kannada":"Kannada","Kashmiri":"Kashmiri","Georgian":"Georgiano","Kanuri":"Kanuri","Kazakh":"Kazako","Khmer":"Khmer","Kikuyu":"Kikuyu","Kinyarwanda":"Kinyarwanda","Kirghiz":"Kirghiso","Komi":"Komi","Kongo":"Kongo","Korean":"Coreano","Kuanyama":"Kuanyama","Kurdish":"Curdo","Lao":"Lao","Latvian":"Lettone","Limburgan":"Limburghese","Lingala":"Lingala","Lithuanian":"Lituano","Luxembourgish":"Lussemburghese","Luba-Katanga":"Luba-Katanga","Ganda":"Ganda","Marshallese":"Marshallese","Malayalam":"Malayalam","Marathi":"Marathi","Macedonian":"Macedone","Malagasy":"Malgascio","Maltese":"Maltese","Mongolian":"Mongolo","Maori":"Maori","Malay (macrolanguage)":"Malay (macrolinguaggio)","Burmese":"Birmano","Nauru":"Nauru","Navajo":"Navajo","South Ndebele":"Ndebele Meridionale","North Ndebele":"Ndebele Settentrionale","Ndonga":"Ndonga","Nepali (macrolanguage)":"Nepalese (macrolinguaggio)","Dutch":"Olandese","Norwegian Nynorsk":"Norvegese Nynorsk","Norwegian Bokmål":"Norvegese Bokmål","Norwegian":"Norvegese","Nyanja":"Chewa","Occitan":"Occitano","Ojibwa":"Ojibwa","Oriya (macrolanguage)":"Oriya (macrolinguaggio)","Oromo":"Oromo","Ossetian":"Osseto","Panjabi":"Punjabi","Pakistan Sign Language":"Lingua dei Segni Pakistana","Polish":"Polacco","Portuguese":"Portoghese","Pushto":"Pashto","Quechua":"Quechua","Romansh":"Romancio","Romanian":"Romeno","Russian Sign Language":"Lingua dei Segni Russa","Rundi":"Rundi","Russian":"Russo","Sango":"Sango","Saudi Arabian Sign Language":"Lingua dei Segni dell'Arabia Saudita","South African Sign Language":"Lingua dei Segni Sudafricana","Sinhala":"Singalese","Slovak":"Slovacco","Slovenian":"Sloveno","Northern Sami":"Sami Settentrionale","Samoan":"Samoano","Shona":"Shona","Sindhi":"Sindhi","Somali":"Somalo","Southern Sotho":"Sotho Meridionale","Spanish":"Spagnolo","Albanian":"Albanese","Sardinian":"Sardo","Serbian":"Serbo","Swati":"Swati","Sundanese":"Sondanese","Swahili (macrolanguage)":"Swahili (macrolinguaggio)","Swedish":"Svedese","Swedish Sign Language":"Lingua dei Segni Svedese","Tahitian":"Tahitiano","Tamil":"Tamil","Tatar":"Tataro","Telugu":"Telugu","Tajik":"Tagico","Tagalog":"Tagalog","Thai":"Thai","Tigrinya":"Tigrino","Klingon":"Klingon","Tonga (Tonga Islands)":"Tonga (Isole delle Tonga)","Tswana":"Tswana","Tsonga":"Tsonga","Turkmen":"Turcmeno","Turkish":"Turco","Twi":"Twi","Uighur":"Uighuro","Ukrainian":"Ucraino","Urdu":"Urdu","Uzbek":"Uzbeco","Venda":"Venda","Vietnamese":"Vietnamita","Walloon":"Vallone","Wolof":"Wolof","Xhosa":"Xhosa","Yiddish":"Yiddish","Yoruba":"Yoruba","Zhuang":"Zhuang","Chinese":"Cinese","Zulu":"Zulu"} \ No newline at end of file
diff --git a/client/src/locale/target/server_nl_NL.xml b/client/src/locale/target/server_nl_NL.xml
index 797d022c5..a53a90588 100644
--- a/client/src/locale/target/server_nl_NL.xml
+++ b/client/src/locale/target/server_nl_NL.xml
@@ -43,6 +43,10 @@
43 <source>Entertainment</source> 43 <source>Entertainment</source>
44 <target>Entertainment</target> 44 <target>Entertainment</target>
45 </trans-unit> 45 </trans-unit>
46 <trans-unit id="News &amp; Politics">
47 <source>News &amp; Politics</source>
48 <target>Nieuws en Politiek</target>
49 </trans-unit>
46 <trans-unit id="How To"> 50 <trans-unit id="How To">
47 <source>How To</source> 51 <source>How To</source>
48 <target>Tutorials</target> 52 <target>Tutorials</target>
@@ -57,7 +61,7 @@
57 </trans-unit> 61 </trans-unit>
58 <trans-unit id="Science &amp; Technology"> 62 <trans-unit id="Science &amp; Technology">
59 <source>Science &amp; Technology</source> 63 <source>Science &amp; Technology</source>
60 <target>Wetenschap &amp; technologie</target> 64 <target>Wetenschap en technologie</target>
61 </trans-unit> 65 </trans-unit>
62 <trans-unit id="Animals"> 66 <trans-unit id="Animals">
63 <source>Animals</source> 67 <source>Animals</source>
@@ -77,7 +81,7 @@
77 </trans-unit> 81 </trans-unit>
78 <trans-unit id="Attribution - Share Alike"> 82 <trans-unit id="Attribution - Share Alike">
79 <source>Attribution - Share Alike</source> 83 <source>Attribution - Share Alike</source>
80 <target>Naamsvermelding – Gelijk Delen</target> 84 <target>Naamsvermelding – Gelijken Delen</target>
81 </trans-unit> 85 </trans-unit>
82 <trans-unit id="Attribution - No Derivatives"> 86 <trans-unit id="Attribution - No Derivatives">
83 <source>Attribution - No Derivatives</source> 87 <source>Attribution - No Derivatives</source>
@@ -111,9 +115,33 @@
111 <source>Private</source> 115 <source>Private</source>
112 <target>Privé</target> 116 <target>Privé</target>
113 </trans-unit> 117 </trans-unit>
118 <trans-unit id="Published">
119 <source>Published</source>
120 <target>Gepubliceerd</target>
121 </trans-unit>
122 <trans-unit id="To transcode">
123 <source>To transcode</source>
124 <target>Transcoden</target>
125 </trans-unit>
126 <trans-unit id="To import">
127 <source>To import</source>
128 <target>Importeren</target>
129 </trans-unit>
130 <trans-unit id="Pending">
131 <source>Pending</source>
132 <target>In behandeling</target>
133 </trans-unit>
134 <trans-unit id="Success">
135 <source>Success</source>
136 <target>Success</target>
137 </trans-unit>
138 <trans-unit id="Failed">
139 <source>Failed</source>
140 <target>Gefaald</target>
141 </trans-unit>
114 <trans-unit id="Misc"> 142 <trans-unit id="Misc">
115 <source>Misc</source> 143 <source>Misc</source>
116 <target>Diverse</target> 144 <target>Varia</target>
117 </trans-unit> 145 </trans-unit>
118 <trans-unit id="Unknown"> 146 <trans-unit id="Unknown">
119 <source>Unknown</source> 147 <source>Unknown</source>
diff --git a/client/src/locale/target/server_pl_PL.json b/client/src/locale/target/server_pl_PL.json
new file mode 100644
index 000000000..90973bf28
--- /dev/null
+++ b/client/src/locale/target/server_pl_PL.json
@@ -0,0 +1 @@
{"Music":"Muzyka","Films":"Filmy","Vehicles":"Pojazdy","Art":"Sztuka","Sports":"Sport","Travels":"Podróże","Gaming":"Gry","People":"Ludzie","Comedy":"Komedia","Entertainment":"Rozrywka","How To":"Poradniki","Education":"Edukacja","Activism":"Aktywizm","Science & Technology":"Nauka i technologia","Animals":"ZwierzÄ™ta","Kids":"Dzieci","Food":"Jedzenie","Attribution":"Uznanie autostwa","Attribution - Share Alike":"Uznanie autorstwa - Na tych samych warunkach","Attribution - No Derivatives":"Uznanie autorstwa - Bez utworów zależnych","Attribution - Non Commercial":"Uznanie autorstwa - Użycie niekomercyjne","Attribution - Non Commercial - Share Alike":"Uznanie autorstwa - Użycie niekomercyjne - Na tych samych warunkach","Attribution - Non Commercial - No Derivatives":"Uznanie autorstwa - Użycie niekomercyjne - Bez utworów zależnych","Public Domain Dedication":"Przekazanie do Domeny Publicznej","Public":"Publiczne","Unlisted":"Niewypisane","Private":"Prywatne","Published":"Opublikowano","To transcode":"Transkodować","To import":"Importować","Pending":"Oczekiwanie","Success":"Sukces","Failed":"Niepowodzenie","Misc":"Różne","Unknown":"Nieznane","Afar":"Afar","Abkhazian":"Abchaski","Afrikaans":"Afrikaans","Akan":"Akan","Amharic":"Amharski","Arabic":"Arabski","American Sign Language":"AmerykaÅ„ski JÄ™zyk Migowy","Avaric":"Awarski","Bashkir":"Baszkirski","Bambara":"Bambara","Belarusian":"BiaÅ‚oruski","Bengali":"Bengalski","British Sign Language":"Brytyjski JÄ™zyk Migowy","Bislama":"Bislama","Tibetan":"TybetaÅ„ski","Bosnian":"BoÅ›niacki","Breton":"BretoÅ„ski","Bulgarian":"BuÅ‚garski","Catalan":"KataloÅ„ski","Czech":"Czeski","Cornish":"Kornijski","Corsican":"KorsykaÅ„ski","Cree":"Kri","Czech Sign Language":"Czeski JÄ™zyk Migowy","Chinese Sign Language":"ChiÅ„ski JÄ™zyk Migowy","Welsh":"Walijski","Danish":"DuÅ„ski","German":"Niemiecki","Danish Sign Language":"DuÅ„ski JÄ™zyk Migowy","Dzongkha":"Dzongkha","Modern Greek (1453-)":"Nowogrecki (1453-)","English":"Angielski","Estonian":"EstoÅ„ski","Basque":"Baskijski","Ewe":"Ewe","Persian":"Perski","Fijian":"Fidżyjski","Finnish":"FiÅ„ski","French":"Francuski","French Sign Language":"Francuski JÄ™zyk Migowy","Fulah":"Ful","Irish":"Irlandzki","Galician":"Galicyjski","German Sign Language":"Niemiecki JÄ™zyk Migowy","Hausa":"Hausa","Serbo-Croatian":"Serbsko-Chorwacki","Hindi":"Hindi","Croatian":"Chorwacki","Hungarian":"WÄ™gierski","Armenian":"OrmaÅ„ski","Igbo":"Igbo","Indonesian":"Indonezyjski","Icelandic":"Islandzki","Italian":"WÅ‚oski","Javanese":"Jawajski","Japanese":"JapoÅ„ski","Japanese Sign Language":"JapoÅ„ski JÄ™zyk Migowy","Komi":"Komi","Kongo":"Kongo","Korean":"KoreaÅ„ski","Kurdish":"Kurdyjski","Lao":"LaotaÅ„ski","Latvian":"Åotewski","Lithuanian":"Litewski","Luxembourgish":"Luksemburski","Nauru":"NauraÅ„ski","Dutch":"Holenderski","Norwegian Nynorsk":"Norweski Nynorsk","Norwegian BokmÃ¥l":"Norweski BokmÃ¥l","Norwegian":"Norweski","Oromo":"Oromo","Polish":"Polski","Portuguese":"Portugalski","Pushto":"Paszto","Romansh":"Romansz","Romanian":"RumuÅ„ski","Russian Sign Language":"Rosyjski JÄ™zyk Migowy","Rundi":"Rundi","Russian":"Rosyjski","Sango":"Sango","Slovak":"SÅ‚owacki","Slovenian":"SÅ‚oweÅ„ski","Samoan":"SamoaÅ„ski","Shona":"Shona","Sindhi":"Sindhi","Somali":"Somalijski","Spanish":"HiszpaÅ„ski","Serbian":"Serbski","Swedish":"Szwedzki","Swedish Sign Language":"Szwedzki JÄ™zyk Migowy","Tamil":"Tamilski","Tatar":"Tatarski","Telugu":"Telugu","Tajik":"Tadżycki","Tagalog":"Tagalski","Thai":"Tajski","Turkmen":"TurkmeÅ„ski","Turkish":"Turecki","Twi":"Twi","Ukrainian":"UkraiÅ„ski","Urdu":"Urdu","Uzbek":"Uzbecki","Venda":"Venda","Vietnamese":"Wietnamski","Walloon":"WaloÅ„ski","Wolof":"Wolof","Xhosa":"Xhosa","Yiddish":"Jidysz","Yoruba":"Joruba","Zhuang":"Zhuang","Chinese":"ChiÅ„ski","Zulu":"Zulu"} \ No newline at end of file
diff --git a/client/src/locale/target/server_pl_PL.xml b/client/src/locale/target/server_pl_PL.xml
deleted file mode 100644
index f5ce3f9ad..000000000
--- a/client/src/locale/target/server_pl_PL.xml
+++ /dev/null
@@ -1,147 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!--XLIFF document generated by Zanata. Visit http://zanata.org for more infomation.-->
3<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" xmlns:xyz="urn:appInfo:Items" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd" version="1.1">
4 <file source-language="en-US" datatype="plaintext" original="" target-language="pl-PL">
5 <body>
6 <trans-unit id="Music">
7 <source>Music</source>
8 <target>Muzyka</target>
9 </trans-unit>
10 <trans-unit id="Films">
11 <source>Films</source>
12 <target>Filmy</target>
13 </trans-unit>
14 <trans-unit id="Vehicles">
15 <source>Vehicles</source>
16 <target>Pojazdy</target>
17 </trans-unit>
18 <trans-unit id="Art">
19 <source>Art</source>
20 <target>Sztuka</target>
21 </trans-unit>
22 <trans-unit id="Sports">
23 <source>Sports</source>
24 <target>Sport</target>
25 </trans-unit>
26 <trans-unit id="Travels">
27 <source>Travels</source>
28 <target>Podróże</target>
29 </trans-unit>
30 <trans-unit id="Gaming">
31 <source>Gaming</source>
32 <target>Gry</target>
33 </trans-unit>
34 <trans-unit id="People">
35 <source>People</source>
36 <target>Ludzie</target>
37 </trans-unit>
38 <trans-unit id="Comedy">
39 <source>Comedy</source>
40 <target>Komedia</target>
41 </trans-unit>
42 <trans-unit id="Entertainment">
43 <source>Entertainment</source>
44 <target>Rozrywka</target>
45 </trans-unit>
46 <trans-unit id="How To">
47 <source>How To</source>
48 <target>Poradniki</target>
49 </trans-unit>
50 <trans-unit id="Education">
51 <source>Education</source>
52 <target>Edukacja</target>
53 </trans-unit>
54 <trans-unit id="Activism">
55 <source>Activism</source>
56 <target>Aktywizm</target>
57 </trans-unit>
58 <trans-unit id="Science &amp; Technology">
59 <source>Science &amp; Technology</source>
60 <target>Nauka i technologia</target>
61 </trans-unit>
62 <trans-unit id="Animals">
63 <source>Animals</source>
64 <target>Zwierzęta</target>
65 </trans-unit>
66 <trans-unit id="Kids">
67 <source>Kids</source>
68 <target>Dzieci</target>
69 </trans-unit>
70 <trans-unit id="Food">
71 <source>Food</source>
72 <target>Jedzenie</target>
73 </trans-unit>
74 <trans-unit id="Attribution">
75 <source>Attribution</source>
76 <target>Uznanie autostwa</target>
77 </trans-unit>
78 <trans-unit id="Attribution - Share Alike">
79 <source>Attribution - Share Alike</source>
80 <target>Uznanie autorstwa - Na tych samych warunkach</target>
81 </trans-unit>
82 <trans-unit id="Attribution - No Derivatives">
83 <source>Attribution - No Derivatives</source>
84 <target>Uznanie autorstwa - Bez utworów zależnych</target>
85 </trans-unit>
86 <trans-unit id="Attribution - Non Commercial">
87 <source>Attribution - Non Commercial</source>
88 <target>Uznanie autorstwa - Użycie niekomercyjne</target>
89 </trans-unit>
90 <trans-unit id="Attribution - Non Commercial - Share Alike">
91 <source>Attribution - Non Commercial - Share Alike</source>
92 <target>Uznanie autorstwa - Użycie niekomercyjne - Na tych samych warunkach</target>
93 </trans-unit>
94 <trans-unit id="Attribution - Non Commercial - No Derivatives">
95 <source>Attribution - Non Commercial - No Derivatives</source>
96 <target>Uznanie autorstwa - Użycie niekomercyjne - Bez utworów zależnych</target>
97 </trans-unit>
98 <trans-unit id="Public Domain Dedication">
99 <source>Public Domain Dedication</source>
100 <target>Przekazanie do Domeny Publicznej</target>
101 </trans-unit>
102 <trans-unit id="Public">
103 <source>Public</source>
104 <target>Publiczne</target>
105 </trans-unit>
106 <trans-unit id="Unlisted">
107 <source>Unlisted</source>
108 <target>Niewypisane</target>
109 </trans-unit>
110 <trans-unit id="Private">
111 <source>Private</source>
112 <target>Prywatne</target>
113 </trans-unit>
114 <trans-unit id="Published">
115 <source>Published</source>
116 <target>Opublikowano</target>
117 </trans-unit>
118 <trans-unit id="To transcode">
119 <source>To transcode</source>
120 <target>Transkodować</target>
121 </trans-unit>
122 <trans-unit id="To import">
123 <source>To import</source>
124 <target>Importować</target>
125 </trans-unit>
126 <trans-unit id="Pending">
127 <source>Pending</source>
128 <target>Oczekiwanie</target>
129 </trans-unit>
130 <trans-unit id="Success">
131 <source>Success</source>
132 <target>Sukces</target>
133 </trans-unit>
134 <trans-unit id="Failed">
135 <source>Failed</source>
136 <target>Niepowodzenie</target>
137 </trans-unit>
138 <trans-unit id="Misc">
139 <source>Misc</source>
140 <target>Różne</target>
141 </trans-unit>
142 <trans-unit id="Unknown">
143 <source>Unknown</source>
144 <target>Nieznane</target>
145 </trans-unit>
146 </body>
147 </file></xliff> \ No newline at end of file
diff --git a/client/src/locale/target/server_ru_RU.json b/client/src/locale/target/server_ru_RU.json
new file mode 100644
index 000000000..e62f2aeb4
--- /dev/null
+++ b/client/src/locale/target/server_ru_RU.json
@@ -0,0 +1 @@
{"Music":"Музыка","Films":"Филмы","Vehicles":"ТранÑпортные ÑредÑтва","Art":"ИÑкуÑÑтво","Sports":"Спорт","Travels":"ПутешеÑтвиÑ","Gaming":"Видеоигры","People":"Люди","Comedy":"КомедиÑ","Entertainment":"РазвлечениÑ","How To":"Как","Education":"Образование","Activism":"Ðктивизм","Science & Technology":"Ðаука и ТехнологиÑ","Animals":"Животные ","Kids":"Дети","Food":"Еда","Attribution":"ÐтрибуциÑ","Attribution - Share Alike":" ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ†Ð¸Ñ - Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ‹Ð¼Ð¸ уÑловиÑми ","Attribution - No Derivatives":"ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ†Ð¸Ñ - без права Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ","Attribution - Non Commercial":"ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ†Ð¸Ñ - не коммерчеÑкое иÑпользование","Attribution - Non Commercial - Share Alike":"ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ†Ð¸Ñ - не коммерчеÑкое иÑпользование - Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ‹Ð¼Ð¸ уÑловиÑми","Attribution - Non Commercial - No Derivatives":"ÐÑ‚Ñ€Ð¸Ð±ÑƒÑ†Ð¸Ñ - не коммерчеÑкое иÑпользование - без права изменениÑ","Public Domain Dedication":"Безлицензионный","Public":"ОбщеÑтвенный","Unlisted":" Ее включённый в ÑпиÑок","Private":"Личный","Published":"Опубликованный","To transcode":"Перекодировать","To import":"Импортировать","Pending":"Ð’ ожидании","Success":"Удачное завершение","Failed":"Ðеудачно","Misc":"Разное","Unknown":"ÐеизвеÑтное","Afar":"ÐфарÑкий","Abkhazian":"ÐбхазÑкий","Afrikaans":"ÐфрикаанÑ","Akan":"Ðкан","Amharic":"ÐмхарÑкий","Arabic":"ÐрабÑкий","Aragonese":"ÐрагонÑкий","American Sign Language":"ÐмÑлен","Assamese":"ÐÑÑамÑкий","Avaric":"ÐварÑкий","Kotava":"Котава","Aymara":"Ðймара","Azerbaijani":"ÐзербайджанÑкий","Bashkir":"БашкирÑкий","Bambara":"Бамана","Belarusian":"БелоруÑÑкий","Bengali":"БенгальÑкий","British Sign Language":"БританÑкий жеÑтовый","Bislama":"БиÑлама","Tibetan":"ТибетÑкий","Bosnian":"БоÑнийÑкий","Breton":"БретонÑкий","Bulgarian":"БолгарÑкий","Brazilian Sign Language":"БразильÑкий жеÑтовый","Catalan":"КаталанÑкий","Czech":"ЧешÑкий","Chamorro":"Чаморро","Chechen":"ЧеченÑкий","Chuvash":"ЧувашÑкий","Cornish":"КорнÑкий","Corsican":"КорÑиканÑкий","Cree":"Кри","Czech Sign Language":"ЧешÑкий жеÑтовый","Chinese Sign Language":"КитайÑкий жеÑтовый","Welsh":"УÑлш","Danish":"ДатÑкий","German":"Ðемецкий","Dhivehi":"Дивехи","Danish Sign Language":"ДатÑкий жеÑтовый ","Dzongkha":"Дзонг-кÑ","Modern Greek (1453-)":"Современный гречеÑкий","English":"ÐнглийÑкий","Esperanto":"ЭÑперанто","Estonian":"ЭÑтонÑкий","Basque":"БаÑкÑкий","Ewe":"Эве","Faroese":"ФарерÑкий","Persian":"ПерÑидÑкий","Fijian":"ФиджийÑкий","Finnish":"ФинÑкий","French":"ФранцузÑкий","Western Frisian":"ЗападнофризÑкий","French Sign Language":"ФранцузÑкий жеÑтовый","Fulah":"Фула","Scottish Gaelic":"ШотландÑкий","Irish":"ИрландÑкий","Galician":"ГалиÑийÑкий","Manx":"ÐœÑнÑкий","Guarani":"Гуарани","German Sign Language":"Ðемецкий жеÑтовый","Gujarati":"Гуджарати","Haitian":"ГаитÑнÑкий креольÑкий","Hausa":"ХауÑа","Serbo-Croatian":"СербохорватÑкий","Hebrew":"Иврит","Herero":"Гереро","Hindi":"Хинди","Hiri Motu":"Хири-моту","Croatian":"ХорватÑкий","Hungarian":"ВенгерÑкий","Armenian":"ÐрмÑнÑкий","Igbo":"Игбо","Sichuan Yi":"ÐоÑу","Inuktitut":"Инуктитут","Indonesian":"ИндонезийÑкий","Inupiaq":"ÐлÑÑкинÑко-инуитÑкие","Icelandic":"ИÑландÑкий","Italian":"ИтальÑнÑкий","Javanese":"ЯванÑкий","Lojban":"Ложбан","Japanese":"ЯпонÑкий","Japanese Sign Language":"ЯпонÑкий жеÑтовый","Kalaallisut":"ГренландÑкий","Kannada":"Каннада","Kashmiri":"КашмирÑкий","Georgian":"ГрузинÑкий","Kanuri":"Канури","Kazakh":"КазахÑкий","Khmer":"КхмерÑкий","Kikuyu":"Кикуйю","Kinyarwanda":"Руанда","Kirghiz":"КиргизÑкий","Komi":"Коми","Kongo":"Конго","Korean":"КорейÑкий","Kuanyama":"КваньÑма","Kurdish":"КурдÑкие","Lao":"ЛаоÑÑкий","Latvian":"ЛатышÑкий","Limburgan":"ЛимбургÑкий","Lingala":"Лингала","Lithuanian":"ЛитовÑкий","Luxembourgish":"ЛюкÑембургÑкий","Luba-Katanga":"Луба-катанга","Ganda":"Луганда","Marshallese":"МаршалльÑкий","Malayalam":"МалаÑлам","Marathi":"Маратхи","Macedonian":"МакедонÑкий","Malagasy":"МалагаÑийÑкий","Maltese":"МальтийÑкий","Mongolian":"МонгольÑкий","Maori":"Маори","Malay (macrolanguage)":"МалайÑкий","Burmese":"БирманÑкий","Nauru":"ÐауруанÑкий","Navajo":"Ðавахо","South Ndebele":"Южный ндебеле","North Ndebele":"Северный ндебеле","Ndonga":"Ðдонга","Nepali (macrolanguage)":"ÐепальÑкий","Dutch":"ÐидерландÑкий","Norwegian Nynorsk":"ÐовонорвежÑкий","Norwegian BokmÃ¥l":"Букмол","Norwegian":"ÐорвежÑкий","Nyanja":"ÐÑŒÑнджа","Ojibwa":"Оджибве","Oriya (macrolanguage)":"ОриÑ","Oromo":"Оромо","Ossetian":"ОÑетинÑкий","Panjabi":"Панджаби","Pakistan Sign Language":"ДагеÑтанÑкий ","Polish":"ПольÑкий","Portuguese":"ПортугальÑкий","Pushto":"Пушту","Quechua":"КеÌчуа","Romansh":"РоманшÑкий","Romanian":"РумынÑкий","Russian Sign Language":"РуÑÑкий жеÑтовый","Rundi":"Рунди","Russian":"РуÑÑкий","Sango":"Санго","Saudi Arabian Sign Language":"ÐрабÑкий жеÑтовый","South African Sign Language":"ЖеÑтовый Южной Ðфрики","Sinhala":"СингальÑкий","Slovak":"Словацкий","Slovenian":"СловенÑкий","Northern Sami":"СеверноÑаамÑкий","Samoan":"СамоанÑкий","Shona":"Шона","Sindhi":"Синдхи","Somali":"СомалийÑкий","Southern Sotho":"СеÑото","Spanish":"ИÑпанÑкий","Albanian":"ÐлбанÑкий","Sardinian":"СардинÑкий","Serbian":"СербÑкий","Swati":"Свати","Sundanese":"СунданÑкий","Swahili (macrolanguage)":"Суахили","Swedish":"ШведÑкий","Swedish Sign Language":"ШведÑкий жеÑтовый","Tahitian":"ТаитÑнÑкий","Tamil":"ТамильÑкий","Tatar":"ТатарÑкий","Telugu":"Телугу","Tajik":"ТаджикÑкий","Tagalog":"ТагальÑкий","Thai":"ТайÑкий","Tigrinya":"ТигриньÑ","Klingon":"КлингонÑкий","Tonga (Tonga Islands)":"ТонганÑкий","Tswana":"ТÑвана","Tsonga":"ТÑонга","Turkmen":"ТуркменÑкий","Turkish":"Турецкий","Twi":"Чви","Uighur":"УйгурÑкий","Ukrainian":"УкраинÑкий","Urdu":"Урду","Uzbek":"УзбекÑкий","Venda":"Венда","Vietnamese":"ВьетнамÑкий","Walloon":"ВаллонÑкий","Wolof":"Волоф","Xhosa":"КоÑа","Yiddish":"Идиш","Yoruba":"Йоруба","Zhuang":"ЧжуанÑкий","Chinese":"КитайÑкий","Zulu":"Зулу"} \ No newline at end of file
diff --git a/client/src/manifest.webmanifest b/client/src/manifest.webmanifest
index 3d3c7d6d5..851e098a8 100644
--- a/client/src/manifest.webmanifest
+++ b/client/src/manifest.webmanifest
@@ -43,5 +43,5 @@
43 ], 43 ],
44 "name": "PeerTube", 44 "name": "PeerTube",
45 "short_name": "PeerTube", 45 "short_name": "PeerTube",
46 "start_url": "/videos/trending" 46 "start_url": "/"
47} 47}
diff --git a/client/src/polyfills.ts b/client/src/polyfills.ts
index 5dff18632..368908432 100644
--- a/client/src/polyfills.ts
+++ b/client/src/polyfills.ts
@@ -45,7 +45,13 @@ import 'core-js/es7/object'
45/** IE10 and IE11 requires the following for the Reflect API. */ 45/** IE10 and IE11 requires the following for the Reflect API. */
46 46
47// For Google Bot 47// For Google Bot
48import 'core-js/es6/reflect' 48// import 'core-js/es6/reflect'; // --> dealt with in src/environment.ts
49
50/**
51 * Evergreen browsers require these.
52 */
53// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
54// import 'core-js/es7/reflect' // --> dealt with in src/environment.ts
49 55
50/** 56/**
51 * Required to support Web Animations `@angular/platform-browser/animations`. 57 * Required to support Web Animations `@angular/platform-browser/animations`.
diff --git a/client/src/sass/application.scss b/client/src/sass/application.scss
index 2356f9837..478737a43 100644
--- a/client/src/sass/application.scss
+++ b/client/src/sass/application.scss
@@ -23,7 +23,7 @@ body {
23 // now beware node-sass requires interpolation 23 // now beware node-sass requires interpolation
24 // for css custom properties #{$var} 24 // for css custom properties #{$var}
25 --mainColor: #{$orange-color}; 25 --mainColor: #{$orange-color};
26 --mainHoverColor: #{$orange-hoover-color}; 26 --mainHoverColor: #{$orange-hover-color};
27 --mainBackgroundColor: #{$bg-color}; 27 --mainBackgroundColor: #{$bg-color};
28 --mainForegroundColor: #{$fg-color}; 28 --mainForegroundColor: #{$fg-color};
29 --menuBackgroundColor: #{$menu-background}; 29 --menuBackgroundColor: #{$menu-background};
@@ -229,13 +229,12 @@ label {
229 font-weight: $font-semibold; 229 font-weight: $font-semibold;
230 } 230 }
231 231
232 .close { 232 my-global-icon {
233 @include icon(24px); 233 @include icon(24px);
234 234
235 position: relative; 235 position: relative;
236 top: 3px; 236 top: 3px;
237 float: right; 237 float: right;
238 background-image: url('../assets/images/global/cross.svg');
239 238
240 margin: 0; 239 margin: 0;
241 padding: 0; 240 padding: 0;
@@ -293,6 +292,10 @@ ngb-tabset.bootstrap {
293 color: var(--mainForegroundColor) !important; 292 color: var(--mainForegroundColor) !important;
294 } 293 }
295 } 294 }
295
296 .nav-pills .nav-link.active {
297 color: #000 !important;
298 }
296} 299}
297 300
298.nav-tabs .nav-link.active { 301.nav-tabs .nav-link.active {
@@ -324,7 +327,7 @@ ngb-tabset.bootstrap {
324table { 327table {
325 .action-button-edit, .action-button-delete { 328 .action-button-edit, .action-button-delete {
326 &:hover, &:active, &:focus, &[disabled], &.disabled { 329 &:hover, &:active, &:focus, &[disabled], &.disabled {
327 background-color: $grey-color !important; 330 background-color: $grey-background-color !important;
328 } 331 }
329 } 332 }
330} 333}
@@ -389,4 +392,4 @@ table {
389 } 392 }
390 } 393 }
391 } 394 }
392} \ No newline at end of file 395}
diff --git a/client/src/sass/include/_bootstrap-variables.scss b/client/src/sass/include/_bootstrap-variables.scss
index 77a20cfe1..7f413836b 100644
--- a/client/src/sass/include/_bootstrap-variables.scss
+++ b/client/src/sass/include/_bootstrap-variables.scss
@@ -31,4 +31,5 @@ $input-focus-border-color: #ced4da;
31$nav-pills-link-active-bg: #F0F0F0; 31$nav-pills-link-active-bg: #F0F0F0;
32$nav-pills-link-active-color: #000; 32$nav-pills-link-active-color: #000;
33 33
34$zindex-dropdown: 10000; \ No newline at end of file 34$zindex-dropdown: 10000;
35$zindex-popover: 10000;
diff --git a/client/src/sass/include/_mixins.scss b/client/src/sass/include/_mixins.scss
index d6f391a45..e18e9ae9d 100644
--- a/client/src/sass/include/_mixins.scss
+++ b/client/src/sass/include/_mixins.scss
@@ -55,6 +55,18 @@
55 hyphens: auto; 55 hyphens: auto;
56} 56}
57 57
58@mixin apply-svg-color ($color) {
59 /deep/ svg {
60 path[fill="#000000"], g[fill="#000000"], rect[fill="#000000"], circle[fill="#000000"] {
61 fill: $color;
62 }
63
64 path[stroke="#000000"], g[stroke="#000000"], rect[stroke="#000000"], circle[stroke="#000000"] {
65 stroke: $color;
66 }
67 }
68}
69
58@mixin peertube-input-text($width) { 70@mixin peertube-input-text($width) {
59 display: inline-block; 71 display: inline-block;
60 height: $button-height; 72 height: $button-height;
@@ -64,6 +76,7 @@
64 border-radius: 3px; 76 border-radius: 3px;
65 padding-left: 15px; 77 padding-left: 15px;
66 padding-right: 15px; 78 padding-right: 15px;
79 font-size: 15px;
67 80
68 &::placeholder { 81 &::placeholder {
69 color: var(--inputPlaceholderColor); 82 color: var(--inputPlaceholderColor);
@@ -110,22 +123,30 @@
110 color: #fff; 123 color: #fff;
111 background-color: #C6C6C6; 124 background-color: #C6C6C6;
112 } 125 }
126
127 my-global-icon {
128 @include apply-svg-color(#fff)
129 }
113} 130}
114 131
115@mixin grey-button { 132@mixin grey-button {
116 &, &:active, &:focus { 133 &, &:active, &:focus {
117 background-color: $grey-color; 134 background-color: $grey-background-color;
118 color: #585858; 135 color: $grey-foreground-color;
119 } 136 }
120 137
121 &:hover, &:active, &:focus, &[disabled], &.disabled { 138 &:hover, &:active, &:focus, &[disabled], &.disabled {
122 color: #585858; 139 color: $grey-foreground-color;
123 background-color: $grey-hoover-color; 140 background-color: $grey-background-hover-color;
124 } 141 }
125 142
126 &[disabled], &.disabled { 143 &[disabled], &.disabled {
127 cursor: default; 144 cursor: default;
128 } 145 }
146
147 my-global-icon {
148 @include apply-svg-color($grey-foreground-color)
149 }
129} 150}
130 151
131@mixin peertube-button { 152@mixin peertube-button {
@@ -148,6 +169,15 @@
148 @include peertube-button; 169 @include peertube-button;
149} 170}
150 171
172@mixin button-with-icon($width: 20px, $margin-right: 3px, $top: -1px) {
173 my-global-icon {
174 position: relative;
175 width: $width;
176 margin-right: $margin-right;
177 top: $top;
178 }
179}
180
151@mixin peertube-button-file ($width) { 181@mixin peertube-button-file ($width) {
152 position: relative; 182 position: relative;
153 overflow: hidden; 183 overflow: hidden;
@@ -231,6 +261,10 @@
231 color: transparent; 261 color: transparent;
232 text-shadow: 0 0 0 #000; 262 text-shadow: 0 0 0 #000;
233 } 263 }
264
265 option {
266 color: #000;
267 }
234 } 268 }
235} 269}
236 270
@@ -455,18 +489,10 @@
455 } 489 }
456} 490}
457 491
458@mixin create-button ($imageUrl) { 492@mixin create-button {
459 @include peertube-button-link; 493 @include peertube-button-link;
460 @include orange-button; 494 @include orange-button;
461 495 @include button-with-icon(20px, 5px, -1px);
462 .icon.icon-add {
463 @include icon(20px);
464
465 position: relative;
466 top: -1px;
467 margin-right: 5px;
468 background-image: url($imageUrl);
469 }
470} 496}
471 497
472@mixin row-blocks { 498@mixin row-blocks {
diff --git a/client/src/sass/include/_variables.scss b/client/src/sass/include/_variables.scss
index fdf33b12a..3780b7501 100644
--- a/client/src/sass/include/_variables.scss
+++ b/client/src/sass/include/_variables.scss
@@ -6,10 +6,13 @@ $font-regular: 400;
6$font-semibold: 600; 6$font-semibold: 600;
7$font-bold: 700; 7$font-bold: 700;
8 8
9$grey-color: #E5E5E5; 9$grey-background-color: #E5E5E5;
10$grey-hoover-color: #EFEFEF;; 10$grey-background-hover-color: #EFEFEF;
11$grey-foreground-color: #585858;
12$grey-foreground-hover-color: #303030;
13
11$orange-color: #F1680D; 14$orange-color: #F1680D;
12$orange-hoover-color: #F97D46; 15$orange-hover-color: #F97D46;
13 16
14$bg-color: #fff; 17$bg-color: #fff;
15$fg-color: #000; 18$fg-color: #000;
diff --git a/client/src/sass/primeng-custom.scss b/client/src/sass/primeng-custom.scss
index 0568de4e2..6e502b028 100644
--- a/client/src/sass/primeng-custom.scss
+++ b/client/src/sass/primeng-custom.scss
@@ -2,7 +2,7 @@
2@import '_mixins'; 2@import '_mixins';
3 3
4@import '~primeng/resources/primeng.css'; 4@import '~primeng/resources/primeng.css';
5@import '~primeng/resources/themes/bootstrap/theme.css'; 5@import '~primeng/resources/themes/nova-light/theme.css';
6 6
7@mixin glyphicon-light { 7@mixin glyphicon-light {
8 font-family: 'Glyphicons Halflings'; 8 font-family: 'Glyphicons Halflings';
@@ -12,10 +12,9 @@
12 12
13// data table customizations 13// data table customizations
14p-table { 14p-table {
15 font-size: 15px !important;
16
17 .ui-table-caption { 15 .ui-table-caption {
18 border: none; 16 border: none !important;
17 background-color: var(--mainBackgroundColor) !important;
19 18
20 .caption { 19 .caption {
21 height: 40px; 20 height: 40px;
@@ -24,6 +23,17 @@ p-table {
24 } 23 }
25 } 24 }
26 25
26 th {
27 background-color: var(--mainBackgroundColor) !important;
28 outline: 0;
29 }
30
31 td, th {
32 font-family: $main-fonts;
33 font-size: 15px !important;
34 color: var(--mainForegroundColor) !important;
35 }
36
27 td { 37 td {
28 padding-left: 15px !important; 38 padding-left: 15px !important;
29 39
@@ -35,12 +45,16 @@ p-table {
35 } 45 }
36 46
37 tr { 47 tr {
48 outline: 0;
38 background-color: var(--mainBackgroundColor) !important; 49 background-color: var(--mainBackgroundColor) !important;
39 height: 46px; 50 height: 46px;
40 51
41 &.ui-state-highlight { 52 &.ui-state-highlight {
42 background-color:var(--submenuColor) !important; 53 background-color: var(--submenuColor) !important;
43 color:var(--mainForegroundColor) !important; 54
55 td, td > a {
56 color: var(--mainForegroundColor) !important;
57 }
44 } 58 }
45 } 59 }
46 60
@@ -56,6 +70,10 @@ p-table {
56 } 70 }
57 } 71 }
58 72
73 td {
74 border: none !important;
75 }
76
59 &:first-child td { 77 &:first-child td {
60 border-top: none !important; 78 border-top: none !important;
61 } 79 }
@@ -93,21 +111,25 @@ p-table {
93 } 111 }
94 112
95 &.ui-state-highlight { 113 &.ui-state-highlight {
96 background-color:var(--submenuColor) !important; 114 background-color: var(--submenuColor) !important;
97 115
98 .pi { 116 .pi {
99 @extend .glyphicon; 117 @extend .glyphicon;
100 118
101 color: #000; 119 color: #000 !important;
102 font-size: 11px; 120 font-size: 11px !important;
103 top: 0; 121 top: 0 !important;
104 122
105 &.pi-sort-up { 123 &.pi-sort-up {
106 @extend .glyphicon-triangle-top; 124 @extend .glyphicon-triangle-top;
125
126 color: var(--mainForegroundColor) !important;
107 } 127 }
108 128
109 &.pi-sort-down { 129 &.pi-sort-down {
110 @extend .glyphicon-triangle-bottom; 130 @extend .glyphicon-triangle-bottom;
131
132 color: var(--mainForegroundColor) !important;
111 } 133 }
112 } 134 }
113 } 135 }
@@ -175,13 +197,14 @@ p-table {
175 height: auto !important; 197 height: auto !important;
176 198
177 a { 199 a {
178 color: #000 !important; 200 color: var(--mainForegroundColor) !important;
179 font-weight: $font-semibold !important; 201 font-weight: $font-semibold !important;
180 margin: 0 10px !important; 202 margin: 0 5px !important;
181 outline: 0 !important; 203 outline: 0 !important;
182 border-radius: 3px !important; 204 border-radius: 3px !important;
183 padding: 5px 2px !important; 205 padding: 5px 2px !important;
184 height: auto !important; 206 height: auto !important;
207 line-height: initial !important;
185 208
186 &.ui-state-active { 209 &.ui-state-active {
187 &, &:hover, &:active, &:focus { 210 &, &:hover, &:active, &:focus {
@@ -210,11 +233,25 @@ p-calendar .ui-datepicker {
210 .ui-datepicker-next { 233 .ui-datepicker-next {
211 @extend .glyphicon-chevron-right; 234 @extend .glyphicon-chevron-right;
212 @include glyphicon-light; 235 @include glyphicon-light;
236
237 color: #000 !important;
238 text-align: right;
239
240 .pi.pi-chevron-right {
241 display: none !important;
242 }
213 } 243 }
214 244
215 .ui-datepicker-prev { 245 .ui-datepicker-prev {
216 @extend .glyphicon-chevron-left; 246 @extend .glyphicon-chevron-left;
217 @include glyphicon-light; 247 @include glyphicon-light;
248
249 color: #000 !important;
250 text-align: left;
251
252 .pi.pi-chevron-left {
253 display: none !important;
254 }
218 } 255 }
219 } 256 }
220 257
@@ -223,39 +260,118 @@ p-calendar .ui-datepicker {
223 .pi.pi-chevron-up { 260 .pi.pi-chevron-up {
224 @extend .glyphicon-chevron-up; 261 @extend .glyphicon-chevron-up;
225 @include glyphicon-light; 262 @include glyphicon-light;
263
264 color: #000 !important;
226 } 265 }
227 266
228 .pi.pi-chevron-down { 267 .pi.pi-chevron-down {
229 @extend .glyphicon-chevron-down; 268 @extend .glyphicon-chevron-down;
230 @include glyphicon-light; 269 @include glyphicon-light;
270
271 color: #000 !important;
272 }
273 }
274}
275
276.ui-chkbox {
277
278 &, .ui-chkbox-box {
279 width: 18px !important;
280 height: 18px !important;
281 }
282
283 .ui-chkbox-box {
284 &.ui-state-active {
285 border-color: var(--mainColor) !important;
286 background-color: var(--mainColor) !important;
287 }
288
289 .ui-chkbox-icon {
290 position: relative;
291 overflow: visible !important;
292
293 &:after {
294 content: '';
295 position: absolute;
296 top: 1px;
297 left: 6px;
298 width: 5px;
299 height: 12px;
300 opacity: 0;
301 transform: rotate(45deg) scale(0);
302 border-right: 2px solid var(--mainBackgroundColor);
303 border-bottom: 2px solid var(--mainBackgroundColor);
304 }
305
306 &.pi-check:after {
307 opacity: 1;
308 transform: rotate(45deg) scale(1);
309 }
231 } 310 }
232 } 311 }
233} 312}
234 313
235.ui-chkbox-box { 314p-inputswitch {
236 &.ui-state-active { 315 .ui-inputswitch-checked .ui-inputswitch-slider {
237 border-color: var(--mainColor) !important;
238 background-color: var(--mainColor) !important; 316 background-color: var(--mainColor) !important;
239 } 317 }
318}
319
320p-toast {
321 .ui-toast {
322 // Modal is 10005
323 z-index: 10010 !important;
324 }
325
326 .ui-toast-message {
327 font-family: $main-fonts;
328
329 &.ui-toast-message-success {
330 color: #fff !important;
331 background-color: #8BC34A !important;
332 }
333
334 &.ui-toast-message-error {
335 color: #fff !important;
336 background-color: #F44336 !important;
337 }
240 338
241 .ui-chkbox-icon { 339 &.ui-toast-message-info {
242 position: relative; 340 color: #fff !important;
243 341 background-color: #03A9F4 !important;
244 &:after {
245 content: '';
246 position: absolute;
247 left: 5px;
248 width: 5px;
249 height: 12px;
250 opacity: 0;
251 transform: rotate(45deg) scale(0);
252 border-right: 2px solid var(--mainBackgroundColor);
253 border-bottom: 2px solid var(--mainBackgroundColor);
254 } 342 }
255 343
256 &.pi-check:after { 344 &.ui-toast-message-info {
257 opacity: 1; 345 color: #fff !important;
258 transform: rotate(45deg) scale(1); 346 background-color: #03A9F4 !important;
347 }
348
349 .notification-block {
350 display: flex;
351 align-items: center;
352 padding: 5px;
353
354 .message {
355 flex-grow: 1;
356
357 h3 {
358 font-size: 21px;
359 }
360
361 p {
362 font-size: 15px;
363 margin-bottom: 0;
364 }
365 }
366
367 .glyphicon {
368 font-size: 32px;
369 margin-right: 5px;
370 }
259 } 371 }
260 } 372 }
261} \ No newline at end of file 373}
374
375.ui-widget {
376 font-family: $main-fonts !important;
377}
diff --git a/client/src/standalone/videos/embed.html b/client/src/standalone/videos/embed.html
index b7cf13ec2..f79cf68df 100644
--- a/client/src/standalone/videos/embed.html
+++ b/client/src/standalone/videos/embed.html
@@ -13,7 +13,7 @@
13 <body> 13 <body>
14 14
15 <div id="error-block"> 15 <div id="error-block">
16 <h1 id="error-title">Sorry</h1> 16 <h1 id="error-title"></h1>
17 17
18 <div id="error-content"></div> 18 <div id="error-content"></div>
19 </div> 19 </div>
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts
index 7daa03f23..54b8fb543 100644
--- a/client/src/standalone/videos/embed.ts
+++ b/client/src/standalone/videos/embed.ts
@@ -157,10 +157,11 @@ class PeerTubeEmbed {
157 player: any 157 player: any
158 playerOptions: any 158 playerOptions: any
159 api: PeerTubeEmbedApi = null 159 api: PeerTubeEmbedApi = null
160 autoplay = false 160 autoplay: boolean
161 controls = true 161 controls: boolean
162 muted = false 162 muted: boolean
163 loop = false 163 loop: boolean
164 subtitle: string
164 enableApi = false 165 enableApi = false
165 startTime: number | string = 0 166 startTime: number | string = 0
166 scope = 'peertube' 167 scope = 'peertube'
@@ -191,34 +192,40 @@ class PeerTubeEmbed {
191 element.parentElement.removeChild(element) 192 element.parentElement.removeChild(element)
192 } 193 }
193 194
194 displayError (text: string) { 195 displayError (text: string, translations?: { [ id: string ]: string }) {
195 // Remove video element 196 // Remove video element
196 if (this.videoElement) this.removeElement(this.videoElement) 197 if (this.videoElement) this.removeElement(this.videoElement)
197 198
198 document.title = 'Sorry - ' + text 199 const translatedText = peertubeTranslate(text, translations)
200 const translatedSorry = peertubeTranslate('Sorry', translations)
201
202 document.title = translatedSorry + ' - ' + translatedText
199 203
200 const errorBlock = document.getElementById('error-block') 204 const errorBlock = document.getElementById('error-block')
201 errorBlock.style.display = 'flex' 205 errorBlock.style.display = 'flex'
202 206
207 const errorTitle = document.getElementById('error-title')
208 errorTitle.innerHTML = peertubeTranslate('Sorry', translations)
209
203 const errorText = document.getElementById('error-content') 210 const errorText = document.getElementById('error-content')
204 errorText.innerHTML = text 211 errorText.innerHTML = translatedText
205 } 212 }
206 213
207 videoNotFound () { 214 videoNotFound (translations?: { [ id: string ]: string }) {
208 const text = 'This video does not exist.' 215 const text = 'This video does not exist.'
209 this.displayError(text) 216 this.displayError(text, translations)
210 } 217 }
211 218
212 videoFetchError () { 219 videoFetchError (translations?: { [ id: string ]: string }) {
213 const text = 'We cannot fetch the video. Please try again later.' 220 const text = 'We cannot fetch the video. Please try again later.'
214 this.displayError(text) 221 this.displayError(text, translations)
215 } 222 }
216 223
217 getParamToggle (params: URLSearchParams, name: string, defaultValue: boolean) { 224 getParamToggle (params: URLSearchParams, name: string, defaultValue?: boolean) {
218 return params.has(name) ? (params.get(name) === '1' || params.get(name) === 'true') : defaultValue 225 return params.has(name) ? (params.get(name) === '1' || params.get(name) === 'true') : defaultValue
219 } 226 }
220 227
221 getParamString (params: URLSearchParams, name: string, defaultValue: string) { 228 getParamString (params: URLSearchParams, name: string, defaultValue?: string) {
222 return params.has(name) ? params.get(name) : defaultValue 229 return params.has(name) ? params.get(name) : defaultValue
223 } 230 }
224 231
@@ -241,15 +248,15 @@ class PeerTubeEmbed {
241 try { 248 try {
242 let params = new URL(window.location.toString()).searchParams 249 let params = new URL(window.location.toString()).searchParams
243 250
244 this.autoplay = this.getParamToggle(params, 'autoplay', this.autoplay) 251 this.autoplay = this.getParamToggle(params, 'autoplay')
245 this.controls = this.getParamToggle(params, 'controls', this.controls) 252 this.controls = this.getParamToggle(params, 'controls')
246 this.muted = this.getParamToggle(params, 'muted', this.muted) 253 this.muted = this.getParamToggle(params, 'muted')
247 this.loop = this.getParamToggle(params, 'loop', this.loop) 254 this.loop = this.getParamToggle(params, 'loop')
248 this.enableApi = this.getParamToggle(params, 'api', this.enableApi) 255 this.enableApi = this.getParamToggle(params, 'api', this.enableApi)
249 this.scope = this.getParamString(params, 'scope', this.scope)
250 256
251 const startTimeParamString = params.get('start') 257 this.scope = this.getParamString(params, 'scope', this.scope)
252 if (startTimeParamString) this.startTime = startTimeParamString 258 this.subtitle = this.getParamString(params, 'subtitle')
259 this.startTime = this.getParamString(params, 'start')
253 } catch (err) { 260 } catch (err) {
254 console.error('Cannot get params from URL.', err) 261 console.error('Cannot get params from URL.', err)
255 } 262 }
@@ -267,9 +274,9 @@ class PeerTubeEmbed {
267 ]) 274 ])
268 275
269 if (!videoResponse.ok) { 276 if (!videoResponse.ok) {
270 if (videoResponse.status === 404) return this.videoNotFound() 277 if (videoResponse.status === 404) return this.videoNotFound(serverTranslations)
271 278
272 return this.videoFetchError() 279 return this.videoFetchError(serverTranslations)
273 } 280 }
274 281
275 const videoInfo: VideoDetails = await videoResponse.json() 282 const videoInfo: VideoDetails = await videoResponse.json()
@@ -291,6 +298,7 @@ class PeerTubeEmbed {
291 muted: this.muted, 298 muted: this.muted,
292 loop: this.loop, 299 loop: this.loop,
293 startTime: this.startTime, 300 startTime: this.startTime,
301 subtitle: this.subtitle,
294 302
295 videoCaptions, 303 videoCaptions,
296 inactivityTimeout: 1500, 304 inactivityTimeout: 1500,
@@ -306,7 +314,7 @@ class PeerTubeEmbed {
306 314
307 this.playerOptions = videojsOptions 315 this.playerOptions = videojsOptions
308 this.player = vjs(this.videoContainerId, videojsOptions, () => { 316 this.player = vjs(this.videoContainerId, videojsOptions, () => {
309 this.player.on('customError', (event: any, data: any) => this.handleError(data.err)) 317 this.player.on('customError', (event: any, data: any) => this.handleError(data.err, serverTranslations))
310 318
311 window[ 'videojsPlayer' ] = this.player 319 window[ 'videojsPlayer' ] = this.player
312 320
@@ -323,11 +331,11 @@ class PeerTubeEmbed {
323 }) 331 })
324 } 332 }
325 333
326 private handleError (err: Error) { 334 private handleError (err: Error, translations?: { [ id: string ]: string }) {
327 if (err.message.indexOf('from xs param') !== -1) { 335 if (err.message.indexOf('from xs param') !== -1) {
328 this.player.dispose() 336 this.player.dispose()
329 this.videoElement = null 337 this.videoElement = null
330 this.displayError('This video is not available because the remote instance is not responding.') 338 this.displayError('This video is not available because the remote instance is not responding.', translations)
331 return 339 return
332 } 340 }
333 } 341 }
diff --git a/client/yarn.lock b/client/yarn.lock
index 928dec01e..dee67c414 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -2,26 +2,26 @@
2# yarn lockfile v1 2# yarn lockfile v1
3 3
4 4
5"@angular-devkit/architect@0.10.6": 5"@angular-devkit/architect@0.11.1":
6 version "0.10.6" 6 version "0.11.1"
7 resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.10.6.tgz#7007e7591be21eeb478951106c84c83802ca21a4" 7 resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.11.1.tgz#fb8429b583d4d7efafe5ff551ffdd30a705b9ab0"
8 integrity sha512-IygpkXNn946vVUFFWKWEDxRqRy888vOAUWcmkZzqPEBYkuwWt7WnLfe8Sjw4fH/+HLWEMS8RXbdSTHiiaP9qOg== 8 integrity sha512-MdcZ5KclwL2SBXCQSn8uI2hakBX58EyuAwFWsM/pKrNt9j8RqIk93l4amd2OkaMtZRFP5zWodyf/3qOwacjuQg==
9 dependencies: 9 dependencies:
10 "@angular-devkit/core" "7.0.6" 10 "@angular-devkit/core" "7.1.1"
11 rxjs "6.3.3" 11 rxjs "6.3.3"
12 12
13"@angular-devkit/build-angular@~0.10.0": 13"@angular-devkit/build-angular@~0.11.1":
14 version "0.10.6" 14 version "0.11.1"
15 resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.10.6.tgz#9c713a786de89a68063bd9e86516eb450f2dac72" 15 resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.11.1.tgz#a828797d9177227aee70a65bb06d4b189b1404cd"
16 integrity sha512-Lbx6rjIGB2mMmkTCaolrQ86OfPxO/qfb4l2RvPiSyx06MEZfmFWKGeJzqCYKBRQajziX3Yc3AFzAPecoCkbIGA== 16 integrity sha512-hA/3GVMmRwOPXWhImrBG9gZTdERr937NMuedKhTXuNj6TNMNjk9XQ+q2erd0LZVbgfhL/nC0wHnpy0dUWXu8jA==
17 dependencies: 17 dependencies:
18 "@angular-devkit/architect" "0.10.6" 18 "@angular-devkit/architect" "0.11.1"
19 "@angular-devkit/build-optimizer" "0.10.6" 19 "@angular-devkit/build-optimizer" "0.11.1"
20 "@angular-devkit/build-webpack" "0.10.6" 20 "@angular-devkit/build-webpack" "0.11.1"
21 "@angular-devkit/core" "7.0.6" 21 "@angular-devkit/core" "7.1.1"
22 "@ngtools/webpack" "7.0.6" 22 "@ngtools/webpack" "7.1.1"
23 ajv "6.5.3" 23 ajv "6.5.3"
24 autoprefixer "9.1.5" 24 autoprefixer "9.3.1"
25 circular-dependency-plugin "5.0.2" 25 circular-dependency-plugin "5.0.2"
26 clean-css "4.2.1" 26 clean-css "4.2.1"
27 copy-webpack-plugin "4.5.4" 27 copy-webpack-plugin "4.5.4"
@@ -34,7 +34,7 @@
34 less-loader "4.1.0" 34 less-loader "4.1.0"
35 license-webpack-plugin "2.0.2" 35 license-webpack-plugin "2.0.2"
36 loader-utils "1.1.0" 36 loader-utils "1.1.0"
37 mini-css-extract-plugin "0.4.3" 37 mini-css-extract-plugin "0.4.4"
38 minimatch "3.0.4" 38 minimatch "3.0.4"
39 opn "5.3.0" 39 opn "5.3.0"
40 parse5 "4.0.0" 40 parse5 "4.0.0"
@@ -48,45 +48,45 @@
48 semver "5.5.1" 48 semver "5.5.1"
49 source-map-loader "0.2.4" 49 source-map-loader "0.2.4"
50 source-map-support "0.5.9" 50 source-map-support "0.5.9"
51 speed-measure-webpack-plugin "^1.2.3" 51 speed-measure-webpack-plugin "1.2.3"
52 stats-webpack-plugin "0.7.0" 52 stats-webpack-plugin "0.7.0"
53 style-loader "0.23.0" 53 style-loader "0.23.1"
54 stylus "0.54.5" 54 stylus "0.54.5"
55 stylus-loader "3.0.2" 55 stylus-loader "3.0.2"
56 terser-webpack-plugin "1.1.0" 56 terser-webpack-plugin "1.1.0"
57 tree-kill "1.2.0" 57 tree-kill "1.2.0"
58 webpack "4.19.1" 58 webpack "4.23.1"
59 webpack-dev-middleware "3.3.0" 59 webpack-dev-middleware "3.4.0"
60 webpack-dev-server "3.1.8" 60 webpack-dev-server "3.1.10"
61 webpack-merge "4.1.4" 61 webpack-merge "4.1.4"
62 webpack-sources "1.2.0" 62 webpack-sources "1.3.0"
63 webpack-subresource-integrity "1.1.0-rc.6" 63 webpack-subresource-integrity "1.1.0-rc.6"
64 optionalDependencies: 64 optionalDependencies:
65 node-sass "4.9.3" 65 node-sass "4.10.0"
66 66
67"@angular-devkit/build-optimizer@0.10.6": 67"@angular-devkit/build-optimizer@0.11.1":
68 version "0.10.6" 68 version "0.11.1"
69 resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.10.6.tgz#ca7db9b3d5378b2759509692f02a5fb5af273dd0" 69 resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.11.1.tgz#1079737a44b26b39e35cea7f966a39cd11bbbf48"
70 integrity sha512-oedg8F++8zZTmoTt141k3nlyPtrSSsQUZI9TFbSdfR1D5WDflwOlkLyRb5WoC53HSoQnagKxY2qzd7khVah//Q== 70 integrity sha512-pyFP6ykZf8Iq8nRkgP2XKq8knpIG6ye0qYklnBC9815AC5RAO126Y4fmtd6tnH+5p1mQxnt5HegG0j5xOCgDRw==
71 dependencies: 71 dependencies:
72 loader-utils "1.1.0" 72 loader-utils "1.1.0"
73 source-map "0.5.6" 73 source-map "0.5.6"
74 typescript "3.1.6" 74 typescript "3.1.6"
75 webpack-sources "1.2.0" 75 webpack-sources "1.2.0"
76 76
77"@angular-devkit/build-webpack@0.10.6": 77"@angular-devkit/build-webpack@0.11.1":
78 version "0.10.6" 78 version "0.11.1"
79 resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.10.6.tgz#d3acb781f97406a49a3e3adfcc49a8518d33e291" 79 resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.11.1.tgz#bd98ff3dea633c5b77671b471e72cf6c91f6c679"
80 integrity sha512-tPv23KKw3iAGCTF6noD7zdHbufny4A3d+mlX1VoJDiAa6jqmuFxhY2fALymc11MRY4HVtMF5J1kQy9BLGCDbQg== 80 integrity sha512-p7fPHOi2Wfq2VPtnRVowg3n99MujghpOp6zW0gBJQD1TQhGVzPK6AX42S0NA4d05ahNBCDU2n7Y+5TjNJRIGJw==
81 dependencies: 81 dependencies:
82 "@angular-devkit/architect" "0.10.6" 82 "@angular-devkit/architect" "0.11.1"
83 "@angular-devkit/core" "7.0.6" 83 "@angular-devkit/core" "7.1.1"
84 rxjs "6.3.3" 84 rxjs "6.3.3"
85 85
86"@angular-devkit/core@7.0.6": 86"@angular-devkit/core@7.1.1":
87 version "7.0.6" 87 version "7.1.1"
88 resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.0.6.tgz#26c4cd4d271e8cd03f6e50b4ec30cbc606f3346e" 88 resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.1.1.tgz#ce0a674f16188072988502cc3f073b15efcfe194"
89 integrity sha512-RPSXUtLrpYDTqAEL0rCyDKxES76EomsPBvUUZTD6UkE2pihoh9ZIxkzhzlE+HU/xdqm28+smQYFhvvEAXFWwSQ== 89 integrity sha512-rODqECpOiV6vX+L1qd63GLiF3SG+V1O+d8WYtnKPOxnsMM9yWpWmqmroHtXfisjucu/zwoqj8HoO/noJZCfynw==
90 dependencies: 90 dependencies:
91 ajv "6.5.3" 91 ajv "6.5.3"
92 chokidar "2.0.4" 92 chokidar "2.0.4"
@@ -94,48 +94,47 @@
94 rxjs "6.3.3" 94 rxjs "6.3.3"
95 source-map "0.7.3" 95 source-map "0.7.3"
96 96
97"@angular-devkit/schematics@7.0.6": 97"@angular-devkit/schematics@7.1.1":
98 version "7.0.6" 98 version "7.1.1"
99 resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.0.6.tgz#97fca028bd937e2319d9d34c12b82e8d1d99de23" 99 resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.1.1.tgz#328ec6071c5ef3b1588a9f4bc97f5edfc3620b09"
100 integrity sha512-S/3CrBDoh/BD4mBq8RNGQ8sgNFDsveCuFHDkOyct8+NDg2wcRkEGigyq8eZwVN/iVKCwjxc0I/bC336edoNMIQ== 100 integrity sha512-yjzTw8ZWMPg0Fc9VQCHNpUCAH7aiNxrUDs0IbhdC0CyKTBoqH+cx2xP4Z6ECf4uNwceLKJlE0l3ot42Ypnlziw==
101 dependencies: 101 dependencies:
102 "@angular-devkit/core" "7.0.6" 102 "@angular-devkit/core" "7.1.1"
103 rxjs "6.3.3" 103 rxjs "6.3.3"
104 104
105"@angular/animations@~7.0.2": 105"@angular/animations@~7.1.1":
106 version "7.0.4" 106 version "7.1.1"
107 resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-7.0.4.tgz#f53fc9f1bce3bf1afe60dcbc08b6863472f519e4" 107 resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-7.1.1.tgz#8fecbd19417364946a9ea40c8fdf32462110232f"
108 integrity sha512-QfFikT0FzYNMjdVg0LWTBijdu9JDJyzejnhCFlXxv+KR4zolpRK98/rU7CFW1Fg2jjL3/yL9PT1sf5I0fTJZYA== 108 integrity sha512-iTNxhPPraCZsE4rgM23lguT1kDV4mfYAr+Bsi5J0+v9ZJA+VaKvi6eRW8ZGrx4/rDz6hzTnBn1jgPppHFbsOcw==
109 dependencies: 109 dependencies:
110 tslib "^1.9.0" 110 tslib "^1.9.0"
111 111
112"@angular/cli@~7.0.4": 112"@angular/cli@~7.1.1":
113 version "7.0.6" 113 version "7.1.1"
114 resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-7.0.6.tgz#f97bc9ca92785c7ce2e5f20819c48265a1da5b53" 114 resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-7.1.1.tgz#c5dd2b92c5c3391f20262b5e530813e4e2d31777"
115 integrity sha512-f76kq8AQMkloeojIffeT7DYLXT/J4DRhYoAPQR4E09V7lkigFCILiYzQs5RtCAX6EjlPxlrZKkdfnBn0OUPnig== 115 integrity sha512-lPVKsk035T5Ls0Mf83OngrNoLZu/ucZSjRLN/GWZK1O/YYVmb/dTgVl/a7HC+G480tWQ34nlqnCRbrP7sE9v7g==
116 dependencies: 116 dependencies:
117 "@angular-devkit/architect" "0.10.6" 117 "@angular-devkit/architect" "0.11.1"
118 "@angular-devkit/core" "7.0.6" 118 "@angular-devkit/core" "7.1.1"
119 "@angular-devkit/schematics" "7.0.6" 119 "@angular-devkit/schematics" "7.1.1"
120 "@schematics/angular" "7.0.6" 120 "@schematics/angular" "7.1.1"
121 "@schematics/update" "0.10.6" 121 "@schematics/update" "0.11.1"
122 inquirer "6.2.0" 122 inquirer "6.2.0"
123 opn "5.3.0" 123 opn "5.3.0"
124 rxjs "6.3.3"
125 semver "5.5.1" 124 semver "5.5.1"
126 symbol-observable "1.2.0" 125 symbol-observable "1.2.0"
127 126
128"@angular/common@~7.0.2": 127"@angular/common@~7.1.1":
129 version "7.0.4" 128 version "7.1.1"
130 resolved "https://registry.yarnpkg.com/@angular/common/-/common-7.0.4.tgz#aafb26ce59c967daa5b122393e1933208a247f72" 129 resolved "https://registry.yarnpkg.com/@angular/common/-/common-7.1.1.tgz#f78f884614ef81ab2fd648f1aa3e83aae370a6c8"
131 integrity sha512-akQojdqY/RBlItkDWAPI3k0Llk1wnbAp+f47yySi3cgQz9SaZ1/RLNWZV84I/cKrksb4ehorT/lTqRBojsAD1A== 130 integrity sha512-SngekFx9v39sjgi9pON0Wehxpu+NdUk7OEebw4Fa8dKqTgydTkuhmnNH+9WQe264asoeCt51oufPRjIqMLNohA==
132 dependencies: 131 dependencies:
133 tslib "^1.9.0" 132 tslib "^1.9.0"
134 133
135"@angular/compiler-cli@~7.0.2": 134"@angular/compiler-cli@~7.1.1":
136 version "7.0.4" 135 version "7.1.1"
137 resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-7.0.4.tgz#f96fc1c0aec27ee97ec5f13a8eb72bc8b964db97" 136 resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-7.1.1.tgz#c5f6225fb72b56f42fa78c332fdee9755c64604e"
138 integrity sha512-kvhWt6OTb1Uduns9Vm+Dwd/UUBNSEU6Jgu+QOPeHr7lg+4NTyr9uQLU0DtfBP0ljOlds8esmfii5IIFTeUQw1Q== 137 integrity sha512-4NXlkDhOEQgaP3Agigqw93CvXJvsfnXa0xiglq9e/wjL+6XbtM9WcDb5lfRQz41N9RSkO3pEHGvKMweKZGgogA==
139 dependencies: 138 dependencies:
140 canonical-path "1.0.0" 139 canonical-path "1.0.0"
141 chokidar "^1.4.2" 140 chokidar "^1.4.2"
@@ -149,64 +148,64 @@
149 tslib "^1.9.0" 148 tslib "^1.9.0"
150 yargs "9.0.1" 149 yargs "9.0.1"
151 150
152"@angular/compiler@~7.0.2": 151"@angular/compiler@~7.1.1":
153 version "7.0.4" 152 version "7.1.1"
154 resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-7.0.4.tgz#df91dab990c46b464705b0901d70d1cfdfd190e1" 153 resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-7.1.1.tgz#4efbcad27ab43d4cd36d936a8df2e073f6d02d0a"
155 integrity sha512-ExDhH1cJkuJkUsgNRZyZBse0a7wWkQyG5O8HONi3Rzig9dalFEuve9jD04zfA1Jx1GTXhovqtGnF72x4kw0V8Q== 154 integrity sha512-oJvBe8XZ+DXF/W/DxWBTbBcixJTuPeZWdkcZIGWhJoQP7K5GnGnj8ffP9Lp6Dh4TKv85awtC6OfIKhbHxa650Q==
156 dependencies: 155 dependencies:
157 tslib "^1.9.0" 156 tslib "^1.9.0"
158 157
159"@angular/core@~7.0.2": 158"@angular/core@~7.1.1":
160 version "7.0.4" 159 version "7.1.1"
161 resolved "https://registry.yarnpkg.com/@angular/core/-/core-7.0.4.tgz#98340a1bdb53f0bbecfcfc9831a7a22a1540d79b" 160 resolved "https://registry.yarnpkg.com/@angular/core/-/core-7.1.1.tgz#9748b0103cd86226554e1ccbd0f43dd8c46f1ed1"
162 integrity sha512-17SSmCz1wQoZKnVHF/T8UkWYPpDm5kPyoc1okkTTv8ZA2EAMMuZFFnRSAxEL5i7mNB9z5CvRqF2tRx/DbgbIRA== 161 integrity sha512-Osig5SRgDRQ+Hec/liN7nq/BCJieB+4/pqRh9rFbOXezb2ptgRZqdXOXN8P17i4AwPVf308Mh55V0niJ5Eu3Rw==
163 dependencies: 162 dependencies:
164 tslib "^1.9.0" 163 tslib "^1.9.0"
165 164
166"@angular/forms@~7.0.2": 165"@angular/forms@~7.1.1":
167 version "7.0.4" 166 version "7.1.1"
168 resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-7.0.4.tgz#5f2328d297f5c7f9f3af81e1f76a13e1546c743f" 167 resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-7.1.1.tgz#d16ef10a901c007062fd19144cd77917ef55ee24"
169 integrity sha512-W3nN9n1VY9On9+9f7PDRbzJUg+mMq1bjkhWsk/b7DfaYdmlzpG+Wd6OfArob2edsqGqH1dvTM8q8aGbWiFZ7dA== 168 integrity sha512-yCWuPjpu23Wc3XUw7v/ACNn/e249oT0bYlM8aaMQ1F5OwrmmC4NJC12Rpl9Ihza61RIHIKzNcHVEgzc7WhcSag==
170 dependencies: 169 dependencies:
171 tslib "^1.9.0" 170 tslib "^1.9.0"
172 171
173"@angular/http@~7.0.2": 172"@angular/http@~7.1.1":
174 version "7.0.4" 173 version "7.1.1"
175 resolved "https://registry.yarnpkg.com/@angular/http/-/http-7.0.4.tgz#445d6a812d25ea1656fc3e3381ef82b3f98fccb4" 174 resolved "https://registry.yarnpkg.com/@angular/http/-/http-7.1.1.tgz#f19f17ad42e7f3cdabcf1250ca757640d0f02219"
176 integrity sha512-oUGT7xS7FZYajuHq0DP6MgahacB5sJTRgxiUU4uhQ/mqV7aREODVJJgw7oHDhM7Cnyzzo0B9D0zpEljKmeCLWQ== 175 integrity sha512-pRk+c/kz9aJ8te5xzCxlPLpFnwB0d/E9YkOo3/ydaXF9vZw13RTzk00YyzJ41PDzJf8oPDdXtueTQ+vtJ7Srtw==
177 dependencies: 176 dependencies:
178 tslib "^1.9.0" 177 tslib "^1.9.0"
179 178
180"@angular/language-service@~7.0.2": 179"@angular/language-service@~7.1.1":
181 version "7.0.4" 180 version "7.1.1"
182 resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-7.0.4.tgz#db221f183725ff54c1188aec7acb2948e29f4c50" 181 resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-7.1.1.tgz#6bbe35b2430ad54618a1803f881efb5894b296c9"
183 integrity sha512-CuJ2Ii97sNoN1HOZOLxG1lEHsQFi8K/RSB/k2suWPKzdM53ldSkKoYRac38zW/uqNABYItgvxb7w0Vi7HhxLsg== 182 integrity sha512-X+5g20PMtNRGZIa3svMv4PLJdJehn4wqrS8nwOtzH5XkSn5vA3IxjsJVdSzAy2AN0/sKKJK5jmQorPtKO4saJg==
184 183
185"@angular/platform-browser-dynamic@~7.0.2": 184"@angular/platform-browser-dynamic@~7.1.1":
186 version "7.0.4" 185 version "7.1.1"
187 resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.0.4.tgz#69abb8c784bb71a660a0c824ca4a1a4960811a33" 186 resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.1.1.tgz#6945298446173338782f437a996226110cda0d3e"
188 integrity sha512-k1I53zIg8YWhtQizLfq/tWrUUdY5vHV8pGHyt0/UTGDqat5TORd6LDFfzCSux0r3qZujCOGNi9f4/AbyV8B9lw== 187 integrity sha512-ZIu48Vn4S6gjD7CMbGlKGaPQ8v9rYkWzlNYi4vTYzgiqKKNC3hqLsVESU3mSvr5oeQBxSIBidTdHSyafHFrA2w==
189 dependencies: 188 dependencies:
190 tslib "^1.9.0" 189 tslib "^1.9.0"
191 190
192"@angular/platform-browser@~7.0.2": 191"@angular/platform-browser@~7.1.1":
193 version "7.0.4" 192 version "7.1.1"
194 resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-7.0.4.tgz#57dfaa23f8a3d678bad6ca110051e3ac6622ff3d" 193 resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-7.1.1.tgz#a6bd408f656dc43ee5a2d8af3dfaa786c7c1dfca"
195 integrity sha512-4brYZZgsCJk1/a6JoSwaiVWO9+/T4iyE27dAgstao1nOf/jrBNKW2HnZtkWZmCCBK0WIk15wlB0Xr87OZbjNVA== 194 integrity sha512-I6OPjecynGJSbPtzu0gvEgSmIR6X6/xEAhg4L9PycW1ryjzptTC9klWRTWIqsIBqMxhVnY44uKLeRNrDwMOwyA==
196 dependencies: 195 dependencies:
197 tslib "^1.9.0" 196 tslib "^1.9.0"
198 197
199"@angular/router@~7.0.2": 198"@angular/router@~7.1.1":
200 version "7.0.4" 199 version "7.1.1"
201 resolved "https://registry.yarnpkg.com/@angular/router/-/router-7.0.4.tgz#ae2c32cc6a29bfe6eb909b9c63257d187075f4ff" 200 resolved "https://registry.yarnpkg.com/@angular/router/-/router-7.1.1.tgz#80a4cdffc03a529b73485c2ad63a30ec435364ea"
202 integrity sha512-nt1jJsxN+JmYZ6URamMdULUpH4aHdnNVKjWtjDI0OpdZvPx7PMFD8cfc92q0tavy2KqqexcceIb4BIC965gtpA== 201 integrity sha512-jbnqEq/1iDBkeH8Vn13hauGPTzhwllWM+MLfmdNGTiMzGRx4pmkWa57seDOeBF/GNYBL9JjkWTCrkKFAc2FJKw==
203 dependencies: 202 dependencies:
204 tslib "^1.9.0" 203 tslib "^1.9.0"
205 204
206"@angular/service-worker@~7.0.2": 205"@angular/service-worker@~7.1.1":
207 version "7.0.4" 206 version "7.1.1"
208 resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-7.0.4.tgz#be274843ae29cb69ac969c078edd8ae5b25e3e61" 207 resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-7.1.1.tgz#c9e6f0265d7e102d8271483519cf09a180f0e08b"
209 integrity sha512-vBA9T1xeCP6QesOYhMyVpXTUVdXU4eMYdoZItHncyom8AxS2a26FB8zLW72VXdEfZ7xnJgcDtsYzYzVi+3DXsQ== 208 integrity sha512-xX00x0XMW47jEfYTZLwdJCqkmPE7+mdtlSeOGpjaKv6Y2hqZodz80RYgH5JltM4RKEzOvQolR6KmdKcw1ANs9Q==
210 dependencies: 209 dependencies:
211 tslib "^1.9.0" 210 tslib "^1.9.0"
212 211
@@ -223,11 +222,11 @@
223 "@babel/highlight" "^7.0.0" 222 "@babel/highlight" "^7.0.0"
224 223
225"@babel/generator@^7.0.0", "@babel/generator@^7.1.6": 224"@babel/generator@^7.0.0", "@babel/generator@^7.1.6":
226 version "7.1.6" 225 version "7.2.0"
227 resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.6.tgz#001303cf87a5b9d093494a4bf251d7b5d03d3999" 226 resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.2.0.tgz#eaf3821fa0301d9d4aef88e63d4bcc19b73ba16c"
228 integrity sha512-brwPBtVvdYdGxtenbQgfCdDPmtkmUBZPjUoK5SXJEBuHaA5BCubh9ly65fzXz7R6o5rA76Rs22ES8Z+HCc0YIQ== 227 integrity sha512-BA75MVfRlFQG2EZgFYIwyT1r6xSkwfP2bdkY/kLZusEYWiJs4xCowab/alaEaT0wSvmVuXGqiefeBlP+7V1yKg==
229 dependencies: 228 dependencies:
230 "@babel/types" "^7.1.6" 229 "@babel/types" "^7.2.0"
231 jsesc "^2.5.1" 230 jsesc "^2.5.1"
232 lodash "^4.17.10" 231 lodash "^4.17.10"
233 source-map "^0.5.0" 232 source-map "^0.5.0"
@@ -266,14 +265,14 @@
266 js-tokens "^4.0.0" 265 js-tokens "^4.0.0"
267 266
268"@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.6": 267"@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.6":
269 version "7.1.6" 268 version "7.2.0"
270 resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.6.tgz#16e97aca1ec1062324a01c5a6a7d0df8dd189854" 269 resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.2.0.tgz#02d01dbc330b6cbf36b76ac93c50752c69027065"
271 integrity sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ== 270 integrity sha512-M74+GvK4hn1eejD9lZ7967qAwvqTZayQa3g10ag4s9uewgR7TKjeaT0YMyoq+gVfKYABiWZ4MQD701/t5e1Jhg==
272 271
273"@babel/runtime@^7.0.0": 272"@babel/runtime@^7.0.0":
274 version "7.1.5" 273 version "7.2.0"
275 resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.5.tgz#4170907641cf1f61508f563ece3725150cc6fe39" 274 resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.2.0.tgz#b03e42eeddf5898e00646e4c840fa07ba8dcad7f"
276 integrity sha512-xKnPpXG/pvK1B90JkwwxSGii90rQGKtzcMt2gI5G6+M0REXaq6rOHsGC2ay6/d0Uje7zzvSzjEzfR3ENhFlrfA== 275 integrity sha512-oouEibCbHMVdZSDlJBO6bZmID/zA/G/Qx3H1d3rSNPTD+L8UNKvCat7aKWSJ74zYbm5zWGh0GQN0hKj8zYFTCg==
277 dependencies: 276 dependencies:
278 regenerator-runtime "^0.12.0" 277 regenerator-runtime "^0.12.0"
279 278
@@ -301,10 +300,10 @@
301 globals "^11.1.0" 300 globals "^11.1.0"
302 lodash "^4.17.10" 301 lodash "^4.17.10"
303 302
304"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.6": 303"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.6", "@babel/types@^7.2.0":
305 version "7.1.6" 304 version "7.2.0"
306 resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.6.tgz#0adb330c3a281348a190263aceb540e10f04bcce" 305 resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.2.0.tgz#7941c5b2d8060e06f9601d6be7c223eef906d5d8"
307 integrity sha512-DMiUzlY9DSjVsOylJssxLHSgj6tWM9PRFJOGW/RaOglVOK9nzTxoOMfTfRQXGUCUQ/HmlG2efwC+XqUEJ5ay4w== 306 integrity sha512-b4v7dyfApuKDvmPb+O488UlGuR1WbwMXFsO/cyqMrnfvRAChZKJAYeeglWTjUO1b9UghKKgepAQM5tsvBJca6A==
308 dependencies: 307 dependencies:
309 esutils "^2.0.2" 308 esutils "^2.0.2"
310 lodash "^4.17.10" 309 lodash "^4.17.10"
@@ -322,38 +321,38 @@
322 dependencies: 321 dependencies:
323 tslib "^1.9.0" 322 tslib "^1.9.0"
324 323
325"@ngtools/webpack@7.0.6": 324"@ngtools/webpack@7.1.1":
326 version "7.0.6" 325 version "7.1.1"
327 resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-7.0.6.tgz#cc4f4189765f6743417b4eee946fb69590f93ce1" 326 resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-7.1.1.tgz#c418e1cb0d70a77d06e8c32500fe2e92e606ea52"
328 integrity sha512-lOHpVqr30QXPuaOxSRasHv6ybDj4a1jVwSOk+W4aGqVlLi0bsngt9HrvgR+FALEoG9P520bytz16wma81Y2Aeg== 327 integrity sha512-XW/YDjiDZlwOYK4YvGAIKIVEkqtdwPLwTWAmDbnfpEHQc8UALsBrzGdjze0jSfXQdQxkbmXo0aolZgNc7uL/wQ==
329 dependencies: 328 dependencies:
330 "@angular-devkit/core" "7.0.6" 329 "@angular-devkit/core" "7.1.1"
331 enhanced-resolve "4.1.0" 330 enhanced-resolve "4.1.0"
332 rxjs "6.3.3" 331 rxjs "6.3.3"
333 tree-kill "1.2.0" 332 tree-kill "1.2.0"
334 webpack-sources "1.2.0" 333 webpack-sources "1.2.0"
335 334
336"@ngx-loading-bar/core@2.2.0", "@ngx-loading-bar/core@^2.2.0": 335"@ngx-loading-bar/core@3.0.0", "@ngx-loading-bar/core@^3.0.0":
337 version "2.2.0" 336 version "3.0.0"
338 resolved "https://registry.yarnpkg.com/@ngx-loading-bar/core/-/core-2.2.0.tgz#ad313bbbd69e4c52cc2d6f0a8b5911272371d16a" 337 resolved "https://registry.yarnpkg.com/@ngx-loading-bar/core/-/core-3.0.0.tgz#86c6d036b5ad50950b5ea526db585f39d44f396a"
339 integrity sha512-0jcnEzuhqE/c+4iAumJ/0D4GBWm4RRVas0+qXpX4Wm225SJoE5KupUOlMrvLnJNK2bn8NW31dEj80kJ+UzhE5A== 338 integrity sha512-DBH+bKf8M9uSk2791HbtN/JvcEmBxEbUCiOJ6PYrjbginH6dUn2NsSxnv3myu0lpx+7K3MusXLNImkB5JUh2QA==
340 dependencies: 339 dependencies:
341 tslib "^1.7.1" 340 tslib "^1.7.1"
342 341
343"@ngx-loading-bar/http-client@^2.2.0": 342"@ngx-loading-bar/http-client@^3.0.0":
344 version "2.2.0" 343 version "3.0.0"
345 resolved "https://registry.yarnpkg.com/@ngx-loading-bar/http-client/-/http-client-2.2.0.tgz#4b5443feed5c53bc5b5f06119f771edbe89799f4" 344 resolved "https://registry.yarnpkg.com/@ngx-loading-bar/http-client/-/http-client-3.0.0.tgz#2fce2f60da37a48f2173ef4f08189eecf98d9215"
346 integrity sha512-+eilxs10KncQWg7DQJLK2AoWnmTPidhVHNxfTOPHJVnmcyAFmTtk+lQbf5Ke3aC4d/KXZklkRyBizqDfvRvc9w== 345 integrity sha512-7AHM3tmA2FDFXsKbL09vnRqqxdztpjilkP3U9zXB5Lkv3XtlJnZoQKFCSbmEusw30k3oAmY5id/ZE9X83uekZg==
347 dependencies: 346 dependencies:
348 "@ngx-loading-bar/core" "2.2.0" 347 "@ngx-loading-bar/core" "3.0.0"
349 tslib "^1.7.1" 348 tslib "^1.7.1"
350 349
351"@ngx-loading-bar/router@^2.2.0": 350"@ngx-loading-bar/router@^3.0.0":
352 version "2.2.0" 351 version "3.0.0"
353 resolved "https://registry.yarnpkg.com/@ngx-loading-bar/router/-/router-2.2.0.tgz#c13c1a05c620a9da102102322685b671d3c9a1ba" 352 resolved "https://registry.yarnpkg.com/@ngx-loading-bar/router/-/router-3.0.0.tgz#627e73be406dfdff48175f75c110bebd4f6fa588"
354 integrity sha512-/lrWc0ZwGcpmuoa26/h0rC7SRVKgCtsikhy0mVXwrb1VVJ+sRU8vNKbq7aidcvEY5vdi3l0Z7DcVq9+JV/i/BQ== 353 integrity sha512-UL3GaFyFfHwgGeAdSEG800Rl3GuBfKydPp21lD/paqdsrUT2Z1cBLAiVFw7U4QdnSLaPzngYr9bzgDFdy4GqYQ==
355 dependencies: 354 dependencies:
356 "@ngx-loading-bar/core" "2.2.0" 355 "@ngx-loading-bar/core" "3.0.0"
357 tslib "^1.7.1" 356 tslib "^1.7.1"
358 357
359"@ngx-meta/core@^6.0.0-rc.1": 358"@ngx-meta/core@^6.0.0-rc.1":
@@ -372,23 +371,25 @@
372 tslib "^1.9.0" 371 tslib "^1.9.0"
373 yargs "10.0.3" 372 yargs "10.0.3"
374 373
375"@schematics/angular@7.0.6": 374"@schematics/angular@7.1.1":
376 version "7.0.6" 375 version "7.1.1"
377 resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.0.6.tgz#1173c201d118cf38d1afdb382e9a916e4b540a17" 376 resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.1.1.tgz#4ee17a17d221eaf48009db0b991766d1074d0b4f"
378 integrity sha512-jOHL+vSu1cqAo3kRNDmgkq/GR2EDkJx5/h0VXGlbtdEpq892LipKHtyPgXa269AABgPKb3TSNBwZls6g2L9FCw== 377 integrity sha512-jMaj8y3rNTQQXuH38uoWfAOmwYjtzqo1RelNfACnT54mfO/Dat+k7WasBLHWuvzvnN4/Ga3kXL7sJpkeMciiIg==
379 dependencies: 378 dependencies:
380 "@angular-devkit/core" "7.0.6" 379 "@angular-devkit/core" "7.1.1"
381 "@angular-devkit/schematics" "7.0.6" 380 "@angular-devkit/schematics" "7.1.1"
382 typescript "3.1.6" 381 typescript "3.1.6"
383 382
384"@schematics/update@0.10.6": 383"@schematics/update@0.11.1":
385 version "0.10.6" 384 version "0.11.1"
386 resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.10.6.tgz#616e6c321cd51468eacda7fc8a0306b37f8b4ca2" 385 resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.11.1.tgz#5129a800043dc38ee1f1c879865e0df82ddac7ed"
387 integrity sha512-Yy/M4JosrVDb5tbpmi+v1uTHSmBYISOiuFVuxtpMN5DWdDNq/JTBEw2jy3quelGWHCU06rbGo578Ml3azGZ+9g== 386 integrity sha512-IzPXamoMpDb2eY2zSW4fPuuH+7RfJLte9XVzQM2y3ZTBhlJQFLqx7qJtOXdcXUboonC6o61KCayNDERFnDUdPg==
388 dependencies: 387 dependencies:
389 "@angular-devkit/core" "7.0.6" 388 "@angular-devkit/core" "7.1.1"
390 "@angular-devkit/schematics" "7.0.6" 389 "@angular-devkit/schematics" "7.1.1"
391 npm-registry-client "8.6.0" 390 "@yarnpkg/lockfile" "1.1.0"
391 ini "1.3.5"
392 pacote "9.1.1"
392 rxjs "6.3.3" 393 rxjs "6.3.3"
393 semver "5.5.1" 394 semver "5.5.1"
394 semver-intersect "1.4.0" 395 semver-intersect "1.4.0"
@@ -405,10 +406,15 @@
405 resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-2.5.0.tgz#35cc282488de6f10af1d92902899a3b8ca3fbc47" 406 resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-2.5.0.tgz#35cc282488de6f10af1d92902899a3b8ca3fbc47"
406 integrity sha512-qjkHL3wF0JMHMqgm/kmL8Pf8rIiqvueEiZ0g6NVTcBX1WN46GWDr+V5z+gsHUeL0n8TfAmXnYmF7ajsxmBp4PQ== 407 integrity sha512-qjkHL3wF0JMHMqgm/kmL8Pf8rIiqvueEiZ0g6NVTcBX1WN46GWDr+V5z+gsHUeL0n8TfAmXnYmF7ajsxmBp4PQ==
407 408
408"@types/jasmine@*", "@types/jasmine@^2.8.7": 409"@types/jasmine@*":
409 version "2.8.11" 410 version "3.3.1"
410 resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-2.8.11.tgz#0b5eba9e02616736b1a189112eacc163c3773b7b" 411 resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.3.1.tgz#b6c4f356013364e98b583647c7b3b6de6fccd2cc"
411 integrity sha512-ITPYT5rkV9S0BcucyBwXIUzqzSODVhvAzhOGV0bwZMuqWJeU0Kfdd6IJeJjGI8Gob+lDyAtKaWUfhG6QXJIPRg== 412 integrity sha512-JnKB+cEIFuQZXizZP6N0zxma+JlvowkjefWuL61otVmXN7Ebbs4ka3IbDVIz1pc+TCiT00q925jANz3gQJ9qXw==
413
414"@types/jasmine@^2.8.7":
415 version "2.8.12"
416 resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-2.8.12.tgz#dfe606b07686c977f54d17cb8ebe6cae2e26f8ff"
417 integrity sha512-eE+xeiGBPgQsNcyg61JBqQS6NtxC+s2yfOikMCnc0Z4NqKujzmSahmtjLCKVQU/AyrTEQ76TOwQBnr8wGP2bmA==
412 418
413"@types/jasminewd2@^2.0.3": 419"@types/jasminewd2@^2.0.3":
414 version "2.0.6" 420 version "2.0.6"
@@ -418,9 +424,9 @@
418 "@types/jasmine" "*" 424 "@types/jasmine" "*"
419 425
420"@types/jest@^23.3.1": 426"@types/jest@^23.3.1":
421 version "23.3.9" 427 version "23.3.10"
422 resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.9.tgz#c16b55186ee73ae65e001fbee69d392c51337ad1" 428 resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.10.tgz#4897974cc317bf99d4fe6af1efa15957fa9c94de"
423 integrity sha512-wNMwXSUcwyYajtbayfPp55tSayuDVU6PfY5gzvRSj80UvxdXEJOVPnUVajaOp7NgXLm+1e2ZDLULmpsU9vDvQw== 429 integrity sha512-DC8xTuW/6TYgvEg3HEXS7cu9OijFqprVDXXiOcdOKZCU/5PJNLZU37VVvmZHdtMiGOa8wAA/We+JzbdxFzQTRQ==
424 430
425"@types/jschannel@^1.0.0": 431"@types/jschannel@^1.0.0":
426 version "1.0.1" 432 version "1.0.1"
@@ -457,9 +463,9 @@
457 integrity sha512-Jn2cF8X6RAMiSmJaATGjf2r3GzIfpZQpvnQhKprQ5sAbMaNXc7hc9sA2XHdMl3bEMEQhTV79JVW7n4Pgg7sjtg== 463 integrity sha512-Jn2cF8X6RAMiSmJaATGjf2r3GzIfpZQpvnQhKprQ5sAbMaNXc7hc9sA2XHdMl3bEMEQhTV79JVW7n4Pgg7sjtg==
458 464
459"@types/node@*", "@types/node@^10.9.2": 465"@types/node@*", "@types/node@^10.9.2":
460 version "10.12.8" 466 version "10.12.12"
461 resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.8.tgz#d0a3ab5a6e61458c492304e2776ac136b81db927" 467 resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.12.tgz#e15a9d034d9210f00320ef718a50c4a799417c47"
462 integrity sha512-INamyRZG4rW3lDCUmwVd5Xho/bXvQm/v1yP8V0UN1RuInU7RoWoaO570b+yLX4Ia/0szsx1wa8VzcsVlsvbWLA== 468 integrity sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A==
463 469
464"@types/node@^6.0.46": 470"@types/node@^6.0.46":
465 version "6.14.2" 471 version "6.14.2"
@@ -504,6 +510,11 @@
504 dependencies: 510 dependencies:
505 "@types/node" "*" 511 "@types/node" "*"
506 512
513"@types/socket.io-client@^1.4.32":
514 version "1.4.32"
515 resolved "https://registry.yarnpkg.com/@types/socket.io-client/-/socket.io-client-1.4.32.tgz#988a65a0386c274b1c22a55377fab6a30789ac14"
516 integrity sha512-Vs55Kq8F+OWvy1RLA31rT+cAyemzgm0EWNeax6BWF8H7QiiOYMJIdcwSDdm5LVgfEkoepsWkS+40+WNb7BUMbg==
517
507"@types/video.js@^7.2.5": 518"@types/video.js@^7.2.5":
508 version "7.2.5" 519 version "7.2.5"
509 resolved "https://registry.yarnpkg.com/@types/video.js/-/video.js-7.2.5.tgz#20896c81141d3517c3a89bb6eb97c6a191aa5d4c" 520 resolved "https://registry.yarnpkg.com/@types/video.js/-/video.js-7.2.5.tgz#20896c81141d3517c3a89bb6eb97c6a191aa5d4c"
@@ -532,294 +543,147 @@
532 url-toolkit "^2.1.3" 543 url-toolkit "^2.1.3"
533 video.js "^6.8.0 || ^7.0.0" 544 video.js "^6.8.0 || ^7.0.0"
534 545
535"@webassemblyjs/ast@1.7.11": 546"@webassemblyjs/ast@1.7.10":
536 version "1.7.11" 547 version "1.7.10"
537 resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" 548 resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.10.tgz#0cfc61d61286240b72fc522cb755613699eea40a"
538 integrity sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA== 549 integrity sha512-wTUeaByYN2EA6qVqhbgavtGc7fLTOx0glG2IBsFlrFG51uXIGlYBTyIZMf4SPLo3v1bgV/7lBN3l7Z0R6Hswew==
539 dependencies: 550 dependencies:
540 "@webassemblyjs/helper-module-context" "1.7.11" 551 "@webassemblyjs/helper-module-context" "1.7.10"
541 "@webassemblyjs/helper-wasm-bytecode" "1.7.11" 552 "@webassemblyjs/helper-wasm-bytecode" "1.7.10"
542 "@webassemblyjs/wast-parser" "1.7.11" 553 "@webassemblyjs/wast-parser" "1.7.10"
543 554
544"@webassemblyjs/ast@1.7.6": 555"@webassemblyjs/floating-point-hex-parser@1.7.10":
545 version "1.7.6" 556 version "1.7.10"
546 resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.6.tgz#3ef8c45b3e5e943a153a05281317474fef63e21e" 557 resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.10.tgz#ee63d729c6311a85863e369a473f9983f984e4d9"
547 integrity sha512-8nkZS48EVsMUU0v6F1LCIOw4RYWLm2plMtbhFTjNgeXmsTNLuU3xTRtnljt9BFQB+iPbLRobkNrCWftWnNC7wQ== 558 integrity sha512-gMsGbI6I3p/P1xL2UxqhNh1ga2HCsx5VBB2i5VvJFAaqAjd2PBTRULc3BpTydabUQEGlaZCzEUQhLoLG7TvEYQ==
548 dependencies: 559
549 "@webassemblyjs/helper-module-context" "1.7.6" 560"@webassemblyjs/helper-api-error@1.7.10":
550 "@webassemblyjs/helper-wasm-bytecode" "1.7.6" 561 version "1.7.10"
551 "@webassemblyjs/wast-parser" "1.7.6" 562 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.10.tgz#bfcb3bbe59775357475790a2ad7b289f09b2f198"
552 mamacro "^0.0.3" 563 integrity sha512-DoYRlPWtuw3yd5BOr9XhtrmB6X1enYF0/54yNvQWGXZEPDF5PJVNI7zQ7gkcKfTESzp8bIBWailaFXEK/jjCsw==
553 564
554"@webassemblyjs/floating-point-hex-parser@1.7.11": 565"@webassemblyjs/helper-buffer@1.7.10":
555 version "1.7.11" 566 version "1.7.10"
556 resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz#a69f0af6502eb9a3c045555b1a6129d3d3f2e313" 567 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.10.tgz#0a8c624c67ad0b214d2e003859921a1988cb151b"
557 integrity sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg== 568 integrity sha512-+RMU3dt/dPh4EpVX4u5jxsOlw22tp3zjqE0m3ftU2tsYxnPULb4cyHlgaNd2KoWuwasCQqn8Mhr+TTdbtj3LlA==
558 569
559"@webassemblyjs/floating-point-hex-parser@1.7.6": 570"@webassemblyjs/helper-code-frame@1.7.10":
560 version "1.7.6" 571 version "1.7.10"
561 resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.6.tgz#7cb37d51a05c3fe09b464ae7e711d1ab3837801f" 572 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.10.tgz#0ab7e22fad0241a173178c73976fc0edf50832ce"
562 integrity sha512-VBOZvaOyBSkPZdIt5VBMg3vPWxouuM13dPXGWI1cBh3oFLNcFJ8s9YA7S9l4mPI7+Q950QqOmqj06oa83hNWBA== 573 integrity sha512-UiytbpKAULOEab2hUZK2ywXen4gWJVrgxtwY3Kn+eZaaSWaRM8z/7dAXRSoamhKFiBh1uaqxzE/XD9BLlug3gw==
563 574 dependencies:
564"@webassemblyjs/helper-api-error@1.7.11": 575 "@webassemblyjs/wast-printer" "1.7.10"
565 version "1.7.11" 576
566 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz#c7b6bb8105f84039511a2b39ce494f193818a32a" 577"@webassemblyjs/helper-fsm@1.7.10":
567 integrity sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg== 578 version "1.7.10"
568 579 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.10.tgz#0915e7713fbbb735620a9d3e4fa3d7951f97ac64"
569"@webassemblyjs/helper-api-error@1.7.6": 580 integrity sha512-w2vDtUK9xeSRtt5+RnnlRCI7wHEvLjF0XdnxJpgx+LJOvklTZPqWkuy/NhwHSLP19sm9H8dWxKeReMR7sCkGZA==
570 version "1.7.6" 581
571 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.6.tgz#99b7e30e66f550a2638299a109dda84a622070ef" 582"@webassemblyjs/helper-module-context@1.7.10":
572 integrity sha512-SCzhcQWHXfrfMSKcj8zHg1/kL9kb3aa5TN4plc/EREOs5Xop0ci5bdVBApbk2yfVi8aL+Ly4Qpp3/TRAUInjrg== 583 version "1.7.10"
573 584 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.10.tgz#9beb83f72740f5ac8075313b5cac5e796510f755"
574"@webassemblyjs/helper-buffer@1.7.11": 585 integrity sha512-yE5x/LzZ3XdPdREmJijxzfrf+BDRewvO0zl8kvORgSWmxpRrkqY39KZSq6TSgIWBxkK4SrzlS3BsMCv2s1FpsQ==
575 version "1.7.11" 586
576 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz#3122d48dcc6c9456ed982debe16c8f37101df39b" 587"@webassemblyjs/helper-wasm-bytecode@1.7.10":
577 integrity sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w== 588 version "1.7.10"
578 589 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.10.tgz#797b1e734bbcfdea8399669cdc58308ef1c7ffc0"
579"@webassemblyjs/helper-buffer@1.7.6": 590 integrity sha512-u5qy4SJ/OrxKxZqJ9N3qH4ZQgHaAzsopsYwLvoWJY6Q33r8PhT3VPyNMaJ7ZFoqzBnZlCcS/0f4Sp8WBxylXfg==
580 version "1.7.6" 591
581 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.6.tgz#ba0648be12bbe560c25c997e175c2018df39ca3e" 592"@webassemblyjs/helper-wasm-section@1.7.10":
582 integrity sha512-1/gW5NaGsEOZ02fjnFiU8/OEEXU1uVbv2um0pQ9YVL3IHSkyk6xOwokzyqqO1qDZQUAllb+V8irtClPWntbVqw== 593 version "1.7.10"
583 594 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.10.tgz#c0ea3703c615d7bc3e3507c3b7991c8767b2f20e"
584"@webassemblyjs/helper-code-frame@1.7.11": 595 integrity sha512-Ecvww6sCkcjatcyctUrn22neSJHLN/TTzolMGG/N7S9rpbsTZ8c6Bl98GpSpV77EvzNijiNRHBG0+JO99qKz6g==
585 version "1.7.11" 596 dependencies:
586 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz#cf8f106e746662a0da29bdef635fcd3d1248364b" 597 "@webassemblyjs/ast" "1.7.10"
587 integrity sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw== 598 "@webassemblyjs/helper-buffer" "1.7.10"
588 dependencies: 599 "@webassemblyjs/helper-wasm-bytecode" "1.7.10"
589 "@webassemblyjs/wast-printer" "1.7.11" 600 "@webassemblyjs/wasm-gen" "1.7.10"
590 601
591"@webassemblyjs/helper-code-frame@1.7.6": 602"@webassemblyjs/ieee754@1.7.10":
592 version "1.7.6" 603 version "1.7.10"
593 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.6.tgz#5a94d21b0057b69a7403fca0c253c3aaca95b1a5" 604 resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.10.tgz#62c1728b7ef0f66ef8221e2966a0afd75db430df"
594 integrity sha512-+suMJOkSn9+vEvDvgyWyrJo5vJsWSDXZmJAjtoUq4zS4eqHyXImpktvHOZwXp1XQjO5H+YQwsBgqTQEc0J/5zg== 605 integrity sha512-HRcWcY+YWt4+s/CvQn+vnSPfRaD4KkuzQFt5MNaELXXHSjelHlSEA8ZcqT69q0GTIuLWZ6JaoKar4yWHVpZHsQ==
595 dependencies:
596 "@webassemblyjs/wast-printer" "1.7.6"
597
598"@webassemblyjs/helper-fsm@1.7.11":
599 version "1.7.11"
600 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz#df38882a624080d03f7503f93e3f17ac5ac01181"
601 integrity sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==
602
603"@webassemblyjs/helper-fsm@1.7.6":
604 version "1.7.6"
605 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.6.tgz#ae1741c6f6121213c7a0b587fb964fac492d3e49"
606 integrity sha512-HCS6KN3wgxUihGBW7WFzEC/o8Eyvk0d56uazusnxXthDPnkWiMv+kGi9xXswL2cvfYfeK5yiM17z2K5BVlwypw==
607
608"@webassemblyjs/helper-module-context@1.7.11":
609 version "1.7.11"
610 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz#d874d722e51e62ac202476935d649c802fa0e209"
611 integrity sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==
612
613"@webassemblyjs/helper-module-context@1.7.6":
614 version "1.7.6"
615 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.6.tgz#116d19a51a6cebc8900ad53ca34ff8269c668c23"
616 integrity sha512-e8/6GbY7OjLM+6OsN7f2krC2qYVNaSr0B0oe4lWdmq5sL++8dYDD1TFbD1TdAdWMRTYNr/Qq7ovXWzia2EbSjw==
617 dependencies:
618 mamacro "^0.0.3"
619
620"@webassemblyjs/helper-wasm-bytecode@1.7.11":
621 version "1.7.11"
622 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz#dd9a1e817f1c2eb105b4cf1013093cb9f3c9cb06"
623 integrity sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==
624
625"@webassemblyjs/helper-wasm-bytecode@1.7.6":
626 version "1.7.6"
627 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.6.tgz#98e515eaee611aa6834eb5f6a7f8f5b29fefb6f1"
628 integrity sha512-PzYFCb7RjjSdAOljyvLWVqd6adAOabJW+8yRT+NWhXuf1nNZWH+igFZCUK9k7Cx7CsBbzIfXjJc7u56zZgFj9Q==
629
630"@webassemblyjs/helper-wasm-section@1.7.11":
631 version "1.7.11"
632 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz#9c9ac41ecf9fbcfffc96f6d2675e2de33811e68a"
633 integrity sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==
634 dependencies:
635 "@webassemblyjs/ast" "1.7.11"
636 "@webassemblyjs/helper-buffer" "1.7.11"
637 "@webassemblyjs/helper-wasm-bytecode" "1.7.11"
638 "@webassemblyjs/wasm-gen" "1.7.11"
639
640"@webassemblyjs/helper-wasm-section@1.7.6":
641 version "1.7.6"
642 resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.6.tgz#783835867bdd686df7a95377ab64f51a275e8333"
643 integrity sha512-3GS628ppDPSuwcYlQ7cDCGr4W2n9c4hLzvnRKeuz+lGsJSmc/ADVoYpm1ts2vlB1tGHkjtQMni+yu8mHoMlKlA==
644 dependencies:
645 "@webassemblyjs/ast" "1.7.6"
646 "@webassemblyjs/helper-buffer" "1.7.6"
647 "@webassemblyjs/helper-wasm-bytecode" "1.7.6"
648 "@webassemblyjs/wasm-gen" "1.7.6"
649
650"@webassemblyjs/ieee754@1.7.11":
651 version "1.7.11"
652 resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz#c95839eb63757a31880aaec7b6512d4191ac640b"
653 integrity sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==
654 dependencies:
655 "@xtuc/ieee754" "^1.2.0"
656
657"@webassemblyjs/ieee754@1.7.6":
658 version "1.7.6"
659 resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.6.tgz#c34fc058f2f831fae0632a8bb9803cf2d3462eb1"
660 integrity sha512-V4cIp0ruyw+hawUHwQLn6o2mFEw4t50tk530oKsYXQhEzKR+xNGDxs/SFFuyTO7X3NzEu4usA3w5jzhl2RYyzQ==
661 dependencies: 606 dependencies:
662 "@xtuc/ieee754" "^1.2.0" 607 "@xtuc/ieee754" "^1.2.0"
663 608
664"@webassemblyjs/leb128@1.7.11": 609"@webassemblyjs/leb128@1.7.10":
665 version "1.7.11" 610 version "1.7.10"
666 resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.11.tgz#d7267a1ee9c4594fd3f7e37298818ec65687db63" 611 resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.10.tgz#167e0bb4b06d7701585772a73fba9f4df85439f6"
667 integrity sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw== 612 integrity sha512-og8MciYlA8hvzCLR71hCuZKPbVBfLQeHv7ImKZ4nlyxrYbG7uJHYtHiHu6OV9SqrGuD03H/HtXC4Bgdjfm9FHw==
668 dependencies:
669 "@xtuc/long" "4.2.1"
670
671"@webassemblyjs/leb128@1.7.6":
672 version "1.7.6"
673 resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.6.tgz#197f75376a29f6ed6ace15898a310d871d92f03b"
674 integrity sha512-ojdlG8WpM394lBow4ncTGJoIVZ4aAtNOWHhfAM7m7zprmkVcKK+2kK5YJ9Bmj6/ketTtOn7wGSHCtMt+LzqgYQ==
675 dependencies: 613 dependencies:
676 "@xtuc/long" "4.2.1" 614 "@xtuc/long" "4.2.1"
677 615
678"@webassemblyjs/utf8@1.7.11": 616"@webassemblyjs/utf8@1.7.10":
679 version "1.7.11" 617 version "1.7.10"
680 resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.11.tgz#06d7218ea9fdc94a6793aa92208160db3d26ee82" 618 resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.10.tgz#b6728f5b6f50364abc155be029f9670e6685605a"
681 integrity sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA== 619 integrity sha512-Ng6Pxv6siyZp635xCSnH3mKmIFgqWPCcGdoo0GBYgyGdxu7cUj4agV7Uu1a8REP66UYUFXJLudeGgd4RvuJAnQ==
682 620
683"@webassemblyjs/utf8@1.7.6": 621"@webassemblyjs/wasm-edit@1.7.10":
684 version "1.7.6" 622 version "1.7.10"
685 resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.6.tgz#eb62c66f906af2be70de0302e29055d25188797d" 623 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.10.tgz#83fe3140f5a58f5a30b914702be9f0e59a399092"
686 integrity sha512-oId+tLxQ+AeDC34ELRYNSqJRaScB0TClUU6KQfpB8rNT6oelYlz8axsPhf6yPTg7PBJ/Z5WcXmUYiHEWgbbHJw== 624 integrity sha512-e9RZFQlb+ZuYcKRcW9yl+mqX/Ycj9+3/+ppDI8nEE/NCY6FoK8f3dKBcfubYV/HZn44b+ND4hjh+4BYBt+sDnA==
687 625 dependencies:
688"@webassemblyjs/wasm-edit@1.7.11": 626 "@webassemblyjs/ast" "1.7.10"
689 version "1.7.11" 627 "@webassemblyjs/helper-buffer" "1.7.10"
690 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz#8c74ca474d4f951d01dbae9bd70814ee22a82005" 628 "@webassemblyjs/helper-wasm-bytecode" "1.7.10"
691 integrity sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg== 629 "@webassemblyjs/helper-wasm-section" "1.7.10"
692 dependencies: 630 "@webassemblyjs/wasm-gen" "1.7.10"
693 "@webassemblyjs/ast" "1.7.11" 631 "@webassemblyjs/wasm-opt" "1.7.10"
694 "@webassemblyjs/helper-buffer" "1.7.11" 632 "@webassemblyjs/wasm-parser" "1.7.10"
695 "@webassemblyjs/helper-wasm-bytecode" "1.7.11" 633 "@webassemblyjs/wast-printer" "1.7.10"
696 "@webassemblyjs/helper-wasm-section" "1.7.11" 634
697 "@webassemblyjs/wasm-gen" "1.7.11" 635"@webassemblyjs/wasm-gen@1.7.10":
698 "@webassemblyjs/wasm-opt" "1.7.11" 636 version "1.7.10"
699 "@webassemblyjs/wasm-parser" "1.7.11" 637 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.10.tgz#4de003806ae29c97ab3707782469b53299570174"
700 "@webassemblyjs/wast-printer" "1.7.11" 638 integrity sha512-M0lb6cO2Y0PzDye/L39PqwV+jvO+2YxEG5ax+7dgq7EwXdAlpOMx1jxyXJTScQoeTpzOPIb+fLgX/IkLF8h2yw==
701 639 dependencies:
702"@webassemblyjs/wasm-edit@1.7.6": 640 "@webassemblyjs/ast" "1.7.10"
703 version "1.7.6" 641 "@webassemblyjs/helper-wasm-bytecode" "1.7.10"
704 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.6.tgz#fa41929160cd7d676d4c28ecef420eed5b3733c5" 642 "@webassemblyjs/ieee754" "1.7.10"
705 integrity sha512-pTNjLO3o41v/Vz9VFLl+I3YLImpCSpodFW77pNoH4agn5I6GgSxXHXtvWDTvYJFty0jSeXZWLEmbaSIRUDlekg== 643 "@webassemblyjs/leb128" "1.7.10"
706 dependencies: 644 "@webassemblyjs/utf8" "1.7.10"
707 "@webassemblyjs/ast" "1.7.6" 645
708 "@webassemblyjs/helper-buffer" "1.7.6" 646"@webassemblyjs/wasm-opt@1.7.10":
709 "@webassemblyjs/helper-wasm-bytecode" "1.7.6" 647 version "1.7.10"
710 "@webassemblyjs/helper-wasm-section" "1.7.6" 648 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.10.tgz#d151e31611934a556c82789fdeec41a814993c2a"
711 "@webassemblyjs/wasm-gen" "1.7.6" 649 integrity sha512-R66IHGCdicgF5ZliN10yn5HaC7vwYAqrSVJGjtJJQp5+QNPBye6heWdVH/at40uh0uoaDN/UVUfXK0gvuUqtVg==
712 "@webassemblyjs/wasm-opt" "1.7.6" 650 dependencies:
713 "@webassemblyjs/wasm-parser" "1.7.6" 651 "@webassemblyjs/ast" "1.7.10"
714 "@webassemblyjs/wast-printer" "1.7.6" 652 "@webassemblyjs/helper-buffer" "1.7.10"
715 653 "@webassemblyjs/wasm-gen" "1.7.10"
716"@webassemblyjs/wasm-gen@1.7.11": 654 "@webassemblyjs/wasm-parser" "1.7.10"
717 version "1.7.11" 655
718 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz#9bbba942f22375686a6fb759afcd7ac9c45da1a8" 656"@webassemblyjs/wasm-parser@1.7.10":
719 integrity sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA== 657 version "1.7.10"
720 dependencies: 658 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.10.tgz#0367be7bf8f09e3e6abc95f8e483b9206487ec65"
721 "@webassemblyjs/ast" "1.7.11" 659 integrity sha512-AEv8mkXVK63n/iDR3T693EzoGPnNAwKwT3iHmKJNBrrALAhhEjuPzo/lTE4U7LquEwyvg5nneSNdTdgrBaGJcA==
722 "@webassemblyjs/helper-wasm-bytecode" "1.7.11" 660 dependencies:
723 "@webassemblyjs/ieee754" "1.7.11" 661 "@webassemblyjs/ast" "1.7.10"
724 "@webassemblyjs/leb128" "1.7.11" 662 "@webassemblyjs/helper-api-error" "1.7.10"
725 "@webassemblyjs/utf8" "1.7.11" 663 "@webassemblyjs/helper-wasm-bytecode" "1.7.10"
726 664 "@webassemblyjs/ieee754" "1.7.10"
727"@webassemblyjs/wasm-gen@1.7.6": 665 "@webassemblyjs/leb128" "1.7.10"
728 version "1.7.6" 666 "@webassemblyjs/utf8" "1.7.10"
729 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.6.tgz#695ac38861ab3d72bf763c8c75e5f087ffabc322" 667
730 integrity sha512-mQvFJVumtmRKEUXMohwn8nSrtjJJl6oXwF3FotC5t6e2hlKMh8sIaW03Sck2MDzw9xPogZD7tdP5kjPlbH9EcQ== 668"@webassemblyjs/wast-parser@1.7.10":
731 dependencies: 669 version "1.7.10"
732 "@webassemblyjs/ast" "1.7.6" 670 resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.10.tgz#058f598b52f730b23fc874d4775b6286b6247264"
733 "@webassemblyjs/helper-wasm-bytecode" "1.7.6" 671 integrity sha512-YTPEtOBljkCL0VjDp4sHe22dAYSm3ZwdJ9+2NTGdtC7ayNvuip1wAhaAS8Zt9Q6SW9E5Jf5PX7YE3XWlrzR9cw==
734 "@webassemblyjs/ieee754" "1.7.6" 672 dependencies:
735 "@webassemblyjs/leb128" "1.7.6" 673 "@webassemblyjs/ast" "1.7.10"
736 "@webassemblyjs/utf8" "1.7.6" 674 "@webassemblyjs/floating-point-hex-parser" "1.7.10"
737 675 "@webassemblyjs/helper-api-error" "1.7.10"
738"@webassemblyjs/wasm-opt@1.7.11": 676 "@webassemblyjs/helper-code-frame" "1.7.10"
739 version "1.7.11" 677 "@webassemblyjs/helper-fsm" "1.7.10"
740 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz#b331e8e7cef8f8e2f007d42c3a36a0580a7d6ca7"
741 integrity sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==
742 dependencies:
743 "@webassemblyjs/ast" "1.7.11"
744 "@webassemblyjs/helper-buffer" "1.7.11"
745 "@webassemblyjs/wasm-gen" "1.7.11"
746 "@webassemblyjs/wasm-parser" "1.7.11"
747
748"@webassemblyjs/wasm-opt@1.7.6":
749 version "1.7.6"
750 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.6.tgz#fbafa78e27e1a75ab759a4b658ff3d50b4636c21"
751 integrity sha512-go44K90fSIsDwRgtHhX14VtbdDPdK2sZQtZqUcMRvTojdozj5tLI0VVJAzLCfz51NOkFXezPeVTAYFqrZ6rI8Q==
752 dependencies:
753 "@webassemblyjs/ast" "1.7.6"
754 "@webassemblyjs/helper-buffer" "1.7.6"
755 "@webassemblyjs/wasm-gen" "1.7.6"
756 "@webassemblyjs/wasm-parser" "1.7.6"
757
758"@webassemblyjs/wasm-parser@1.7.11":
759 version "1.7.11"
760 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz#6e3d20fa6a3519f6b084ef9391ad58211efb0a1a"
761 integrity sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==
762 dependencies:
763 "@webassemblyjs/ast" "1.7.11"
764 "@webassemblyjs/helper-api-error" "1.7.11"
765 "@webassemblyjs/helper-wasm-bytecode" "1.7.11"
766 "@webassemblyjs/ieee754" "1.7.11"
767 "@webassemblyjs/leb128" "1.7.11"
768 "@webassemblyjs/utf8" "1.7.11"
769
770"@webassemblyjs/wasm-parser@1.7.6":
771 version "1.7.6"
772 resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.6.tgz#84eafeeff405ad6f4c4b5777d6a28ae54eed51fe"
773 integrity sha512-t1T6TfwNY85pDA/HWPA8kB9xA4sp9ajlRg5W7EKikqrynTyFo+/qDzIpvdkOkOGjlS6d4n4SX59SPuIayR22Yg==
774 dependencies:
775 "@webassemblyjs/ast" "1.7.6"
776 "@webassemblyjs/helper-api-error" "1.7.6"
777 "@webassemblyjs/helper-wasm-bytecode" "1.7.6"
778 "@webassemblyjs/ieee754" "1.7.6"
779 "@webassemblyjs/leb128" "1.7.6"
780 "@webassemblyjs/utf8" "1.7.6"
781
782"@webassemblyjs/wast-parser@1.7.11":
783 version "1.7.11"
784 resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz#25bd117562ca8c002720ff8116ef9072d9ca869c"
785 integrity sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==
786 dependencies:
787 "@webassemblyjs/ast" "1.7.11"
788 "@webassemblyjs/floating-point-hex-parser" "1.7.11"
789 "@webassemblyjs/helper-api-error" "1.7.11"
790 "@webassemblyjs/helper-code-frame" "1.7.11"
791 "@webassemblyjs/helper-fsm" "1.7.11"
792 "@xtuc/long" "4.2.1"
793
794"@webassemblyjs/wast-parser@1.7.6":
795 version "1.7.6"
796 resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.6.tgz#ca4d20b1516e017c91981773bd7e819d6bd9c6a7"
797 integrity sha512-1MaWTErN0ziOsNUlLdvwS+NS1QWuI/kgJaAGAMHX8+fMJFgOJDmN/xsG4h/A1Gtf/tz5VyXQciaqHZqp2q0vfg==
798 dependencies:
799 "@webassemblyjs/ast" "1.7.6"
800 "@webassemblyjs/floating-point-hex-parser" "1.7.6"
801 "@webassemblyjs/helper-api-error" "1.7.6"
802 "@webassemblyjs/helper-code-frame" "1.7.6"
803 "@webassemblyjs/helper-fsm" "1.7.6"
804 "@xtuc/long" "4.2.1" 678 "@xtuc/long" "4.2.1"
805 mamacro "^0.0.3"
806 679
807"@webassemblyjs/wast-printer@1.7.11": 680"@webassemblyjs/wast-printer@1.7.10":
808 version "1.7.11" 681 version "1.7.10"
809 resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz#c4245b6de242cb50a2cc950174fdbf65c78d7813" 682 resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.10.tgz#d817909d2450ae96c66b7607624d98a33b84223b"
810 integrity sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg== 683 integrity sha512-mJ3QKWtCchL1vhU/kZlJnLPuQZnlDOdZsyP0bbLWPGdYsQDnSBvyTLhzwBA3QAMlzEL9V4JHygEmK6/OTEyytA==
811 dependencies: 684 dependencies:
812 "@webassemblyjs/ast" "1.7.11" 685 "@webassemblyjs/ast" "1.7.10"
813 "@webassemblyjs/wast-parser" "1.7.11" 686 "@webassemblyjs/wast-parser" "1.7.10"
814 "@xtuc/long" "4.2.1"
815
816"@webassemblyjs/wast-printer@1.7.6":
817 version "1.7.6"
818 resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.6.tgz#a6002c526ac5fa230fe2c6d2f1bdbf4aead43a5e"
819 integrity sha512-vHdHSK1tOetvDcl1IV1OdDeGNe/NDDQ+KzuZHMtqTVP1xO/tZ/IKNpj5BaGk1OYFdsDWQqb31PIwdEyPntOWRQ==
820 dependencies:
821 "@webassemblyjs/ast" "1.7.6"
822 "@webassemblyjs/wast-parser" "1.7.6"
823 "@xtuc/long" "4.2.1" 687 "@xtuc/long" "4.2.1"
824 688
825"@xtuc/ieee754@^1.2.0": 689"@xtuc/ieee754@^1.2.0":
@@ -832,6 +696,19 @@
832 resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" 696 resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8"
833 integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g== 697 integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==
834 698
699"@yarnpkg/lockfile@1.1.0":
700 version "1.1.0"
701 resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
702 integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
703
704JSONStream@^1.3.4:
705 version "1.3.5"
706 resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
707 integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==
708 dependencies:
709 jsonparse "^1.2.0"
710 through ">=2.2.7 <3"
711
835abab@^2.0.0: 712abab@^2.0.0:
836 version "2.0.0" 713 version "2.0.0"
837 resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" 714 resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f"
@@ -909,13 +786,20 @@ after@0.8.2:
909 resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" 786 resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
910 integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= 787 integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
911 788
912agent-base@^4.1.0: 789agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0:
913 version "4.2.1" 790 version "4.2.1"
914 resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" 791 resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
915 integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== 792 integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
916 dependencies: 793 dependencies:
917 es6-promisify "^5.0.0" 794 es6-promisify "^5.0.0"
918 795
796agentkeepalive@^3.4.1:
797 version "3.5.2"
798 resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67"
799 integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==
800 dependencies:
801 humanize-ms "^1.2.1"
802
919ajv-errors@^1.0.0: 803ajv-errors@^1.0.0:
920 version "1.0.0" 804 version "1.0.0"
921 resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.0.tgz#ecf021fa108fd17dfb5e6b383f2dd233e31ffc59" 805 resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.0.tgz#ecf021fa108fd17dfb5e6b383f2dd233e31ffc59"
@@ -944,7 +828,7 @@ ajv@^4.11.2:
944 co "^4.6.0" 828 co "^4.6.0"
945 json-stable-stringify "^1.0.1" 829 json-stable-stringify "^1.0.1"
946 830
947ajv@^5.0.0, ajv@^5.1.0: 831ajv@^5.0.0:
948 version "5.5.2" 832 version "5.5.2"
949 resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" 833 resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
950 integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= 834 integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=
@@ -955,9 +839,9 @@ ajv@^5.0.0, ajv@^5.1.0:
955 json-schema-traverse "^0.3.0" 839 json-schema-traverse "^0.3.0"
956 840
957ajv@^6.1.0, ajv@^6.5.5: 841ajv@^6.1.0, ajv@^6.5.5:
958 version "6.5.5" 842 version "6.6.1"
959 resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" 843 resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61"
960 integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== 844 integrity sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==
961 dependencies: 845 dependencies:
962 fast-deep-equal "^2.0.1" 846 fast-deep-equal "^2.0.1"
963 fast-json-stable-stringify "^2.0.0" 847 fast-json-stable-stringify "^2.0.0"
@@ -977,15 +861,10 @@ angular2-hotkeys@^2.1.2:
977 "@types/mousetrap" "^1.6.0" 861 "@types/mousetrap" "^1.6.0"
978 mousetrap "^1.6.0" 862 mousetrap "^1.6.0"
979 863
980angular2-notifications@^1.0.2:
981 version "1.0.4"
982 resolved "https://registry.yarnpkg.com/angular2-notifications/-/angular2-notifications-1.0.4.tgz#7b3c449dbad45503965f8cd8ac00e998a4463544"
983 integrity sha512-DjazfwXtLY8BNXKIEw1oEEMy7G6fmldpzP1FYwyVGUwEtZPLQyYGu9MQYCjtVlZMljxpa3qvnv8l9ZUfXAarNA==
984
985ansi-colors@^3.0.0: 864ansi-colors@^3.0.0:
986 version "3.2.1" 865 version "3.2.2"
987 resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.1.tgz#9638047e4213f3428a11944a7d4b31cba0a3ff95" 866 resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.2.tgz#e49349137dbeb6d381b91e607c189915e53265ba"
988 integrity sha512-Xt+zb6nqgvV9SWAVp0EG3lRsHcbq5DDgqjPPz6pwgtj6RKz65zGXMNa82oJfOSBA/to6GmRP7Dr+6o+kbApTzQ== 867 integrity sha512-kJmcp4PrviBBEx95fC3dYRiC/QSN3EBd0GU1XoNEk/IuUa92rsB6o90zP3w5VAyNznR38Vkc9i8vk5zK6T7TxA==
989 868
990ansi-escapes@^3.0.0: 869ansi-escapes@^3.0.0:
991 version "3.1.0" 870 version "3.1.0"
@@ -1112,9 +991,9 @@ array-flatten@1.1.1:
1112 integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= 991 integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
1113 992
1114array-flatten@^2.1.0: 993array-flatten@^2.1.0:
1115 version "2.1.1" 994 version "2.1.2"
1116 resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.1.tgz#426bb9da84090c1838d812c8150af20a8331e296" 995 resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
1117 integrity sha1-Qmu52oQJDBg42BLIFQryCoMx4pY= 996 integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
1118 997
1119array-slice@^0.2.3: 998array-slice@^0.2.3:
1120 version "0.2.3" 999 version "0.2.3"
@@ -1238,17 +1117,17 @@ atob@^2.1.1:
1238 resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" 1117 resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
1239 integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== 1118 integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
1240 1119
1241autoprefixer@9.1.5: 1120autoprefixer@9.3.1:
1242 version "9.1.5" 1121 version "9.3.1"
1243 resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.1.5.tgz#8675fd8d1c0d43069f3b19a2c316f3524e4f6671" 1122 resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.3.1.tgz#71b622174de2b783d5fd99f9ad617b7a3c78443e"
1244 integrity sha512-kk4Zb6RUc58ld7gdosERHMF3DzIYJc2fp5sX46qEsGXQQy5bXsu8qyLjoxuY1NuQ/cJuCYnx99BfjwnRggrYIw== 1123 integrity sha512-DY9gOh8z3tnCbJ13JIWaeQsoYncTGdsrgCceBaQSIL4nvdrLxgbRSBPevg2XbX7u4QCSfLheSJEEIUUSlkbx6Q==
1245 dependencies: 1124 dependencies:
1246 browserslist "^4.1.0" 1125 browserslist "^4.3.3"
1247 caniuse-lite "^1.0.30000884" 1126 caniuse-lite "^1.0.30000898"
1248 normalize-range "^0.1.2" 1127 normalize-range "^0.1.2"
1249 num2fraction "^1.2.2" 1128 num2fraction "^1.2.2"
1250 postcss "^7.0.2" 1129 postcss "^7.0.5"
1251 postcss-value-parser "^3.2.3" 1130 postcss-value-parser "^3.3.1"
1252 1131
1253awesome-typescript-loader@5.2.1: 1132awesome-typescript-loader@5.2.1:
1254 version "5.2.1" 1133 version "5.2.1"
@@ -1269,7 +1148,7 @@ aws-sign2@~0.7.0:
1269 resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" 1148 resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
1270 integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= 1149 integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
1271 1150
1272aws4@^1.6.0, aws4@^1.8.0: 1151aws4@^1.8.0:
1273 version "1.8.0" 1152 version "1.8.0"
1274 resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" 1153 resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
1275 integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== 1154 integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
@@ -1631,7 +1510,7 @@ blocking-proxy@^1.0.0:
1631 dependencies: 1510 dependencies:
1632 minimist "^1.2.0" 1511 minimist "^1.2.0"
1633 1512
1634bluebird@^3.3.0, bluebird@^3.5.1: 1513bluebird@^3.3.0, bluebird@^3.5.1, bluebird@^3.5.2:
1635 version "3.5.3" 1514 version "3.5.3"
1636 resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" 1515 resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7"
1637 integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== 1516 integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==
@@ -1800,14 +1679,14 @@ browserify-zlib@^0.2.0:
1800 dependencies: 1679 dependencies:
1801 pako "~1.0.5" 1680 pako "~1.0.5"
1802 1681
1803browserslist@^4.1.0: 1682browserslist@^4.3.3:
1804 version "4.3.4" 1683 version "4.3.5"
1805 resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.4.tgz#4477b737db6a1b07077275b24791e680d4300425" 1684 resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.5.tgz#1a917678acc07b55606748ea1adf9846ea8920f7"
1806 integrity sha512-u5iz+ijIMUlmV8blX82VGFrB9ecnUg5qEt55CMZ/YJEhha+d8qpBfOFuutJ6F/VKRXjZoD33b6uvarpPxcl3RA== 1685 integrity sha512-z9ZhGc3d9e/sJ9dIx5NFXkKoaiQTnrvrMsN3R1fGb1tkWWNSz12UewJn9TNxGo1l7J23h0MRaPmk7jfeTZYs1w==
1807 dependencies: 1686 dependencies:
1808 caniuse-lite "^1.0.30000899" 1687 caniuse-lite "^1.0.30000912"
1809 electron-to-chromium "^1.3.82" 1688 electron-to-chromium "^1.3.86"
1810 node-releases "^1.0.1" 1689 node-releases "^1.0.5"
1811 1690
1812browserstack@^1.5.1: 1691browserstack@^1.5.1:
1813 version "1.5.1" 1692 version "1.5.1"
@@ -1931,7 +1810,7 @@ cacache@^10.0.4:
1931 unique-filename "^1.1.0" 1810 unique-filename "^1.1.0"
1932 y18n "^4.0.0" 1811 y18n "^4.0.0"
1933 1812
1934cacache@^11.0.2: 1813cacache@^11.0.1, cacache@^11.0.2, cacache@^11.2.0:
1935 version "11.3.1" 1814 version "11.3.1"
1936 resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.1.tgz#d09d25f6c4aca7a6d305d141ae332613aa1d515f" 1815 resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.1.tgz#d09d25f6c4aca7a6d305d141ae332613aa1d515f"
1937 integrity sha512-2PEw4cRRDu+iQvBTTuttQifacYjLPhET+SYO/gEFMy8uhi+jlJREDAjSF5FWSdV/Aw5h18caHA7vMTw2c+wDzA== 1816 integrity sha512-2PEw4cRRDu+iQvBTTuttQifacYjLPhET+SYO/gEFMy8uhi+jlJREDAjSF5FWSdV/Aw5h18caHA7vMTw2c+wDzA==
@@ -2014,10 +1893,15 @@ camelcase@^4.1.0:
2014 resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" 1893 resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
2015 integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= 1894 integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
2016 1895
2017caniuse-lite@^1.0.30000884, caniuse-lite@^1.0.30000899: 1896camelcase@^5.0.0:
2018 version "1.0.30000907" 1897 version "5.0.0"
2019 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000907.tgz#0b9899bde53fb1c30e214fb12402361e02ff5c42" 1898 resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42"
2020 integrity sha512-No5sQ/OB2Nmka8MNOOM6nJx+Hxt6MQ6h7t7kgJFu9oTuwjykyKRSBP/+i/QAyFHxeHB+ddE0Da1CG5ihx9oehQ== 1899 integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==
1900
1901caniuse-lite@^1.0.30000898, caniuse-lite@^1.0.30000912:
1902 version "1.0.30000914"
1903 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000914.tgz#f802b4667c24d0255f54a95818dcf8e1aa41f624"
1904 integrity sha512-qqj0CL1xANgg6iDOybiPTIxtsmAnfIky9mBC35qgWrnK4WwmhqfpmkDYMYgwXJ8LRZ3/2jXlCntulO8mBaAgSg==
2021 1905
2022canonical-path@1.0.0: 1906canonical-path@1.0.0:
2023 version "1.0.0" 1907 version "1.0.0"
@@ -2276,7 +2160,7 @@ combine-lists@^1.0.0:
2276 dependencies: 2160 dependencies:
2277 lodash "^4.5.0" 2161 lodash "^4.5.0"
2278 2162
2279combined-stream@^1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: 2163combined-stream@^1.0.6, combined-stream@~1.0.6:
2280 version "1.0.7" 2164 version "1.0.7"
2281 resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" 2165 resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
2282 integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== 2166 integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==
@@ -2355,7 +2239,7 @@ concat-map@0.0.1:
2355 resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 2239 resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
2356 integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 2240 integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
2357 2241
2358concat-stream@^1.5.0, concat-stream@^1.5.2: 2242concat-stream@^1.5.0:
2359 version "1.6.2" 2243 version "1.6.2"
2360 resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" 2244 resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
2361 integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== 2245 integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
@@ -2622,6 +2506,14 @@ css-selector-tokenizer@^0.7.0:
2622 fastparse "^1.1.1" 2506 fastparse "^1.1.1"
2623 regexpu-core "^1.0.0" 2507 regexpu-core "^1.0.0"
2624 2508
2509css-tree@^1.0.0-alpha.29:
2510 version "1.0.0-alpha.29"
2511 resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.29.tgz#3fa9d4ef3142cbd1c301e7664c1f352bd82f5a39"
2512 integrity sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==
2513 dependencies:
2514 mdn-data "~1.1.0"
2515 source-map "^0.5.3"
2516
2625css-what@2.1: 2517css-what@2.1:
2626 version "2.1.2" 2518 version "2.1.2"
2627 resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d" 2519 resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.2.tgz#c0876d9d0480927d7d4920dcd72af3595649554d"
@@ -2718,28 +2610,28 @@ debug@*, debug@^4.0.1, debug@^4.1.0:
2718 dependencies: 2610 dependencies:
2719 ms "^2.1.1" 2611 ms "^2.1.1"
2720 2612
2721debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9: 2613debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
2722 version "2.6.9" 2614 version "2.6.9"
2723 resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 2615 resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
2724 integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 2616 integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
2725 dependencies: 2617 dependencies:
2726 ms "2.0.0" 2618 ms "2.0.0"
2727 2619
2728debug@=3.1.0, debug@~3.1.0: 2620debug@3.1.0, debug@=3.1.0, debug@~3.1.0:
2729 version "3.1.0" 2621 version "3.1.0"
2730 resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 2622 resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
2731 integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 2623 integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
2732 dependencies: 2624 dependencies:
2733 ms "2.0.0" 2625 ms "2.0.0"
2734 2626
2735debug@^3.1.0: 2627debug@^3.1.0, debug@^3.2.5:
2736 version "3.2.6" 2628 version "3.2.6"
2737 resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 2629 resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
2738 integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== 2630 integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
2739 dependencies: 2631 dependencies:
2740 ms "^2.1.1" 2632 ms "^2.1.1"
2741 2633
2742decamelize@^1.1.1, decamelize@^1.1.2: 2634decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0:
2743 version "1.2.0" 2635 version "1.2.0"
2744 resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 2636 resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
2745 integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 2637 integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
@@ -3106,10 +2998,10 @@ ejs@^2.6.1:
3106 resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" 2998 resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
3107 integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== 2999 integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==
3108 3000
3109electron-to-chromium@^1.3.82: 3001electron-to-chromium@^1.3.86:
3110 version "1.3.84" 3002 version "1.3.88"
3111 resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.84.tgz#2e55df59e818f150a9f61b53471ebf4f0feecc65" 3003 resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.88.tgz#f36ab32634f49ef2b0fdc1e82e2d1cc17feb29e7"
3112 integrity sha512-IYhbzJYOopiTaNWMBp7RjbecUBsbnbDneOP86f3qvS0G0xfzwNSvMJpTrvi5/Y1gU7tg2NAgeg8a8rCYvW9Whw== 3004 integrity sha512-UPV4NuQMKeUh1S0OWRvwg0PI8ASHN9kBC8yDTk1ROXLC85W5GnhTRu/MZu3Teqx3JjlQYuckuHYXSUSgtb3J+A==
3113 3005
3114elliptic@^6.0.0: 3006elliptic@^6.0.0:
3115 version "6.4.1" 3007 version "6.4.1"
@@ -3134,6 +3026,13 @@ encodeurl@~1.0.1, encodeurl@~1.0.2:
3134 resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 3026 resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
3135 integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 3027 integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
3136 3028
3029encoding@^0.1.11:
3030 version "0.1.12"
3031 resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
3032 integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=
3033 dependencies:
3034 iconv-lite "~0.4.13"
3035
3137end-of-stream@^1.0.0, end-of-stream@^1.1.0: 3036end-of-stream@^1.0.0, end-of-stream@^1.1.0:
3138 version "1.4.1" 3037 version "1.4.1"
3139 resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" 3038 resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
@@ -3158,6 +3057,23 @@ engine.io-client@~3.2.0:
3158 xmlhttprequest-ssl "~1.5.4" 3057 xmlhttprequest-ssl "~1.5.4"
3159 yeast "0.1.2" 3058 yeast "0.1.2"
3160 3059
3060engine.io-client@~3.3.1:
3061 version "3.3.1"
3062 resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.3.1.tgz#afedb4a07b2ea48b7190c3136bfea98fdd4f0f03"
3063 integrity sha512-q66JBFuQcy7CSlfAz9L3jH+v7DTT3i6ZEadYcVj2pOs8/0uJHLxKX3WBkGTvULJMdz0tUCyJag0aKT/dpXL9BQ==
3064 dependencies:
3065 component-emitter "1.2.1"
3066 component-inherit "0.0.3"
3067 debug "~3.1.0"
3068 engine.io-parser "~2.1.1"
3069 has-cors "1.1.0"
3070 indexof "0.0.1"
3071 parseqs "0.0.5"
3072 parseuri "0.0.5"
3073 ws "~6.1.0"
3074 xmlhttprequest-ssl "~1.5.4"
3075 yeast "0.1.2"
3076
3161engine.io-parser@~2.1.0, engine.io-parser@~2.1.1: 3077engine.io-parser@~2.1.0, engine.io-parser@~2.1.1:
3162 version "2.1.3" 3078 version "2.1.3"
3163 resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6" 3079 resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6"
@@ -3200,6 +3116,11 @@ entities@^1.1.1, entities@~1.1.1:
3200 resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" 3116 resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
3201 integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== 3117 integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
3202 3118
3119err-code@^1.0.0:
3120 version "1.1.2"
3121 resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960"
3122 integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=
3123
3203errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: 3124errno@^0.1.1, errno@^0.1.3, errno@~0.1.7:
3204 version "0.1.7" 3125 version "0.1.7"
3205 resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" 3126 resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
@@ -3384,12 +3305,12 @@ events@^1.0.0:
3384 resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" 3305 resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
3385 integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= 3306 integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=
3386 3307
3387eventsource@0.1.6: 3308eventsource@^1.0.7:
3388 version "0.1.6" 3309 version "1.0.7"
3389 resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" 3310 resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0"
3390 integrity sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI= 3311 integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==
3391 dependencies: 3312 dependencies:
3392 original ">=0.0.5" 3313 original "^1.0.0"
3393 3314
3394evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: 3315evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
3395 version "1.0.3" 3316 version "1.0.3"
@@ -3544,7 +3465,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
3544 assign-symbols "^1.0.0" 3465 assign-symbols "^1.0.0"
3545 is-extendable "^1.0.1" 3466 is-extendable "^1.0.1"
3546 3467
3547extend@^3.0.0, extend@~3.0.1, extend@~3.0.2: 3468extend@^3.0.0, extend@~3.0.2:
3548 version "3.0.2" 3469 version "3.0.2"
3549 resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" 3470 resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
3550 integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== 3471 integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
@@ -3631,7 +3552,7 @@ faye-websocket@^0.10.0:
3631 dependencies: 3552 dependencies:
3632 websocket-driver ">=0.5.1" 3553 websocket-driver ">=0.5.1"
3633 3554
3634faye-websocket@~0.11.0: 3555faye-websocket@~0.11.1:
3635 version "0.11.1" 3556 version "0.11.1"
3636 resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" 3557 resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38"
3637 integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg= 3558 integrity sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=
@@ -3645,7 +3566,7 @@ fb-watchman@^2.0.0:
3645 dependencies: 3566 dependencies:
3646 bser "^2.0.0" 3567 bser "^2.0.0"
3647 3568
3648figgy-pudding@^3.1.0, figgy-pudding@^3.5.1: 3569figgy-pudding@^3.1.0, figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
3649 version "3.5.1" 3570 version "3.5.1"
3650 resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" 3571 resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
3651 integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== 3572 integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
@@ -3780,6 +3701,11 @@ find-up@^3.0.0:
3780 dependencies: 3701 dependencies:
3781 locate-path "^3.0.0" 3702 locate-path "^3.0.0"
3782 3703
3704flatted@^2.0.0:
3705 version "2.0.0"
3706 resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916"
3707 integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==
3708
3783flatten@^1.0.2: 3709flatten@^1.0.2:
3784 version "1.0.2" 3710 version "1.0.2"
3785 resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" 3711 resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
@@ -3799,9 +3725,9 @@ focus-visible@^4.1.5:
3799 integrity sha512-yo/njtk/BB4Z2euzaZe3CZrg4u5s5uEi7ZwbHBJS2quHx51N0mmcx9nTIiImUGlgy+vf26d0CcQluahBBBL/Fw== 3725 integrity sha512-yo/njtk/BB4Z2euzaZe3CZrg4u5s5uEi7ZwbHBJS2quHx51N0mmcx9nTIiImUGlgy+vf26d0CcQluahBBBL/Fw==
3800 3726
3801follow-redirects@^1.0.0: 3727follow-redirects@^1.0.0:
3802 version "1.5.9" 3728 version "1.5.10"
3803 resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.9.tgz#c9ed9d748b814a39535716e531b9196a845d89c6" 3729 resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
3804 integrity sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w== 3730 integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
3805 dependencies: 3731 dependencies:
3806 debug "=3.1.0" 3732 debug "=3.1.0"
3807 3733
@@ -3841,7 +3767,7 @@ forever-agent@~0.6.1:
3841 resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" 3767 resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
3842 integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= 3768 integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
3843 3769
3844form-data@~2.3.1, form-data@~2.3.2: 3770form-data@~2.3.2:
3845 version "2.3.3" 3771 version "2.3.3"
3846 resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" 3772 resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
3847 integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== 3773 integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
@@ -3969,6 +3895,11 @@ gaze@^1.0.0:
3969 dependencies: 3895 dependencies:
3970 globule "^1.0.0" 3896 globule "^1.0.0"
3971 3897
3898genfun@^5.0.0:
3899 version "5.0.0"
3900 resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537"
3901 integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==
3902
3972get-browser-rtc@^1.0.0: 3903get-browser-rtc@^1.0.0:
3973 version "1.0.2" 3904 version "1.0.2"
3974 resolved "https://registry.yarnpkg.com/get-browser-rtc/-/get-browser-rtc-1.0.2.tgz#bbcd40c8451a7ed4ef5c373b8169a409dd1d11d9" 3905 resolved "https://registry.yarnpkg.com/get-browser-rtc/-/get-browser-rtc-1.0.2.tgz#bbcd40c8451a7ed4ef5c373b8169a409dd1d11d9"
@@ -3994,6 +3925,13 @@ get-stream@^3.0.0:
3994 resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" 3925 resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
3995 integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= 3926 integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
3996 3927
3928get-stream@^4.1.0:
3929 version "4.1.0"
3930 resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
3931 integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
3932 dependencies:
3933 pump "^3.0.0"
3934
3997get-value@^2.0.3, get-value@^2.0.6: 3935get-value@^2.0.3, get-value@^2.0.6:
3998 version "2.0.6" 3936 version "2.0.6"
3999 resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" 3937 resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
@@ -4053,7 +3991,7 @@ glob@7.1.2:
4053 once "^1.3.0" 3991 once "^1.3.0"
4054 path-is-absolute "^1.0.0" 3992 path-is-absolute "^1.0.0"
4055 3993
4056glob@7.1.3, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: 3994glob@7.1.3, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@~7.1.1:
4057 version "7.1.3" 3995 version "7.1.3"
4058 resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" 3996 resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
4059 integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== 3997 integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
@@ -4077,9 +4015,9 @@ glob@^5.0.15:
4077 path-is-absolute "^1.0.0" 4015 path-is-absolute "^1.0.0"
4078 4016
4079global-modules-path@^2.3.0: 4017global-modules-path@^2.3.0:
4080 version "2.3.0" 4018 version "2.3.1"
4081 resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.0.tgz#b0e2bac6beac39745f7db5c59d26a36a0b94f7dc" 4019 resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.1.tgz#e541f4c800a1a8514a990477b267ac67525b9931"
4082 integrity sha512-HchvMJNYh9dGSCy8pOQ2O8u/hoXaL+0XhnrwH0RyLiSXMMTl9W3N6KUU73+JFOg5PGjtzl6VZzUQsnrpm7Szag== 4020 integrity sha512-y+shkf4InI7mPRHSo2b/k6ix6+NLDtyccYv86whhxrSGX9wjPX1VMITmrDbE1eh7zkzhiWtW2sHklJYoQ62Cxg==
4083 4021
4084global@4.3.2, global@^4.3.0, global@^4.3.1, global@^4.3.2, global@~4.3.0: 4022global@4.3.2, global@^4.3.0, global@^4.3.1, global@^4.3.2, global@~4.3.0:
4085 version "4.3.2" 4023 version "4.3.2"
@@ -4182,14 +4120,6 @@ har-schema@^2.0.0:
4182 resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" 4120 resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
4183 integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= 4121 integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
4184 4122
4185har-validator@~5.0.3:
4186 version "5.0.3"
4187 resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
4188 integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=
4189 dependencies:
4190 ajv "^5.1.0"
4191 har-schema "^2.0.0"
4192
4193har-validator@~5.1.0: 4123har-validator@~5.1.0:
4194 version "5.1.3" 4124 version "5.1.3"
4195 resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" 4125 resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
@@ -4284,9 +4214,9 @@ hash-base@^3.0.0:
4284 safe-buffer "^5.0.1" 4214 safe-buffer "^5.0.1"
4285 4215
4286hash.js@^1.0.0, hash.js@^1.0.3: 4216hash.js@^1.0.0, hash.js@^1.0.3:
4287 version "1.1.5" 4217 version "1.1.7"
4288 resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" 4218 resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
4289 integrity sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA== 4219 integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
4290 dependencies: 4220 dependencies:
4291 inherits "^2.0.3" 4221 inherits "^2.0.3"
4292 minimalistic-assert "^1.0.1" 4222 minimalistic-assert "^1.0.1"
@@ -4382,7 +4312,7 @@ html-webpack-plugin@^3.2.0:
4382 toposort "^1.0.0" 4312 toposort "^1.0.0"
4383 util.promisify "1.0.0" 4313 util.promisify "1.0.0"
4384 4314
4385htmlparser2@^3.9.0: 4315htmlparser2@^3.10.0:
4386 version "3.10.0" 4316 version "3.10.0"
4387 resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464" 4317 resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.0.tgz#5f5e422dcf6119c0d983ed36260ce9ded0bee464"
4388 integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ== 4318 integrity sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==
@@ -4404,6 +4334,11 @@ htmlparser2@~3.3.0:
4404 domutils "1.1" 4334 domutils "1.1"
4405 readable-stream "1.0" 4335 readable-stream "1.0"
4406 4336
4337http-cache-semantics@^3.8.1:
4338 version "3.8.1"
4339 resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
4340 integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==
4341
4407http-deceiver@^1.2.7: 4342http-deceiver@^1.2.7:
4408 version "1.2.7" 4343 version "1.2.7"
4409 resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" 4344 resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
@@ -4424,6 +4359,14 @@ http-parser-js@>=0.4.0:
4424 resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8" 4359 resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8"
4425 integrity sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w== 4360 integrity sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==
4426 4361
4362http-proxy-agent@^2.1.0:
4363 version "2.1.0"
4364 resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
4365 integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==
4366 dependencies:
4367 agent-base "4"
4368 debug "3.1.0"
4369
4427http-proxy-middleware@~0.18.0: 4370http-proxy-middleware@~0.18.0:
4428 version "0.18.0" 4371 version "0.18.0"
4429 resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz#0987e6bb5a5606e5a69168d8f967a87f15dd8aab" 4372 resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz#0987e6bb5a5606e5a69168d8f967a87f15dd8aab"
@@ -4465,6 +4408,13 @@ https-proxy-agent@^2.2.1:
4465 agent-base "^4.1.0" 4408 agent-base "^4.1.0"
4466 debug "^3.1.0" 4409 debug "^3.1.0"
4467 4410
4411humanize-ms@^1.2.1:
4412 version "1.2.1"
4413 resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed"
4414 integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=
4415 dependencies:
4416 ms "^2.0.0"
4417
4468iconv-lite@0.4.23: 4418iconv-lite@0.4.23:
4469 version "0.4.23" 4419 version "0.4.23"
4470 resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" 4420 resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
@@ -4472,7 +4422,7 @@ iconv-lite@0.4.23:
4472 dependencies: 4422 dependencies:
4473 safer-buffer ">= 2.1.2 < 3" 4423 safer-buffer ">= 2.1.2 < 3"
4474 4424
4475iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: 4425iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
4476 version "0.4.24" 4426 version "0.4.24"
4477 resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 4427 resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
4478 integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 4428 integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -4603,7 +4553,7 @@ inherits@2.0.1:
4603 resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" 4553 resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
4604 integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= 4554 integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
4605 4555
4606ini@^1.3.4, ini@~1.3.0: 4556ini@1.3.5, ini@^1.3.4, ini@~1.3.0:
4607 version "1.3.5" 4557 version "1.3.5"
4608 resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" 4558 resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
4609 integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== 4559 integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
@@ -5640,7 +5590,7 @@ jsesc@~0.5.0:
5640 resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" 5590 resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
5641 integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= 5591 integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
5642 5592
5643json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: 5593json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
5644 version "1.0.2" 5594 version "1.0.2"
5645 resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" 5595 resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
5646 integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== 5596 integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
@@ -5701,6 +5651,11 @@ jsonify@~0.0.0:
5701 resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" 5651 resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
5702 integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= 5652 integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
5703 5653
5654jsonparse@^1.2.0:
5655 version "1.3.1"
5656 resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
5657 integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
5658
5704jsprim@^1.2.2: 5659jsprim@^1.2.2:
5705 version "1.4.1" 5660 version "1.4.1"
5706 resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" 5661 resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@@ -5796,9 +5751,9 @@ karma-source-map-support@1.3.0:
5796 source-map-support "^0.5.5" 5751 source-map-support "^0.5.5"
5797 5752
5798karma@^3.0.0: 5753karma@^3.0.0:
5799 version "3.1.1" 5754 version "3.1.3"
5800 resolved "https://registry.yarnpkg.com/karma/-/karma-3.1.1.tgz#94c8edd20fb9597ccde343326da009737fb0423a" 5755 resolved "https://registry.yarnpkg.com/karma/-/karma-3.1.3.tgz#6e251648e3aff900927bc1126dbcbcb92d3edd61"
5801 integrity sha512-NetT3wPCQMNB36uiL9LLyhrOt8SQwrEKt0xD3+KpTCfm0VxVyUJdPL5oTq2Ic5ouemgL/Iz4wqXEbF3zea9kQQ== 5756 integrity sha512-JU4FYUtFEGsLZd6ZJzLrivcPj0TkteBiIRDcXWFsltPMGgZMDtby/MIzNOzgyZv/9dahs9vHpSxerC/ZfeX9Qw==
5802 dependencies: 5757 dependencies:
5803 bluebird "^3.3.0" 5758 bluebird "^3.3.0"
5804 body-parser "^1.16.1" 5759 body-parser "^1.16.1"
@@ -5810,11 +5765,12 @@ karma@^3.0.0:
5810 di "^0.0.1" 5765 di "^0.0.1"
5811 dom-serialize "^2.2.0" 5766 dom-serialize "^2.2.0"
5812 expand-braces "^0.1.1" 5767 expand-braces "^0.1.1"
5768 flatted "^2.0.0"
5813 glob "^7.1.1" 5769 glob "^7.1.1"
5814 graceful-fs "^4.1.2" 5770 graceful-fs "^4.1.2"
5815 http-proxy "^1.13.0" 5771 http-proxy "^1.13.0"
5816 isbinaryfile "^3.0.0" 5772 isbinaryfile "^3.0.0"
5817 lodash "^4.17.4" 5773 lodash "^4.17.5"
5818 log4js "^3.0.0" 5774 log4js "^3.0.0"
5819 mime "^2.3.1" 5775 mime "^2.3.1"
5820 minimatch "^3.0.2" 5776 minimatch "^3.0.2"
@@ -5826,7 +5782,7 @@ karma@^3.0.0:
5826 socket.io "2.1.1" 5782 socket.io "2.1.1"
5827 source-map "^0.6.1" 5783 source-map "^0.6.1"
5828 tmp "0.0.33" 5784 tmp "0.0.33"
5829 useragent "2.2.1" 5785 useragent "2.3.0"
5830 5786
5831killable@^1.0.0: 5787killable@^1.0.0:
5832 version "1.0.1" 5788 version "1.0.1"
@@ -5939,9 +5895,9 @@ lie@~3.1.0:
5939 immediate "~3.0.5" 5895 immediate "~3.0.5"
5940 5896
5941linkify-it@^2.0.0: 5897linkify-it@^2.0.0:
5942 version "2.0.3" 5898 version "2.1.0"
5943 resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.3.tgz#d94a4648f9b1c179d64fa97291268bdb6ce9434f" 5899 resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.1.0.tgz#c4caf38a6cd7ac2212ef3c7d2bde30a91561f9db"
5944 integrity sha1-2UpGSPmxwXnWT6lykSaL22zpQ08= 5900 integrity sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==
5945 dependencies: 5901 dependencies:
5946 uc.micro "^1.0.1" 5902 uc.micro "^1.0.1"
5947 5903
@@ -6061,7 +6017,7 @@ lodash.isstring@^4.0.1:
6061 resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" 6017 resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
6062 integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= 6018 integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
6063 6019
6064lodash.mergewith@^4.6.0: 6020lodash.mergewith@^4.6.0, lodash.mergewith@^4.6.1:
6065 version "4.6.1" 6021 version "4.6.1"
6066 resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927" 6022 resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz#639057e726c3afbdb3e7d42741caa8d6e4335927"
6067 integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ== 6023 integrity sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==
@@ -6119,7 +6075,7 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
6119 dependencies: 6075 dependencies:
6120 js-tokens "^3.0.0 || ^4.0.0" 6076 js-tokens "^3.0.0 || ^4.0.0"
6121 6077
6122loud-rejection@^1.0.0, loud-rejection@^1.6.0: 6078loud-rejection@^1.0.0:
6123 version "1.6.0" 6079 version "1.6.0"
6124 resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" 6080 resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
6125 integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= 6081 integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=
@@ -6132,15 +6088,10 @@ lower-case@^1.1.1:
6132 resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" 6088 resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
6133 integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= 6089 integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
6134 6090
6135lru-cache@2.2.x: 6091lru-cache@4.1.x, lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2, lru-cache@^4.1.3:
6136 version "2.2.4" 6092 version "4.1.5"
6137 resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d" 6093 resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
6138 integrity sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0= 6094 integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
6139
6140lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.3:
6141 version "4.1.3"
6142 resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c"
6143 integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==
6144 dependencies: 6095 dependencies:
6145 pseudomap "^1.0.2" 6096 pseudomap "^1.0.2"
6146 yallist "^2.1.2" 6097 yallist "^2.1.2"
@@ -6184,6 +6135,23 @@ make-error@1.x:
6184 resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" 6135 resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8"
6185 integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== 6136 integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==
6186 6137
6138make-fetch-happen@^4.0.1:
6139 version "4.0.1"
6140 resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz#141497cb878f243ba93136c83d8aba12c216c083"
6141 integrity sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ==
6142 dependencies:
6143 agentkeepalive "^3.4.1"
6144 cacache "^11.0.1"
6145 http-cache-semantics "^3.8.1"
6146 http-proxy-agent "^2.1.0"
6147 https-proxy-agent "^2.2.1"
6148 lru-cache "^4.1.2"
6149 mississippi "^3.0.0"
6150 node-fetch-npm "^2.0.2"
6151 promise-retry "^1.1.1"
6152 socks-proxy-agent "^4.0.0"
6153 ssri "^6.0.0"
6154
6187makeerror@1.0.x: 6155makeerror@1.0.x:
6188 version "1.0.11" 6156 version "1.0.11"
6189 resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" 6157 resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
@@ -6191,11 +6159,6 @@ makeerror@1.0.x:
6191 dependencies: 6159 dependencies:
6192 tmpl "1.0.x" 6160 tmpl "1.0.x"
6193 6161
6194mamacro@^0.0.3:
6195 version "0.0.3"
6196 resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4"
6197 integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==
6198
6199map-age-cleaner@^0.1.1: 6162map-age-cleaner@^0.1.1:
6200 version "0.1.3" 6163 version "0.1.3"
6201 resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" 6164 resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
@@ -6245,6 +6208,11 @@ md5.js@^1.3.4:
6245 inherits "^2.0.1" 6208 inherits "^2.0.1"
6246 safe-buffer "^5.1.2" 6209 safe-buffer "^5.1.2"
6247 6210
6211mdn-data@~1.1.0:
6212 version "1.1.4"
6213 resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.4.tgz#50b5d4ffc4575276573c4eedb8780812a8419f01"
6214 integrity sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==
6215
6248mdurl@^1.0.1: 6216mdurl@^1.0.1:
6249 version "1.0.1" 6217 version "1.0.1"
6250 resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" 6218 resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
@@ -6400,9 +6368,9 @@ mime@^1.4.1:
6400 integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 6368 integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
6401 6369
6402mime@^2.2.0, mime@^2.3.1: 6370mime@^2.2.0, mime@^2.3.1:
6403 version "2.3.1" 6371 version "2.4.0"
6404 resolved "https://registry.yarnpkg.com/mime/-/mime-2.3.1.tgz#b1621c54d63b97c47d3cfe7f7215f7d64517c369" 6372 resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6"
6405 integrity sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg== 6373 integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==
6406 6374
6407mimic-fn@^1.0.0: 6375mimic-fn@^1.0.0:
6408 version "1.2.0" 6376 version "1.2.0"
@@ -6421,10 +6389,10 @@ min-document@^2.19.0:
6421 dependencies: 6389 dependencies:
6422 dom-walk "^0.1.0" 6390 dom-walk "^0.1.0"
6423 6391
6424mini-css-extract-plugin@0.4.3: 6392mini-css-extract-plugin@0.4.4:
6425 version "0.4.3" 6393 version "0.4.4"
6426 resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.3.tgz#98d60fcc5d228c3e36a9bd15a1d6816d6580beb8" 6394 resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.4.tgz#c10410a004951bd3cedac1da69053940fccb625d"
6427 integrity sha512-Mxs0nxzF1kxPv4TRi2NimewgXlJqh0rGE30vviCU2WHrpbta6wklnUV9dr9FUtoAHmB3p3LeXEC+ZjgHvB0Dzg== 6395 integrity sha512-o+Jm+ocb0asEngdM6FsZWtZsRzA8koFUudIDwYUfl94M3PejPHG7Vopw5hN9V8WsMkSFpm3tZP3Fesz89EyrfQ==
6428 dependencies: 6396 dependencies:
6429 loader-utils "^1.1.0" 6397 loader-utils "^1.1.0"
6430 schema-utils "^1.0.0" 6398 schema-utils "^1.0.0"
@@ -6462,7 +6430,7 @@ minimist@~0.0.1:
6462 resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" 6430 resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
6463 integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= 6431 integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=
6464 6432
6465minipass@^2.2.1, minipass@^2.3.4: 6433minipass@^2.2.1, minipass@^2.3.4, minipass@^2.3.5:
6466 version "2.3.5" 6434 version "2.3.5"
6467 resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" 6435 resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848"
6468 integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== 6436 integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==
@@ -6582,7 +6550,7 @@ ms@2.0.0:
6582 resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 6550 resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
6583 integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 6551 integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
6584 6552
6585ms@^2.1.1: 6553ms@^2.0.0, ms@^2.1.1:
6586 version "2.1.1" 6554 version "2.1.1"
6587 resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 6555 resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
6588 integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 6556 integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
@@ -6735,6 +6703,15 @@ no-case@^2.2.0:
6735 dependencies: 6703 dependencies:
6736 lower-case "^1.1.1" 6704 lower-case "^1.1.1"
6737 6705
6706node-fetch-npm@^2.0.2:
6707 version "2.0.2"
6708 resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7"
6709 integrity sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw==
6710 dependencies:
6711 encoding "^0.1.11"
6712 json-parse-better-errors "^1.0.0"
6713 safe-buffer "^5.1.1"
6714
6738node-forge@0.7.5: 6715node-forge@0.7.5:
6739 version "0.7.5" 6716 version "0.7.5"
6740 resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" 6717 resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"
@@ -6823,39 +6800,14 @@ node-pre-gyp@^0.10.0:
6823 semver "^5.3.0" 6800 semver "^5.3.0"
6824 tar "^4" 6801 tar "^4"
6825 6802
6826node-releases@^1.0.1: 6803node-releases@^1.0.5:
6827 version "1.0.3" 6804 version "1.0.5"
6828 resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.3.tgz#3414ed84595096459c251699bfcb47d88324a9e4" 6805 resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.5.tgz#a641adcc968b039a27345d92ef10b093e5cbd41d"
6829 integrity sha512-ZaZWMsbuDcetpHmYeKWPO6e63pSXLb50M7lJgCbcM2nC/nQC3daNifmtp5a2kp7EWwYfhuvH6zLPWkrF8IiDdw== 6806 integrity sha512-Ky7q0BO1BBkG/rQz6PkEZ59rwo+aSfhczHP1wwq8IowoVdN/FpiP7qp0XW0P2+BVCWe5fQUBozdbVd54q1RbCQ==
6830 dependencies: 6807 dependencies:
6831 semver "^5.3.0" 6808 semver "^5.3.0"
6832 6809
6833node-sass@4.9.3: 6810node-sass@4.10.0, node-sass@^4.9.3:
6834 version "4.9.3"
6835 resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.9.3.tgz#f407cf3d66f78308bb1e346b24fa428703196224"
6836 integrity sha512-XzXyGjO+84wxyH7fV6IwBOTrEBe2f0a6SBze9QWWYR/cL74AcQUks2AsqcCZenl/Fp/JVbuEaLpgrLtocwBUww==
6837 dependencies:
6838 async-foreach "^0.1.3"
6839 chalk "^1.1.1"
6840 cross-spawn "^3.0.0"
6841 gaze "^1.0.0"
6842 get-stdin "^4.0.1"
6843 glob "^7.0.3"
6844 in-publish "^2.0.0"
6845 lodash.assign "^4.2.0"
6846 lodash.clonedeep "^4.3.2"
6847 lodash.mergewith "^4.6.0"
6848 meow "^3.7.0"
6849 mkdirp "^0.5.1"
6850 nan "^2.10.0"
6851 node-gyp "^3.8.0"
6852 npmlog "^4.0.0"
6853 request "2.87.0"
6854 sass-graph "^2.2.4"
6855 stdout-stream "^1.4.0"
6856 "true-case-path" "^1.0.2"
6857
6858node-sass@^4.9.3:
6859 version "4.10.0" 6811 version "4.10.0"
6860 resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.10.0.tgz#dcc2b364c0913630945ccbf7a2bbf1f926effca4" 6812 resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.10.0.tgz#dcc2b364c0913630945ccbf7a2bbf1f926effca4"
6861 integrity sha512-fDQJfXszw6vek63Fe/ldkYXmRYK/QS6NbvM3i5oEo9ntPDy4XX7BcKZyTKv+/kSSxRtXXc7l+MSwEmYc0CSy6Q== 6813 integrity sha512-fDQJfXszw6vek63Fe/ldkYXmRYK/QS6NbvM3i5oEo9ntPDy4XX7BcKZyTKv+/kSSxRtXXc7l+MSwEmYc0CSy6Q==
@@ -6895,7 +6847,7 @@ nopt@^4.0.1:
6895 abbrev "1" 6847 abbrev "1"
6896 osenv "^0.1.4" 6848 osenv "^0.1.4"
6897 6849
6898normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, "normalize-package-data@~1.0.1 || ^2.0.0": 6850normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.4.0:
6899 version "2.4.0" 6851 version "2.4.0"
6900 resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" 6852 resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
6901 integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== 6853 integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==
@@ -6927,7 +6879,7 @@ npm-font-source-sans-pro@^1.0.2:
6927 resolved "https://registry.yarnpkg.com/npm-font-source-sans-pro/-/npm-font-source-sans-pro-1.0.2.tgz#c55c8ae368eebdbcaca65425a0d7e1f9a192a03e" 6879 resolved "https://registry.yarnpkg.com/npm-font-source-sans-pro/-/npm-font-source-sans-pro-1.0.2.tgz#c55c8ae368eebdbcaca65425a0d7e1f9a192a03e"
6928 integrity sha1-xVyK42juvbysplQloNfh+aGSoD4= 6880 integrity sha1-xVyK42juvbysplQloNfh+aGSoD4=
6929 6881
6930"npm-package-arg@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0": 6882npm-package-arg@^6.0.0, npm-package-arg@^6.1.0:
6931 version "6.1.0" 6883 version "6.1.0"
6932 resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1" 6884 resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1"
6933 integrity sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA== 6885 integrity sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==
@@ -6937,7 +6889,7 @@ npm-font-source-sans-pro@^1.0.2:
6937 semver "^5.5.0" 6889 semver "^5.5.0"
6938 validate-npm-package-name "^3.0.0" 6890 validate-npm-package-name "^3.0.0"
6939 6891
6940npm-packlist@^1.1.6: 6892npm-packlist@^1.1.12, npm-packlist@^1.1.6:
6941 version "1.1.12" 6893 version "1.1.12"
6942 resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" 6894 resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a"
6943 integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== 6895 integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g==
@@ -6945,24 +6897,26 @@ npm-packlist@^1.1.6:
6945 ignore-walk "^3.0.1" 6897 ignore-walk "^3.0.1"
6946 npm-bundled "^1.0.1" 6898 npm-bundled "^1.0.1"
6947 6899
6948npm-registry-client@8.6.0: 6900npm-pick-manifest@^2.1.0:
6949 version "8.6.0" 6901 version "2.2.3"
6950 resolved "https://registry.yarnpkg.com/npm-registry-client/-/npm-registry-client-8.6.0.tgz#7f1529f91450732e89f8518e0f21459deea3e4c4" 6902 resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz#32111d2a9562638bb2c8f2bf27f7f3092c8fae40"
6951 integrity sha512-Qs6P6nnopig+Y8gbzpeN/dkt+n7IyVd8f45NTMotGk6Qo7GfBmzwYx6jRLoOOgKiMnaQfYxsuyQlD8Mc3guBhg== 6903 integrity sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==
6952 dependencies: 6904 dependencies:
6953 concat-stream "^1.5.2" 6905 figgy-pudding "^3.5.1"
6954 graceful-fs "^4.1.6" 6906 npm-package-arg "^6.0.0"
6955 normalize-package-data "~1.0.1 || ^2.0.0" 6907 semver "^5.4.1"
6956 npm-package-arg "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" 6908
6957 once "^1.3.3" 6909npm-registry-fetch@^3.8.0:
6958 request "^2.74.0" 6910 version "3.8.0"
6959 retry "^0.10.0" 6911 resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.8.0.tgz#aa7d9a7c92aff94f48dba0984bdef4bd131c88cc"
6960 safe-buffer "^5.1.1" 6912 integrity sha512-hrw8UMD+Nob3Kl3h8Z/YjmKamb1gf7D1ZZch2otrIXM3uFLB5vjEY6DhMlq80z/zZet6eETLbOXcuQudCB3Zpw==
6961 semver "2 >=2.2.1 || 3.x || 4 || 5" 6913 dependencies:
6962 slide "^1.1.3" 6914 JSONStream "^1.3.4"
6963 ssri "^5.2.4" 6915 bluebird "^3.5.1"
6964 optionalDependencies: 6916 figgy-pudding "^3.4.1"
6965 npmlog "2 || ^3.1.0 || ^4.0.0" 6917 lru-cache "^4.1.3"
6918 make-fetch-happen "^4.0.1"
6919 npm-package-arg "^6.1.0"
6966 6920
6967npm-run-path@^2.0.0: 6921npm-run-path@^2.0.0:
6968 version "2.0.2" 6922 version "2.0.2"
@@ -6971,7 +6925,7 @@ npm-run-path@^2.0.0:
6971 dependencies: 6925 dependencies:
6972 path-key "^2.0.0" 6926 path-key "^2.0.0"
6973 6927
6974"npmlog@0 || 1 || 2 || 3 || 4", "npmlog@2 || ^3.1.0 || ^4.0.0", npmlog@^4.0.0, npmlog@^4.0.2: 6928"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2:
6975 version "4.1.2" 6929 version "4.1.2"
6976 resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" 6930 resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
6977 integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== 6931 integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
@@ -7008,11 +6962,6 @@ nwsapi@^2.0.7:
7008 resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" 6962 resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016"
7009 integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ== 6963 integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ==
7010 6964
7011oauth-sign@~0.8.2:
7012 version "0.8.2"
7013 resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
7014 integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=
7015
7016oauth-sign@~0.9.0: 6965oauth-sign@~0.9.0:
7017 version "0.9.0" 6966 version "0.9.0"
7018 resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" 6967 resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
@@ -7152,7 +7101,7 @@ optionator@^0.8.1:
7152 type-check "~0.3.2" 7101 type-check "~0.3.2"
7153 wordwrap "~1.0.0" 7102 wordwrap "~1.0.0"
7154 7103
7155original@>=0.0.5: 7104original@^1.0.0:
7156 version "1.0.2" 7105 version "1.0.2"
7157 resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" 7106 resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f"
7158 integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== 7107 integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==
@@ -7272,10 +7221,43 @@ package-json-versionify@^1.0.2:
7272 dependencies: 7221 dependencies:
7273 browserify-package-json "^1.0.0" 7222 browserify-package-json "^1.0.0"
7274 7223
7224pacote@9.1.1:
7225 version "9.1.1"
7226 resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.1.1.tgz#25091f75a25021de8be8d34cc6408728fca3579b"
7227 integrity sha512-f28Rq5ozzKAA9YwIKw61/ipwAatUZseYmVssDbHHaexF0wRIVotapVEZPAjOT7Eu3LYVqEp0NVpNizoAnYBUaA==
7228 dependencies:
7229 bluebird "^3.5.2"
7230 cacache "^11.2.0"
7231 figgy-pudding "^3.5.1"
7232 get-stream "^4.1.0"
7233 glob "^7.1.3"
7234 lru-cache "^4.1.3"
7235 make-fetch-happen "^4.0.1"
7236 minimatch "^3.0.4"
7237 minipass "^2.3.5"
7238 mississippi "^3.0.0"
7239 mkdirp "^0.5.1"
7240 normalize-package-data "^2.4.0"
7241 npm-package-arg "^6.1.0"
7242 npm-packlist "^1.1.12"
7243 npm-pick-manifest "^2.1.0"
7244 npm-registry-fetch "^3.8.0"
7245 osenv "^0.1.5"
7246 promise-inflight "^1.0.1"
7247 promise-retry "^1.1.1"
7248 protoduck "^5.0.1"
7249 rimraf "^2.6.2"
7250 safe-buffer "^5.1.2"
7251 semver "^5.6.0"
7252 ssri "^6.0.1"
7253 tar "^4.4.6"
7254 unique-filename "^1.1.1"
7255 which "^1.3.1"
7256
7275pako@~1.0.2, pako@~1.0.5: 7257pako@~1.0.2, pako@~1.0.5:
7276 version "1.0.6" 7258 version "1.0.7"
7277 resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" 7259 resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.7.tgz#2473439021b57f1516c82f58be7275ad8ef1bb27"
7278 integrity sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg== 7260 integrity sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ==
7279 7261
7280parallel-transform@^1.1.0: 7262parallel-transform@^1.1.0:
7281 version "1.1.0" 7263 version "1.1.0"
@@ -7543,9 +7525,9 @@ portfinder@1.0.17:
7543 mkdirp "0.5.x" 7525 mkdirp "0.5.x"
7544 7526
7545portfinder@^1.0.9: 7527portfinder@^1.0.9:
7546 version "1.0.19" 7528 version "1.0.20"
7547 resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.19.tgz#07e87914a55242dcda5b833d42f018d6875b595f" 7529 resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a"
7548 integrity sha512-23aeQKW9KgHe6citUrG3r9HjeX6vls0h713TAa+CwTKZwNIr/pD2ApaxYF4Um3ZZyq4ar+Siv3+fhoHaIwSOSw== 7530 integrity sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==
7549 dependencies: 7531 dependencies:
7550 async "^1.5.2" 7532 async "^1.5.2"
7551 debug "^2.2.0" 7533 debug "^2.2.0"
@@ -7615,12 +7597,12 @@ postcss-modules-values@^1.3.0:
7615 icss-replace-symbols "^1.1.0" 7597 icss-replace-symbols "^1.1.0"
7616 postcss "^6.0.1" 7598 postcss "^6.0.1"
7617 7599
7618postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: 7600postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0, postcss-value-parser@^3.3.1:
7619 version "3.3.1" 7601 version "3.3.1"
7620 resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" 7602 resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
7621 integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== 7603 integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
7622 7604
7623postcss@7.0.5, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.2: 7605postcss@7.0.5:
7624 version "7.0.5" 7606 version "7.0.5"
7625 resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.5.tgz#70e6443e36a6d520b0fd4e7593fcca3635ee9f55" 7607 resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.5.tgz#70e6443e36a6d520b0fd4e7593fcca3635ee9f55"
7626 integrity sha512-HBNpviAUFCKvEh7NZhw1e8MBPivRszIiUnhrJ+sBFVSYSqubrzwX3KG51mYgcRHX8j/cAgZJedONZcm5jTBdgQ== 7608 integrity sha512-HBNpviAUFCKvEh7NZhw1e8MBPivRszIiUnhrJ+sBFVSYSqubrzwX3KG51mYgcRHX8j/cAgZJedONZcm5jTBdgQ==
@@ -7629,7 +7611,7 @@ postcss@7.0.5, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.2:
7629 source-map "^0.6.1" 7611 source-map "^0.6.1"
7630 supports-color "^5.5.0" 7612 supports-color "^5.5.0"
7631 7613
7632postcss@^6.0.1, postcss@^6.0.14, postcss@^6.0.23: 7614postcss@^6.0.1, postcss@^6.0.23:
7633 version "6.0.23" 7615 version "6.0.23"
7634 resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" 7616 resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324"
7635 integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== 7617 integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==
@@ -7638,6 +7620,15 @@ postcss@^6.0.1, postcss@^6.0.14, postcss@^6.0.23:
7638 source-map "^0.6.1" 7620 source-map "^0.6.1"
7639 supports-color "^5.4.0" 7621 supports-color "^5.4.0"
7640 7622
7623postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.5:
7624 version "7.0.6"
7625 resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.6.tgz#6dcaa1e999cdd4a255dcd7d4d9547f4ca010cdc2"
7626 integrity sha512-Nq/rNjnHFcKgCDDZYO0lNsl6YWe6U7tTy+ESN+PnLxebL8uBtYX59HZqvrj7YLK5UCyll2hqDsJOo3ndzEW8Ug==
7627 dependencies:
7628 chalk "^2.4.1"
7629 source-map "^0.6.1"
7630 supports-color "^5.5.0"
7631
7641prelude-ls@~1.1.2: 7632prelude-ls@~1.1.2:
7642 version "1.1.2" 7633 version "1.1.2"
7643 resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" 7634 resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@@ -7664,10 +7655,10 @@ pretty-format@^23.6.0:
7664 ansi-regex "^3.0.0" 7655 ansi-regex "^3.0.0"
7665 ansi-styles "^3.2.0" 7656 ansi-styles "^3.2.0"
7666 7657
7667primeng@^6.1.2: 7658primeng@^7.0.0:
7668 version "6.1.6" 7659 version "7.0.0"
7669 resolved "https://registry.yarnpkg.com/primeng/-/primeng-6.1.6.tgz#3a699a02507fcd5befb2fb9fe18fcc5d385f810e" 7660 resolved "https://registry.yarnpkg.com/primeng/-/primeng-7.0.0.tgz#3a189568069a31544c9ed952328e221daad9b9b1"
7670 integrity sha512-9QYkXfBuSwx5zZej5QiEWhdAFJPc+f9h6PXuFtw4PzUfOhPmnoUxR5K04xeFreCNP13WwP3Uh/U3o7mY0PZtQA== 7661 integrity sha512-PrEEnp0VPbzsUQdpB/4KtUdRxaWwpprHy+IpUi09C42OAI2zqdTVIC0AaW81gDAGQyW7XraCP9EFI8KT4nC9GA==
7671 7662
7672private@^0.1.8, private@~0.1.5: 7663private@^0.1.8, private@~0.1.5:
7673 version "0.1.8" 7664 version "0.1.8"
@@ -7699,6 +7690,14 @@ promise-inflight@^1.0.1:
7699 resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" 7690 resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
7700 integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= 7691 integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
7701 7692
7693promise-retry@^1.1.1:
7694 version "1.1.1"
7695 resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d"
7696 integrity sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=
7697 dependencies:
7698 err-code "^1.0.0"
7699 retry "^0.10.0"
7700
7702promise@^7.1.1: 7701promise@^7.1.1:
7703 version "7.3.1" 7702 version "7.3.1"
7704 resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" 7703 resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
@@ -7722,6 +7721,13 @@ prop-types@^15.6.2:
7722 loose-envify "^1.3.1" 7721 loose-envify "^1.3.1"
7723 object-assign "^4.1.1" 7722 object-assign "^4.1.1"
7724 7723
7724protoduck@^5.0.1:
7725 version "5.0.1"
7726 resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f"
7727 integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==
7728 dependencies:
7729 genfun "^5.0.0"
7730
7725protractor@^5.3.2: 7731protractor@^5.3.2:
7726 version "5.4.1" 7732 version "5.4.1"
7727 resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.4.1.tgz#011a99e38df7aa45d22455b889ffbb13a6ce0bd9" 7733 resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.4.1.tgz#011a99e38df7aa45d22455b889ffbb13a6ce0bd9"
@@ -7762,7 +7768,7 @@ pseudomap@^1.0.2:
7762 resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 7768 resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
7763 integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= 7769 integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
7764 7770
7765psl@^1.1.24: 7771psl@^1.1.24, psl@^1.1.28:
7766 version "1.1.29" 7772 version "1.1.29"
7767 resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" 7773 resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67"
7768 integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== 7774 integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==
@@ -7814,7 +7820,7 @@ punycode@^1.2.4, punycode@^1.4.1:
7814 resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" 7820 resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
7815 integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= 7821 integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
7816 7822
7817punycode@^2.1.0: 7823punycode@^2.1.0, punycode@^2.1.1:
7818 version "2.1.1" 7824 version "2.1.1"
7819 resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 7825 resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
7820 integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 7826 integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
@@ -7863,7 +7869,7 @@ qrcode@^0.8.2:
7863 isarray "^2.0.1" 7869 isarray "^2.0.1"
7864 pngjs "^2.3.1" 7870 pngjs "^2.3.1"
7865 7871
7866qs@6.5.2, qs@~6.5.1, qs@~6.5.2: 7872qs@6.5.2, qs@~6.5.2:
7867 version "6.5.2" 7873 version "6.5.2"
7868 resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" 7874 resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
7869 integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== 7875 integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
@@ -8241,33 +8247,7 @@ request-promise-native@^1.0.5:
8241 stealthy-require "^1.1.0" 8247 stealthy-require "^1.1.0"
8242 tough-cookie ">=2.3.3" 8248 tough-cookie ">=2.3.3"
8243 8249
8244request@2.87.0: 8250request@^2.83.0, request@^2.87.0, request@^2.88.0:
8245 version "2.87.0"
8246 resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e"
8247 integrity sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==
8248 dependencies:
8249 aws-sign2 "~0.7.0"
8250 aws4 "^1.6.0"
8251 caseless "~0.12.0"
8252 combined-stream "~1.0.5"
8253 extend "~3.0.1"
8254 forever-agent "~0.6.1"
8255 form-data "~2.3.1"
8256 har-validator "~5.0.3"
8257 http-signature "~1.2.0"
8258 is-typedarray "~1.0.0"
8259 isstream "~0.1.2"
8260 json-stringify-safe "~5.0.1"
8261 mime-types "~2.1.17"
8262 oauth-sign "~0.8.2"
8263 performance-now "^2.1.0"
8264 qs "~6.5.1"
8265 safe-buffer "^5.1.1"
8266 tough-cookie "~2.3.3"
8267 tunnel-agent "^0.6.0"
8268 uuid "^3.1.0"
8269
8270request@^2.74.0, request@^2.83.0, request@^2.87.0, request@^2.88.0:
8271 version "2.88.0" 8251 version "2.88.0"
8272 resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" 8252 resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
8273 integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== 8253 integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
@@ -8335,7 +8315,7 @@ resolve@1.1.7, resolve@1.1.x:
8335 resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" 8315 resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
8336 integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= 8316 integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
8337 8317
8338resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.2: 8318resolve@1.x, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.2:
8339 version "1.8.1" 8319 version "1.8.1"
8340 resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" 8320 resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
8341 integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== 8321 integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==
@@ -8482,20 +8462,20 @@ sane@^2.0.0:
8482 fsevents "^1.2.3" 8462 fsevents "^1.2.3"
8483 8463
8484sanitize-html@^1.18.4: 8464sanitize-html@^1.18.4:
8485 version "1.19.1" 8465 version "1.19.2"
8486 resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.1.tgz#e8b33c69578054d6ee4f57ea152d6497f3f6fb7d" 8466 resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.19.2.tgz#c03fffe2bf96cd582968ece9792cbca32e64dde0"
8487 integrity sha512-zNYr6FvBn4bZukr9x2uny6od/9YdjCLwF+FqxivqI0YOt/m9GIxfX+tWhm52tBAPUXiTTb4bJTGVagRz5b06bw== 8467 integrity sha512-7fNb3/N0sZ/nkshMRBoxLz6K1dlMSVF/eQHX1Bof9sRT7cZJvmrDGfXEn544MXJnpY29vux1A599g9UrcHTBXA==
8488 dependencies: 8468 dependencies:
8489 chalk "^2.3.0" 8469 chalk "^2.4.1"
8490 htmlparser2 "^3.9.0" 8470 css-tree "^1.0.0-alpha.29"
8471 htmlparser2 "^3.10.0"
8491 lodash.clonedeep "^4.5.0" 8472 lodash.clonedeep "^4.5.0"
8492 lodash.escaperegexp "^4.1.2" 8473 lodash.escaperegexp "^4.1.2"
8493 lodash.isplainobject "^4.0.6" 8474 lodash.isplainobject "^4.0.6"
8494 lodash.isstring "^4.0.1" 8475 lodash.isstring "^4.0.1"
8495 lodash.mergewith "^4.6.0" 8476 lodash.mergewith "^4.6.1"
8496 postcss "^6.0.14"
8497 srcset "^1.0.0" 8477 srcset "^1.0.0"
8498 xtend "^4.0.0" 8478 xtend "^4.0.1"
8499 8479
8500sass-graph@^2.2.4: 8480sass-graph@^2.2.4:
8501 version "2.2.4" 8481 version "2.2.4"
@@ -8547,9 +8527,9 @@ sax@>=0.6.0, sax@^1.2.4:
8547 integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== 8527 integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
8548 8528
8549scheduler@^0.11.2: 8529scheduler@^0.11.2:
8550 version "0.11.2" 8530 version "0.11.3"
8551 resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.2.tgz#a8db5399d06eba5abac51b705b7151d2319d33d3" 8531 resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.3.tgz#b5769b90cf8b1464f3f3cfcafe8e3cd7555a2d6b"
8552 integrity sha512-+WCP3s3wOaW4S7C1tl3TEXp4l9lJn0ZK8G3W3WKRWmw77Z2cIFUW2MiNTMHn5sCjxN+t7N43HAOOgMjyAg5hlg== 8532 integrity sha512-i9X9VRRVZDd3xZw10NY5Z2cVMbdYg6gqFecfj79USv1CFN+YrJ3gIPRKf1qlY+Sxly4djoKdfx1T+m9dnRB8kQ==
8553 dependencies: 8533 dependencies:
8554 loose-envify "^1.1.0" 8534 loose-envify "^1.1.0"
8555 object-assign "^4.1.1" 8535 object-assign "^4.1.1"
@@ -8622,7 +8602,7 @@ semver-intersect@1.4.0:
8622 dependencies: 8602 dependencies:
8623 semver "^5.0.0" 8603 semver "^5.0.0"
8624 8604
8625"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", semver@^5.0.0, semver@^5.3.0, semver@^5.5, semver@^5.5.0: 8605"semver@2 || 3 || 4 || 5", semver@^5.0.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.6.0:
8626 version "5.6.0" 8606 version "5.6.0"
8627 resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" 8607 resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
8628 integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== 8608 integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
@@ -8820,10 +8800,10 @@ slash@^1.0.0:
8820 resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" 8800 resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
8821 integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= 8801 integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=
8822 8802
8823slide@^1.1.3: 8803smart-buffer@^4.0.1:
8824 version "1.1.6" 8804 version "4.0.1"
8825 resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" 8805 resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.1.tgz#07ea1ca8d4db24eb4cac86537d7d18995221ace3"
8826 integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= 8806 integrity sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==
8827 8807
8828snapdragon-node@^2.0.1: 8808snapdragon-node@^2.0.1:
8829 version "2.1.1" 8809 version "2.1.1"
@@ -8880,6 +8860,26 @@ socket.io-client@2.1.1:
8880 socket.io-parser "~3.2.0" 8860 socket.io-parser "~3.2.0"
8881 to-array "0.1.4" 8861 to-array "0.1.4"
8882 8862
8863socket.io-client@^2.2.0:
8864 version "2.2.0"
8865 resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.2.0.tgz#84e73ee3c43d5020ccc1a258faeeb9aec2723af7"
8866 integrity sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==
8867 dependencies:
8868 backo2 "1.0.2"
8869 base64-arraybuffer "0.1.5"
8870 component-bind "1.0.0"
8871 component-emitter "1.2.1"
8872 debug "~3.1.0"
8873 engine.io-client "~3.3.1"
8874 has-binary2 "~1.0.2"
8875 has-cors "1.1.0"
8876 indexof "0.0.1"
8877 object-component "0.0.3"
8878 parseqs "0.0.5"
8879 parseuri "0.0.5"
8880 socket.io-parser "~3.3.0"
8881 to-array "0.1.4"
8882
8883socket.io-parser@~3.2.0: 8883socket.io-parser@~3.2.0:
8884 version "3.2.0" 8884 version "3.2.0"
8885 resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077" 8885 resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.2.0.tgz#e7c6228b6aa1f814e6148aea325b51aa9499e077"
@@ -8889,6 +8889,15 @@ socket.io-parser@~3.2.0:
8889 debug "~3.1.0" 8889 debug "~3.1.0"
8890 isarray "2.0.1" 8890 isarray "2.0.1"
8891 8891
8892socket.io-parser@~3.3.0:
8893 version "3.3.0"
8894 resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f"
8895 integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==
8896 dependencies:
8897 component-emitter "1.2.1"
8898 debug "~3.1.0"
8899 isarray "2.0.1"
8900
8892socket.io@2.1.1: 8901socket.io@2.1.1:
8893 version "2.1.1" 8902 version "2.1.1"
8894 resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980" 8903 resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.1.1.tgz#a069c5feabee3e6b214a75b40ce0652e1cfb9980"
@@ -8901,17 +8910,17 @@ socket.io@2.1.1:
8901 socket.io-client "2.1.1" 8910 socket.io-client "2.1.1"
8902 socket.io-parser "~3.2.0" 8911 socket.io-parser "~3.2.0"
8903 8912
8904sockjs-client@1.1.5: 8913sockjs-client@1.3.0:
8905 version "1.1.5" 8914 version "1.3.0"
8906 resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.5.tgz#1bb7c0f7222c40f42adf14f4442cbd1269771a83" 8915 resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.3.0.tgz#12fc9d6cb663da5739d3dc5fb6e8687da95cb177"
8907 integrity sha1-G7fA9yIsQPQq3xT0RCy9Eml3GoM= 8916 integrity sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==
8908 dependencies: 8917 dependencies:
8909 debug "^2.6.6" 8918 debug "^3.2.5"
8910 eventsource "0.1.6" 8919 eventsource "^1.0.7"
8911 faye-websocket "~0.11.0" 8920 faye-websocket "~0.11.1"
8912 inherits "^2.0.1" 8921 inherits "^2.0.3"
8913 json3 "^3.3.2" 8922 json3 "^3.3.2"
8914 url-parse "^1.1.8" 8923 url-parse "^1.4.3"
8915 8924
8916sockjs@0.3.19: 8925sockjs@0.3.19:
8917 version "0.3.19" 8926 version "0.3.19"
@@ -8921,6 +8930,22 @@ sockjs@0.3.19:
8921 faye-websocket "^0.10.0" 8930 faye-websocket "^0.10.0"
8922 uuid "^3.0.1" 8931 uuid "^3.0.1"
8923 8932
8933socks-proxy-agent@^4.0.0:
8934 version "4.0.1"
8935 resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz#5936bf8b707a993079c6f37db2091821bffa6473"
8936 integrity sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==
8937 dependencies:
8938 agent-base "~4.2.0"
8939 socks "~2.2.0"
8940
8941socks@~2.2.0:
8942 version "2.2.2"
8943 resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.2.tgz#f061219fc2d4d332afb4af93e865c84d3fa26e2b"
8944 integrity sha512-g6wjBnnMOZpE0ym6e0uHSddz9p3a+WsBaaYQaBaSCJYvrC4IXykQR9MNGjLQf38e9iIIhp3b1/Zk8YZI3KGJ0Q==
8945 dependencies:
8946 ip "^1.1.5"
8947 smart-buffer "^4.0.1"
8948
8924source-list-map@^2.0.0: 8949source-list-map@^2.0.0:
8925 version "2.0.1" 8950 version "2.0.1"
8926 resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" 8951 resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
@@ -9012,9 +9037,9 @@ source-map@~0.2.0:
9012 amdefine ">=0.0.4" 9037 amdefine ">=0.0.4"
9013 9038
9014sourcemap-codec@^1.4.1: 9039sourcemap-codec@^1.4.1:
9015 version "1.4.3" 9040 version "1.4.4"
9016 resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.3.tgz#0ba615b73ec35112f63c2f2d9e7c3f87282b0e33" 9041 resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz#c63ea927c029dd6bd9a2b7fa03b3fec02ad56e9f"
9017 integrity sha512-vFrY/x/NdsD7Yc8mpTJXuao9S8lq08Z/kOITHz6b7YbfI9xL8Spe5EvSQUHOI7SbpY8bRPr0U3kKSsPuqEGSfA== 9042 integrity sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==
9018 9043
9019spdx-correct@^3.0.0: 9044spdx-correct@^3.0.0:
9020 version "3.0.2" 9045 version "3.0.2"
@@ -9067,7 +9092,7 @@ spdy@^3.4.1:
9067 select-hose "^2.0.0" 9092 select-hose "^2.0.0"
9068 spdy-transport "^2.0.18" 9093 spdy-transport "^2.0.18"
9069 9094
9070speed-measure-webpack-plugin@^1.2.3: 9095speed-measure-webpack-plugin@1.2.3:
9071 version "1.2.3" 9096 version "1.2.3"
9072 resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.2.3.tgz#de170b5cefbfa1c039d95e639edd3ad50cfc7c48" 9097 resolved "https://registry.yarnpkg.com/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.2.3.tgz#de170b5cefbfa1c039d95e639edd3ad50cfc7c48"
9073 integrity sha512-p+taQ69VkRUXYMoZOx2nxV/Tz8tt79ahctoZJyJDHWP7fEYvwFNf5Pd73k5kZ6auu0pTsPNLEUwWpM8mCk85Zw== 9098 integrity sha512-p+taQ69VkRUXYMoZOx2nxV/Tz8tt79ahctoZJyJDHWP7fEYvwFNf5Pd73k5kZ6auu0pTsPNLEUwWpM8mCk85Zw==
@@ -9133,7 +9158,7 @@ ssri@^5.2.4:
9133 dependencies: 9158 dependencies:
9134 safe-buffer "^5.1.1" 9159 safe-buffer "^5.1.1"
9135 9160
9136ssri@^6.0.0: 9161ssri@^6.0.0, ssri@^6.0.1:
9137 version "6.0.1" 9162 version "6.0.1"
9138 resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" 9163 resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8"
9139 integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== 9164 integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==
@@ -9293,10 +9318,10 @@ string2compact@^1.1.1, string2compact@^1.2.5:
9293 addr-to-ip-port "^1.0.1" 9318 addr-to-ip-port "^1.0.1"
9294 ipaddr.js "^1.0.1" 9319 ipaddr.js "^1.0.1"
9295 9320
9296string_decoder@^1.0.0, string_decoder@^1.1.1, string_decoder@~1.1.1: 9321string_decoder@^1.0.0, string_decoder@^1.1.1:
9297 version "1.1.1" 9322 version "1.2.0"
9298 resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 9323 resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
9299 integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 9324 integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==
9300 dependencies: 9325 dependencies:
9301 safe-buffer "~5.1.0" 9326 safe-buffer "~5.1.0"
9302 9327
@@ -9305,6 +9330,13 @@ string_decoder@~0.10.x:
9305 resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 9330 resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
9306 integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= 9331 integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
9307 9332
9333string_decoder@~1.1.1:
9334 version "1.1.1"
9335 resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
9336 integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
9337 dependencies:
9338 safe-buffer "~5.1.0"
9339
9308strip-ansi@^3.0.0, strip-ansi@^3.0.1: 9340strip-ansi@^3.0.0, strip-ansi@^3.0.1:
9309 version "3.0.1" 9341 version "3.0.1"
9310 resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 9342 resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
@@ -9348,13 +9380,13 @@ strip-json-comments@~2.0.1:
9348 resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 9380 resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
9349 integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 9381 integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
9350 9382
9351style-loader@0.23.0: 9383style-loader@0.23.1:
9352 version "0.23.0" 9384 version "0.23.1"
9353 resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.0.tgz#8377fefab68416a2e05f1cabd8c3a3acfcce74f1" 9385 resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.23.1.tgz#cb9154606f3e771ab6c4ab637026a1049174d925"
9354 integrity sha512-uCcN7XWHkqwGVt7skpInW6IGO1tG6ReyFQ1Cseh0VcN6VdcFQi62aG/2F3Y9ueA8x4IVlfaSUxpmQXQD9QrEuQ== 9386 integrity sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==
9355 dependencies: 9387 dependencies:
9356 loader-utils "^1.1.0" 9388 loader-utils "^1.1.0"
9357 schema-utils "^0.4.5" 9389 schema-utils "^1.0.0"
9358 9390
9359stylus-loader@3.0.2: 9391stylus-loader@3.0.2:
9360 version "3.0.2" 9392 version "3.0.2"
@@ -9407,9 +9439,9 @@ symbol-tree@^3.2.2:
9407 integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= 9439 integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=
9408 9440
9409tapable@^1.0.0, tapable@^1.1.0: 9441tapable@^1.0.0, tapable@^1.1.0:
9410 version "1.1.0" 9442 version "1.1.1"
9411 resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.0.tgz#0d076a172e3d9ba088fd2272b2668fb8d194b78c" 9443 resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.1.tgz#4d297923c5a72a42360de2ab52dadfaaec00018e"
9412 integrity sha512-IlqtmLVaZA2qab8epUXbVWRn3aB1imbDMJtjB3nu4X0NqPkcY/JH9ZtCBWKHWPxs8Svi9tyo8w2dBoi07qZbBA== 9444 integrity sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==
9413 9445
9414tar@^2.0.0: 9446tar@^2.0.0:
9415 version "2.2.1" 9447 version "2.2.1"
@@ -9420,7 +9452,7 @@ tar@^2.0.0:
9420 fstream "^1.0.2" 9452 fstream "^1.0.2"
9421 inherits "2" 9453 inherits "2"
9422 9454
9423tar@^4: 9455tar@^4, tar@^4.4.6:
9424 version "4.4.8" 9456 version "4.4.8"
9425 resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" 9457 resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d"
9426 integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== 9458 integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==
@@ -9448,9 +9480,9 @@ terser-webpack-plugin@1.1.0, terser-webpack-plugin@^1.1.0:
9448 worker-farm "^1.5.2" 9480 worker-farm "^1.5.2"
9449 9481
9450terser@^3.8.1: 9482terser@^3.8.1:
9451 version "3.10.11" 9483 version "3.11.0"
9452 resolved "https://registry.yarnpkg.com/terser/-/terser-3.10.11.tgz#e063da74b194dde9faf0a561f3a438c549d2da3f" 9484 resolved "https://registry.yarnpkg.com/terser/-/terser-3.11.0.tgz#60782893e1f4d6788acc696351f40636d0e37af0"
9453 integrity sha512-iruZ7j14oBbRYJC5cP0/vTU7YOWjN+J1ZskEGoF78tFzXdkK2hbCL/3TRZN8XB+MuvFhvOHMp7WkOCBO4VEL5g== 9485 integrity sha512-5iLMdhEPIq3zFWskpmbzmKwMQixKmTYwY3Ox9pjtSklBLnHiuQ0GKJLhL1HSYtyffHM3/lDIFBnb82m9D7ewwQ==
9454 dependencies: 9486 dependencies:
9455 commander "~2.17.1" 9487 commander "~2.17.1"
9456 source-map "~0.6.1" 9488 source-map "~0.6.1"
@@ -9485,7 +9517,7 @@ through2@^2.0.0:
9485 readable-stream "~2.3.6" 9517 readable-stream "~2.3.6"
9486 xtend "~4.0.1" 9518 xtend "~4.0.1"
9487 9519
9488through@2, through@X.X.X, through@^2.3.6, through@~2.3.6: 9520through@2, "through@>=2.2.7 <3", through@X.X.X, through@^2.3.6, through@~2.3.6:
9489 version "2.3.8" 9521 version "2.3.8"
9490 resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 9522 resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
9491 integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 9523 integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
@@ -9586,7 +9618,15 @@ torrent-piece@^2.0.0:
9586 resolved "https://registry.yarnpkg.com/torrent-piece/-/torrent-piece-2.0.0.tgz#6598ae67d93699e887f178db267ba16d89d7ec9b" 9618 resolved "https://registry.yarnpkg.com/torrent-piece/-/torrent-piece-2.0.0.tgz#6598ae67d93699e887f178db267ba16d89d7ec9b"
9587 integrity sha512-H/Z/yCuvZJj1vl1IQHI8dvF2QrUuXRJoptT5DW5967/dsLpXlCg+uyhFR5lfNj5mNaYePUbKtnL+qKWZGXv4Nw== 9619 integrity sha512-H/Z/yCuvZJj1vl1IQHI8dvF2QrUuXRJoptT5DW5967/dsLpXlCg+uyhFR5lfNj5mNaYePUbKtnL+qKWZGXv4Nw==
9588 9620
9589tough-cookie@>=2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.4.3: 9621tough-cookie@>=2.3.3, tough-cookie@^2.3.4:
9622 version "2.5.0"
9623 resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
9624 integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
9625 dependencies:
9626 psl "^1.1.28"
9627 punycode "^2.1.1"
9628
9629tough-cookie@~2.4.3:
9590 version "2.4.3" 9630 version "2.4.3"
9591 resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" 9631 resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
9592 integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== 9632 integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
@@ -9594,13 +9634,6 @@ tough-cookie@>=2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.4.3:
9594 psl "^1.1.24" 9634 psl "^1.1.24"
9595 punycode "^1.4.1" 9635 punycode "^1.4.1"
9596 9636
9597tough-cookie@~2.3.3:
9598 version "2.3.4"
9599 resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
9600 integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==
9601 dependencies:
9602 punycode "^1.4.1"
9603
9604tr46@^1.0.1: 9637tr46@^1.0.1:
9605 version "1.0.1" 9638 version "1.0.1"
9606 resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" 9639 resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"
@@ -9641,9 +9674,9 @@ tryer@^1.0.0:
9641 integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== 9674 integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
9642 9675
9643ts-jest@^23.1.4: 9676ts-jest@^23.1.4:
9644 version "23.10.4" 9677 version "23.10.5"
9645 resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-23.10.4.tgz#a7a953f55c9165bcaa90ff91014a178e87fe0df8" 9678 resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-23.10.5.tgz#cdb550df4466a30489bf70ba867615799f388dd5"
9646 integrity sha512-oV/wBwGUS7olSk/9yWMiSIJWbz5xO4zhftnY3gwv6s4SMg6WHF1m8XZNBvQOKQRiTAexZ9754Z13dxBq3Zgssw== 9679 integrity sha512-MRCs9qnGoyKgFc8adDEntAOP64fWK1vZKnOYU1o2HxaqjdJvGqmkLCPCnVq1/If4zkUmEjKPnCiUisTrlX2p2A==
9647 dependencies: 9680 dependencies:
9648 bs-logger "0.x" 9681 bs-logger "0.x"
9649 buffer-from "1.x" 9682 buffer-from "1.x"
@@ -9651,6 +9684,7 @@ ts-jest@^23.1.4:
9651 json5 "2.x" 9684 json5 "2.x"
9652 make-error "1.x" 9685 make-error "1.x"
9653 mkdirp "0.x" 9686 mkdirp "0.x"
9687 resolve "1.x"
9654 semver "^5.5" 9688 semver "^5.5"
9655 yargs-parser "10.x" 9689 yargs-parser "10.x"
9656 9690
@@ -9721,9 +9755,9 @@ tsutils@^2.27.2:
9721 tslib "^1.8.1" 9755 tslib "^1.8.1"
9722 9756
9723tsutils@^3.0.0: 9757tsutils@^3.0.0:
9724 version "3.5.0" 9758 version "3.5.2"
9725 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.5.0.tgz#42602f7df241e753a2105cc3627a664abf11f745" 9759 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.5.2.tgz#6fd3c2d5a731e83bb21b070a173ec0faf3a8f6d3"
9726 integrity sha512-/FZ+pEJQixWruFejFxNPRSwg+iF6aw7PYZVRqUscJ7EnzV3zieI8byfZziUR7QjCuJFulq8SEe9JcGflO4ze4Q== 9760 integrity sha512-qIlklNuI/1Dzfm+G+kJV5gg3gimZIX5haYtIVQe7qGyKd7eu8T1t1DY6pz4Sc2CGXAj9s1izycctm9Zfl9sRuQ==
9727 dependencies: 9761 dependencies:
9728 tslib "^1.8.1" 9762 tslib "^1.8.1"
9729 9763
@@ -9838,7 +9872,7 @@ uniq@^1.0.1:
9838 resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" 9872 resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
9839 integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= 9873 integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=
9840 9874
9841unique-filename@^1.1.0: 9875unique-filename@^1.1.0, unique-filename@^1.1.1:
9842 version "1.1.1" 9876 version "1.1.1"
9843 resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" 9877 resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230"
9844 integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== 9878 integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==
@@ -9897,12 +9931,7 @@ urix@^0.1.0:
9897 resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" 9931 resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
9898 integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= 9932 integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
9899 9933
9900url-join@^4.0.0: 9934url-parse@^1.4.3:
9901 version "4.0.0"
9902 resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a"
9903 integrity sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=
9904
9905url-parse@^1.1.8, url-parse@^1.4.3:
9906 version "1.4.4" 9935 version "1.4.4"
9907 resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8" 9936 resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8"
9908 integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg== 9937 integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==
@@ -9928,12 +9957,12 @@ use@^3.1.0:
9928 resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" 9957 resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
9929 integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== 9958 integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
9930 9959
9931useragent@2.2.1: 9960useragent@2.3.0:
9932 version "2.2.1" 9961 version "2.3.0"
9933 resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.1.tgz#cf593ef4f2d175875e8bb658ea92e18a4fd06d8e" 9962 resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972"
9934 integrity sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4= 9963 integrity sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==
9935 dependencies: 9964 dependencies:
9936 lru-cache "2.2.x" 9965 lru-cache "4.1.x"
9937 tmp "0.0.x" 9966 tmp "0.0.x"
9938 9967
9939ut_metadata@^3.3.0: 9968ut_metadata@^3.3.0:
@@ -10222,35 +10251,20 @@ webpack-core@^0.6.8:
10222 source-list-map "~0.1.7" 10251 source-list-map "~0.1.7"
10223 source-map "~0.4.1" 10252 source-map "~0.4.1"
10224 10253
10225webpack-dev-middleware@3.2.0: 10254webpack-dev-middleware@3.4.0:
10226 version "3.2.0" 10255 version "3.4.0"
10227 resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.2.0.tgz#a20ceef194873710052da678f3c6ee0aeed92552" 10256 resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz#1132fecc9026fd90f0ecedac5cbff75d1fb45890"
10228 integrity sha512-YJLMF/96TpKXaEQwaLEo+Z4NDK8aV133ROF6xp9pe3gQoS7sxfpXh4Rv9eC+8vCvWfmDjRQaMSlRPbO+9G6jgA== 10257 integrity sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==
10229 dependencies:
10230 loud-rejection "^1.6.0"
10231 memory-fs "~0.4.1"
10232 mime "^2.3.1"
10233 path-is-absolute "^1.0.0"
10234 range-parser "^1.0.3"
10235 url-join "^4.0.0"
10236 webpack-log "^2.0.0"
10237
10238webpack-dev-middleware@3.3.0:
10239 version "3.3.0"
10240 resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.3.0.tgz#8104daf4d4f65defe06ee2eaaeea612a7c541462"
10241 integrity sha512-5C5gXtOo1I6+0AEg4UPglYEtu3Rai6l5IiO6aUu65scHXz29dc3oIWMiRwvcNLXgL0HwRkRxa9N02ZjFt4hY8w==
10242 dependencies: 10258 dependencies:
10243 loud-rejection "^1.6.0"
10244 memory-fs "~0.4.1" 10259 memory-fs "~0.4.1"
10245 mime "^2.3.1" 10260 mime "^2.3.1"
10246 range-parser "^1.0.3" 10261 range-parser "^1.0.3"
10247 url-join "^4.0.0"
10248 webpack-log "^2.0.0" 10262 webpack-log "^2.0.0"
10249 10263
10250webpack-dev-server@3.1.8: 10264webpack-dev-server@3.1.10:
10251 version "3.1.8" 10265 version "3.1.10"
10252 resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.8.tgz#eb7a95945d1108170f902604fb3b939533d9daeb" 10266 resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.1.10.tgz#507411bee727ee8d2fdffdc621b66a64ab3dea2b"
10253 integrity sha512-c+tcJtDqnPdxCAzEEZKdIPmg3i5i7cAHe+B+0xFNK0BlCc2HF/unYccbU7xTgfGc5xxhCztCQzFmsqim+KhI+A== 10267 integrity sha512-RqOAVjfqZJtQcB0LmrzJ5y4Jp78lv9CK0MZ1YJDTaTmedMZ9PU9FLMQNrMCfVu8hHzaVLVOJKBlGEHMN10z+ww==
10254 dependencies: 10268 dependencies:
10255 ansi-html "0.0.7" 10269 ansi-html "0.0.7"
10256 bonjour "^3.5.0" 10270 bonjour "^3.5.0"
@@ -10273,11 +10287,11 @@ webpack-dev-server@3.1.8:
10273 selfsigned "^1.9.1" 10287 selfsigned "^1.9.1"
10274 serve-index "^1.7.2" 10288 serve-index "^1.7.2"
10275 sockjs "0.3.19" 10289 sockjs "0.3.19"
10276 sockjs-client "1.1.5" 10290 sockjs-client "1.3.0"
10277 spdy "^3.4.1" 10291 spdy "^3.4.1"
10278 strip-ansi "^3.0.0" 10292 strip-ansi "^3.0.0"
10279 supports-color "^5.1.0" 10293 supports-color "^5.1.0"
10280 webpack-dev-middleware "3.2.0" 10294 webpack-dev-middleware "3.4.0"
10281 webpack-log "^2.0.0" 10295 webpack-log "^2.0.0"
10282 yargs "12.0.2" 10296 yargs "12.0.2"
10283 10297
@@ -10314,6 +10328,14 @@ webpack-sources@1.2.0:
10314 source-list-map "^2.0.0" 10328 source-list-map "^2.0.0"
10315 source-map "~0.6.1" 10329 source-map "~0.6.1"
10316 10330
10331webpack-sources@1.3.0, webpack-sources@^1.1.0, webpack-sources@^1.2.0, webpack-sources@^1.3.0:
10332 version "1.3.0"
10333 resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85"
10334 integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==
10335 dependencies:
10336 source-list-map "^2.0.0"
10337 source-map "~0.6.1"
10338
10317webpack-sources@^0.1.4: 10339webpack-sources@^0.1.4:
10318 version "0.1.5" 10340 version "0.1.5"
10319 resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750" 10341 resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750"
@@ -10322,14 +10344,6 @@ webpack-sources@^0.1.4:
10322 source-list-map "~0.1.7" 10344 source-list-map "~0.1.7"
10323 source-map "~0.5.3" 10345 source-map "~0.5.3"
10324 10346
10325webpack-sources@^1.1.0, webpack-sources@^1.2.0, webpack-sources@^1.3.0:
10326 version "1.3.0"
10327 resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85"
10328 integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==
10329 dependencies:
10330 source-list-map "^2.0.0"
10331 source-map "~0.6.1"
10332
10333webpack-subresource-integrity@1.1.0-rc.6: 10347webpack-subresource-integrity@1.1.0-rc.6:
10334 version "1.1.0-rc.6" 10348 version "1.1.0-rc.6"
10335 resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-1.1.0-rc.6.tgz#37f6f1264e1eb378e41465a98da80fad76ab8886" 10349 resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-1.1.0-rc.6.tgz#37f6f1264e1eb378e41465a98da80fad76ab8886"
@@ -10337,45 +10351,15 @@ webpack-subresource-integrity@1.1.0-rc.6:
10337 dependencies: 10351 dependencies:
10338 webpack-core "^0.6.8" 10352 webpack-core "^0.6.8"
10339 10353
10340webpack@4.19.1: 10354webpack@4.23.1:
10341 version "4.19.1" 10355 version "4.23.1"
10342 resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.19.1.tgz#096674bc3b573f8756c762754366e5b333d6576f" 10356 resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.23.1.tgz#db7467b116771ae020c58bdfe2a0822785bb8239"
10343 integrity sha512-j7Q/5QqZRqIFXJvC0E59ipLV5Hf6lAnS3ezC3I4HMUybwEDikQBVad5d+IpPtmaQPQArvgUZLXIN6lWijHBn4g== 10357 integrity sha512-iE5Cu4rGEDk7ONRjisTOjVHv3dDtcFfwitSxT7evtYj/rANJpt1OuC/Kozh1pBa99AUBr1L/LsaNB+D9Xz3CEg==
10344 dependencies: 10358 dependencies:
10345 "@webassemblyjs/ast" "1.7.6" 10359 "@webassemblyjs/ast" "1.7.10"
10346 "@webassemblyjs/helper-module-context" "1.7.6" 10360 "@webassemblyjs/helper-module-context" "1.7.10"
10347 "@webassemblyjs/wasm-edit" "1.7.6" 10361 "@webassemblyjs/wasm-edit" "1.7.10"
10348 "@webassemblyjs/wasm-parser" "1.7.6" 10362 "@webassemblyjs/wasm-parser" "1.7.10"
10349 acorn "^5.6.2"
10350 acorn-dynamic-import "^3.0.0"
10351 ajv "^6.1.0"
10352 ajv-keywords "^3.1.0"
10353 chrome-trace-event "^1.0.0"
10354 enhanced-resolve "^4.1.0"
10355 eslint-scope "^4.0.0"
10356 json-parse-better-errors "^1.0.2"
10357 loader-runner "^2.3.0"
10358 loader-utils "^1.1.0"
10359 memory-fs "~0.4.1"
10360 micromatch "^3.1.8"
10361 mkdirp "~0.5.0"
10362 neo-async "^2.5.0"
10363 node-libs-browser "^2.0.0"
10364 schema-utils "^0.4.4"
10365 tapable "^1.1.0"
10366 uglifyjs-webpack-plugin "^1.2.4"
10367 watchpack "^1.5.0"
10368 webpack-sources "^1.2.0"
10369
10370webpack@^4.17.1:
10371 version "4.25.1"
10372 resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.25.1.tgz#4f459fbaea0f93440dc86c89f771bb3a837cfb6d"
10373 integrity sha512-T0GU/3NRtO4tMfNzsvpdhUr8HnzA4LTdP2zd+e5zd6CdOH5vNKHnAlO+DvzccfhPdzqRrALOFcjYxx7K5DWmvA==
10374 dependencies:
10375 "@webassemblyjs/ast" "1.7.11"
10376 "@webassemblyjs/helper-module-context" "1.7.11"
10377 "@webassemblyjs/wasm-edit" "1.7.11"
10378 "@webassemblyjs/wasm-parser" "1.7.11"
10379 acorn "^5.6.2" 10363 acorn "^5.6.2"
10380 acorn-dynamic-import "^3.0.0" 10364 acorn-dynamic-import "^3.0.0"
10381 ajv "^6.1.0" 10365 ajv "^6.1.0"
@@ -10468,9 +10452,9 @@ whatwg-fetch@^3.0.0:
10468 integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== 10452 integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
10469 10453
10470whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: 10454whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0:
10471 version "2.2.0" 10455 version "2.3.0"
10472 resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.2.0.tgz#a3d58ef10b76009b042d03e25591ece89b88d171" 10456 resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
10473 integrity sha512-5YSO1nMd5D1hY3WzAQV3PzZL83W3YeyR1yW9PcH26Weh1t+Vzh9B6XkDh7aXm83HBZ4nSMvkjvN2H2ySWIvBgw== 10457 integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
10474 10458
10475whatwg-url@^6.4.1: 10459whatwg-url@^6.4.1:
10476 version "6.5.0" 10460 version "6.5.0"
@@ -10505,7 +10489,7 @@ which-module@^2.0.0:
10505 resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" 10489 resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
10506 integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= 10490 integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
10507 10491
10508which@1, which@^1.1.1, which@^1.2.1, which@^1.2.12, which@^1.2.9, which@^1.3.0: 10492which@1, which@^1.1.1, which@^1.2.1, which@^1.2.12, which@^1.2.9, which@^1.3.0, which@^1.3.1:
10509 version "1.3.1" 10493 version "1.3.1"
10510 resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 10494 resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
10511 integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== 10495 integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
@@ -10565,10 +10549,10 @@ ws@^5.2.0:
10565 dependencies: 10549 dependencies:
10566 async-limiter "~1.0.0" 10550 async-limiter "~1.0.0"
10567 10551
10568ws@^6.0.0: 10552ws@^6.0.0, ws@~6.1.0:
10569 version "6.1.0" 10553 version "6.1.2"
10570 resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.0.tgz#119a9dbf92c54e190ec18d10e871d55c95cf9373" 10554 resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8"
10571 integrity sha512-H3dGVdGvW2H8bnYpIDc3u3LH8Wue3Qh+Zto6aXXFzvESkTVT6rAfKR6tR/+coaUvxs8yHtmNV0uioBF62ZGSTg== 10555 integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==
10572 dependencies: 10556 dependencies:
10573 async-limiter "~1.0.0" 10557 async-limiter "~1.0.0"
10574 10558
@@ -10640,9 +10624,9 @@ yallist@^2.1.2:
10640 integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= 10624 integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
10641 10625
10642yallist@^3.0.0, yallist@^3.0.2: 10626yallist@^3.0.0, yallist@^3.0.2:
10643 version "3.0.2" 10627 version "3.0.3"
10644 resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" 10628 resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9"
10645 integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= 10629 integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==
10646 10630
10647yargs-parser@10.x, yargs-parser@^10.1.0: 10631yargs-parser@10.x, yargs-parser@^10.1.0:
10648 version "10.1.0" 10632 version "10.1.0"
@@ -10651,6 +10635,14 @@ yargs-parser@10.x, yargs-parser@^10.1.0:
10651 dependencies: 10635 dependencies:
10652 camelcase "^4.1.0" 10636 camelcase "^4.1.0"
10653 10637
10638yargs-parser@^11.1.1:
10639 version "11.1.1"
10640 resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"
10641 integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==
10642 dependencies:
10643 camelcase "^5.0.0"
10644 decamelize "^1.2.0"
10645
10654yargs-parser@^5.0.0: 10646yargs-parser@^5.0.0:
10655 version "5.0.0" 10647 version "5.0.0"
10656 resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" 10648 resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a"
@@ -10697,7 +10689,7 @@ yargs@10.0.3:
10697 y18n "^3.2.1" 10689 y18n "^3.2.1"
10698 yargs-parser "^8.0.0" 10690 yargs-parser "^8.0.0"
10699 10691
10700yargs@12.0.2, yargs@^12.0.2: 10692yargs@12.0.2:
10701 version "12.0.2" 10693 version "12.0.2"
10702 resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" 10694 resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc"
10703 integrity sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ== 10695 integrity sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==
@@ -10752,6 +10744,24 @@ yargs@^11.0.0:
10752 y18n "^3.2.1" 10744 y18n "^3.2.1"
10753 yargs-parser "^9.0.2" 10745 yargs-parser "^9.0.2"
10754 10746
10747yargs@^12.0.2:
10748 version "12.0.5"
10749 resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
10750 integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
10751 dependencies:
10752 cliui "^4.0.0"
10753 decamelize "^1.2.0"
10754 find-up "^3.0.0"
10755 get-caller-file "^1.0.1"
10756 os-locale "^3.0.0"
10757 require-directory "^2.1.1"
10758 require-main-filename "^1.0.1"
10759 set-blocking "^2.0.0"
10760 string-width "^2.0.0"
10761 which-module "^2.0.0"
10762 y18n "^3.2.1 || ^4.0.0"
10763 yargs-parser "^11.1.1"
10764
10755yargs@^7.0.0: 10765yargs@^7.0.0:
10756 version "7.1.0" 10766 version "7.1.0"
10757 resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" 10767 resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8"
diff --git a/config/default.yaml b/config/default.yaml
index 257ec7ed1..e16b8c352 100644
--- a/config/default.yaml
+++ b/config/default.yaml
@@ -45,8 +45,10 @@ smtp:
45 45
46# From the project root directory 46# From the project root directory
47storage: 47storage:
48 tmp: 'storage/tmp/' # Used to download data (imports etc), store uploaded files before processing...
48 avatars: 'storage/avatars/' 49 avatars: 'storage/avatars/'
49 videos: 'storage/videos/' 50 videos: 'storage/videos/'
51 redundancy: 'storage/redundancy/'
50 logs: 'storage/logs/' 52 logs: 'storage/logs/'
51 previews: 'storage/previews/' 53 previews: 'storage/previews/'
52 thumbnails: 'storage/thumbnails/' 54 thumbnails: 'storage/thumbnails/'
@@ -75,7 +77,7 @@ trending:
75redundancy: 77redundancy:
76 videos: 78 videos:
77 check_interval: '1 hour' # How often you want to check new videos to cache 79 check_interval: '1 hour' # How often you want to check new videos to cache
78 strategies: 80 strategies: # Just uncomment strategies you want
79# - 81# -
80# size: '10GB' 82# size: '10GB'
81# # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances) 83# # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)
@@ -100,7 +102,12 @@ cache:
100 size: 500 # Max number of video captions/subtitles you want to cache 102 size: 500 # Max number of video captions/subtitles you want to cache
101 103
102admin: 104admin:
103 email: 'admin@example.com' # Your personal email as administrator 105 # Used to generate the root user at first startup
106 # And to receive emails from the contact form
107 email: 'admin@example.com'
108
109contact_form:
110 enabled: true
104 111
105signup: 112signup:
106 enabled: false 113 enabled: false
@@ -122,6 +129,8 @@ user:
122# Please, do not disable transcoding since many uploaded videos will not work 129# Please, do not disable transcoding since many uploaded videos will not work
123transcoding: 130transcoding:
124 enabled: true 131 enabled: true
132 # Allow your users to upload .mkv, .mov, .avi, .flv videos
133 allow_additional_extensions: true
125 threads: 1 134 threads: 1
126 resolutions: # Only created if the original video has a higher resolution, uses more storage! 135 resolutions: # Only created if the original video has a higher resolution, uses more storage!
127 240p: false 136 240p: false
@@ -159,6 +168,8 @@ instance:
159 "# If you would like to report a security issue\n# you may report it to:\nContact: https://github.com/Chocobozzz/PeerTube/blob/develop/SECURITY.md\nContact: mailto:" 168 "# If you would like to report a security issue\n# you may report it to:\nContact: https://github.com/Chocobozzz/PeerTube/blob/develop/SECURITY.md\nContact: mailto:"
160 169
161services: 170services:
171 # You can provide a reporting endpoint for Content Security Policy violations
172 csp-logger:
162 # Cards configuration to format video in Twitter 173 # Cards configuration to format video in Twitter
163 twitter: 174 twitter:
164 username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published 175 username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published
diff --git a/config/production.yaml.example b/config/production.yaml.example
index ac15fc736..661eac0d5 100644
--- a/config/production.yaml.example
+++ b/config/production.yaml.example
@@ -46,8 +46,10 @@ smtp:
46 46
47# From the project root directory 47# From the project root directory
48storage: 48storage:
49 tmp: '/var/www/peertube/storage/tmp/' # Used to download data (imports etc), store uploaded files before processing...
49 avatars: '/var/www/peertube/storage/avatars/' 50 avatars: '/var/www/peertube/storage/avatars/'
50 videos: '/var/www/peertube/storage/videos/' 51 videos: '/var/www/peertube/storage/videos/'
52 redundancy: '/var/www/peertube/storage/videos/'
51 logs: '/var/www/peertube/storage/logs/' 53 logs: '/var/www/peertube/storage/logs/'
52 previews: '/var/www/peertube/storage/previews/' 54 previews: '/var/www/peertube/storage/previews/'
53 thumbnails: '/var/www/peertube/storage/thumbnails/' 55 thumbnails: '/var/www/peertube/storage/thumbnails/'
@@ -76,7 +78,7 @@ trending:
76redundancy: 78redundancy:
77 videos: 79 videos:
78 check_interval: '1 hour' # How often you want to check new videos to cache 80 check_interval: '1 hour' # How often you want to check new videos to cache
79 strategies: 81 strategies: # Just uncomment strategies you want
80# - 82# -
81# size: '10GB' 83# size: '10GB'
82# # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances) 84# # Minimum time the video must remain in the cache. Only accept values > 10 hours (to not overload remote instances)
@@ -113,8 +115,13 @@ cache:
113 size: 500 # Max number of video captions/subtitles you want to cache 115 size: 500 # Max number of video captions/subtitles you want to cache
114 116
115admin: 117admin:
118 # Used to generate the root user at first startup
119 # And to receive emails from the contact form
116 email: 'admin@example.com' 120 email: 'admin@example.com'
117 121
122contact_form:
123 enabled: true
124
118signup: 125signup:
119 enabled: false 126 enabled: false
120 limit: 10 # When the limit is reached, registrations are disabled. -1 == unlimited 127 limit: 10 # When the limit is reached, registrations are disabled. -1 == unlimited
@@ -135,6 +142,8 @@ user:
135# Please, do not disable transcoding since many uploaded videos will not work 142# Please, do not disable transcoding since many uploaded videos will not work
136transcoding: 143transcoding:
137 enabled: true 144 enabled: true
145 # Allow your users to upload .mkv, .mov, .avi, .flv videos
146 allow_additional_extensions: true
138 threads: 1 147 threads: 1
139 resolutions: # Only created if the original video has a higher resolution, uses more storage! 148 resolutions: # Only created if the original video has a higher resolution, uses more storage!
140 240p: false 149 240p: false
@@ -173,6 +182,8 @@ instance:
173 "# If you would like to report a security issue\n# you may report it to:\nContact: https://github.com/Chocobozzz/PeerTube/blob/develop/SECURITY.md\nContact: mailto:" 182 "# If you would like to report a security issue\n# you may report it to:\nContact: https://github.com/Chocobozzz/PeerTube/blob/develop/SECURITY.md\nContact: mailto:"
174 183
175services: 184services:
185 # You can provide a reporting endpoint for Content Security Policy violations
186 csp-logger:
176 # Cards configuration to format video in Twitter 187 # Cards configuration to format video in Twitter
177 twitter: 188 twitter:
178 username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published 189 username: '@Chocobozzz' # Indicates the Twitter account for the website or platform on which the content was published
diff --git a/config/test-1.yaml b/config/test-1.yaml
index 503bbc661..8f4f66d2a 100644
--- a/config/test-1.yaml
+++ b/config/test-1.yaml
@@ -10,8 +10,10 @@ database:
10 10
11# From the project root directory 11# From the project root directory
12storage: 12storage:
13 tmp: 'test1/tmp/'
13 avatars: 'test1/avatars/' 14 avatars: 'test1/avatars/'
14 videos: 'test1/videos/' 15 videos: 'test1/videos/'
16 redundancy: 'test1/redundancy/'
15 logs: 'test1/logs/' 17 logs: 'test1/logs/'
16 previews: 'test1/previews/' 18 previews: 'test1/previews/'
17 thumbnails: 'test1/thumbnails/' 19 thumbnails: 'test1/thumbnails/'
diff --git a/config/test-2.yaml b/config/test-2.yaml
index 8c77bf581..b6d319394 100644
--- a/config/test-2.yaml
+++ b/config/test-2.yaml
@@ -10,8 +10,10 @@ database:
10 10
11# From the project root directory 11# From the project root directory
12storage: 12storage:
13 tmp: 'test2/tmp/'
13 avatars: 'test2/avatars/' 14 avatars: 'test2/avatars/'
14 videos: 'test2/videos/' 15 videos: 'test2/videos/'
16 redundancy: 'test2/redundancy/'
15 logs: 'test2/logs/' 17 logs: 'test2/logs/'
16 previews: 'test2/previews/' 18 previews: 'test2/previews/'
17 thumbnails: 'test2/thumbnails/' 19 thumbnails: 'test2/thumbnails/'
@@ -27,3 +29,4 @@ signup:
27 29
28transcoding: 30transcoding:
29 enabled: true 31 enabled: true
32 allow_additional_extensions: true
diff --git a/config/test-3.yaml b/config/test-3.yaml
index 82d89567a..934401eb0 100644
--- a/config/test-3.yaml
+++ b/config/test-3.yaml
@@ -10,8 +10,10 @@ database:
10 10
11# From the project root directory 11# From the project root directory
12storage: 12storage:
13 tmp: 'test3/tmp/'
13 avatars: 'test3/avatars/' 14 avatars: 'test3/avatars/'
14 videos: 'test3/videos/' 15 videos: 'test3/videos/'
16 redundancy: 'test3/redundancy/'
15 logs: 'test3/logs/' 17 logs: 'test3/logs/'
16 previews: 'test3/previews/' 18 previews: 'test3/previews/'
17 thumbnails: 'test3/thumbnails/' 19 thumbnails: 'test3/thumbnails/'
diff --git a/config/test-4.yaml b/config/test-4.yaml
index 1aa56d041..ee99b250b 100644
--- a/config/test-4.yaml
+++ b/config/test-4.yaml
@@ -10,8 +10,10 @@ database:
10 10
11# From the project root directory 11# From the project root directory
12storage: 12storage:
13 tmp: 'test4/tmp/'
13 avatars: 'test4/avatars/' 14 avatars: 'test4/avatars/'
14 videos: 'test4/videos/' 15 videos: 'test4/videos/'
16 redundancy: 'test4/redundancy/'
15 logs: 'test4/logs/' 17 logs: 'test4/logs/'
16 previews: 'test4/previews/' 18 previews: 'test4/previews/'
17 thumbnails: 'test4/thumbnails/' 19 thumbnails: 'test4/thumbnails/'
diff --git a/config/test-5.yaml b/config/test-5.yaml
index 5f1c2f583..e2662bdd9 100644
--- a/config/test-5.yaml
+++ b/config/test-5.yaml
@@ -10,8 +10,10 @@ database:
10 10
11# From the project root directory 11# From the project root directory
12storage: 12storage:
13 tmp: 'test5/tmp/'
13 avatars: 'test5/avatars/' 14 avatars: 'test5/avatars/'
14 videos: 'test5/videos/' 15 videos: 'test5/videos/'
16 redundancy: 'test5/redundancy/'
15 logs: 'test5/logs/' 17 logs: 'test5/logs/'
16 previews: 'test5/previews/' 18 previews: 'test5/previews/'
17 thumbnails: 'test5/thumbnails/' 19 thumbnails: 'test5/thumbnails/'
diff --git a/config/test-6.yaml b/config/test-6.yaml
index 719629844..ad39c6a9f 100644
--- a/config/test-6.yaml
+++ b/config/test-6.yaml
@@ -10,8 +10,10 @@ database:
10 10
11# From the project root directory 11# From the project root directory
12storage: 12storage:
13 tmp: 'test6/tmp/'
13 avatars: 'test6/avatars/' 14 avatars: 'test6/avatars/'
14 videos: 'test6/videos/' 15 videos: 'test6/videos/'
16 redundancy: 'test6/redundancy/'
15 logs: 'test6/logs/' 17 logs: 'test6/logs/'
16 previews: 'test6/previews/' 18 previews: 'test6/previews/'
17 thumbnails: 'test6/thumbnails/' 19 thumbnails: 'test6/thumbnails/'
diff --git a/config/test.yaml b/config/test.yaml
index 9c051fabc..aba5dd73c 100644
--- a/config/test.yaml
+++ b/config/test.yaml
@@ -21,6 +21,9 @@ smtp:
21log: 21log:
22 level: 'debug' 22 level: 'debug'
23 23
24contact_form:
25 enabled: true
26
24redundancy: 27redundancy:
25 videos: 28 videos:
26 check_interval: '10 minutes' 29 check_interval: '10 minutes'
@@ -51,6 +54,7 @@ signup:
51 54
52transcoding: 55transcoding:
53 enabled: true 56 enabled: true
57 allow_additional_extensions: false
54 threads: 2 58 threads: 2
55 resolutions: 59 resolutions:
56 240p: true 60 240p: true
@@ -67,4 +71,4 @@ import:
67 enabled: true 71 enabled: true
68 72
69instance: 73instance:
70 default_nsfw_policy: 'display' \ No newline at end of file 74 default_nsfw_policy: 'display'
diff --git a/package.json b/package.json
index d4076612e..0cf39c7ee 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
1{ 1{
2 "name": "peertube", 2 "name": "peertube",
3 "description": "Federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.", 3 "description": "Federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.",
4 "version": "1.1.0", 4 "version": "1.2.0",
5 "private": true, 5 "private": true,
6 "licence": "AGPLv3", 6 "licence": "AGPLv3",
7 "engines": { 7 "engines": {
@@ -104,7 +104,7 @@
104 "cli-table": "^0.3.1", 104 "cli-table": "^0.3.1",
105 "commander": "^2.13.0", 105 "commander": "^2.13.0",
106 "concurrently": "^4.0.1", 106 "concurrently": "^4.0.1",
107 "config": "^2.0.1", 107 "config": "^3.0.0",
108 "cookie-parser": "^1.4.3", 108 "cookie-parser": "^1.4.3",
109 "cors": "^2.8.1", 109 "cors": "^2.8.1",
110 "create-torrent": "^3.24.5", 110 "create-torrent": "^3.24.5",
@@ -127,7 +127,6 @@
127 "jsonld-signatures": "https://github.com/Chocobozzz/jsonld-signatures#rsa2017", 127 "jsonld-signatures": "https://github.com/Chocobozzz/jsonld-signatures#rsa2017",
128 "lodash": "^4.17.10", 128 "lodash": "^4.17.10",
129 "magnet-uri": "^5.1.4", 129 "magnet-uri": "^5.1.4",
130 "marked-man": "^0.2.1",
131 "memoizee": "^0.4.14", 130 "memoizee": "^0.4.14",
132 "morgan": "^1.5.3", 131 "morgan": "^1.5.3",
133 "multer": "^1.1.0", 132 "multer": "^1.1.0",
@@ -138,16 +137,16 @@
138 "pem": "^1.12.3", 137 "pem": "^1.12.3",
139 "pfeed": "^1.1.6", 138 "pfeed": "^1.1.6",
140 "pg": "^7.4.1", 139 "pg": "^7.4.1",
141 "pg-hstore": "^2.3.2",
142 "prompt": "^1.0.0", 140 "prompt": "^1.0.0",
143 "redis": "^2.8.0", 141 "redis": "^2.8.0",
144 "reflect-metadata": "^0.1.10", 142 "reflect-metadata": "^0.1.12",
145 "request": "^2.81.0", 143 "request": "^2.81.0",
146 "safe-buffer": "^5.0.1",
147 "scripty": "^1.5.0", 144 "scripty": "^1.5.0",
148 "sequelize": "4.41.2", 145 "sequelize": "4.41.2",
149 "sequelize-typescript": "0.6.6", 146 "sequelize-typescript": "0.6.6",
150 "sharp": "^0.21.0", 147 "sharp": "^0.21.0",
148 "sitemap": "^2.1.0",
149 "socket.io": "^2.2.0",
151 "srt-to-vtt": "^1.1.2", 150 "srt-to-vtt": "^1.1.2",
152 "summon-install": "^0.4.3", 151 "summon-install": "^0.4.3",
153 "useragent": "^2.3.0", 152 "useragent": "^2.3.0",
@@ -165,7 +164,7 @@
165 "@types/bcrypt": "^3.0.0", 164 "@types/bcrypt": "^3.0.0",
166 "@types/bluebird": "3.5.21", 165 "@types/bluebird": "3.5.21",
167 "@types/body-parser": "^1.16.3", 166 "@types/body-parser": "^1.16.3",
168 "@types/bull": "^3.3.12", 167 "@types/bull": "3.4.0",
169 "@types/bytes": "^3.0.0", 168 "@types/bytes": "^3.0.0",
170 "@types/chai": "^4.0.4", 169 "@types/chai": "^4.0.4",
171 "@types/chai-json-schema": "^1.4.3", 170 "@types/chai-json-schema": "^1.4.3",
@@ -191,6 +190,7 @@
191 "@types/redis": "^2.8.5", 190 "@types/redis": "^2.8.5",
192 "@types/request": "^2.0.3", 191 "@types/request": "^2.0.3",
193 "@types/sharp": "^0.21.0", 192 "@types/sharp": "^0.21.0",
193 "@types/socket.io": "^2.1.2",
194 "@types/supertest": "^2.0.3", 194 "@types/supertest": "^2.0.3",
195 "@types/validator": "^9.4.0", 195 "@types/validator": "^9.4.0",
196 "@types/webtorrent": "^0.98.4", 196 "@types/webtorrent": "^0.98.4",
@@ -202,6 +202,7 @@
202 "libxmljs": "0.19.5", 202 "libxmljs": "0.19.5",
203 "lint-staged": "^8.0.4", 203 "lint-staged": "^8.0.4",
204 "maildev": "^1.0.0-rc3", 204 "maildev": "^1.0.0-rc3",
205 "marked-man": "^0.2.1",
205 "mocha": "^5.0.0", 206 "mocha": "^5.0.0",
206 "nodemon": "^1.18.6", 207 "nodemon": "^1.18.6",
207 "sass-lint": "^1.12.1", 208 "sass-lint": "^1.12.1",
diff --git a/scripts/build/client.sh b/scripts/build/client.sh
index 62daf98cf..be3eef802 100755
--- a/scripts/build/client.sh
+++ b/scripts/build/client.sh
@@ -41,7 +41,7 @@ if [ -z ${1+x} ] || [ "$1" != "--light" ]; then
41 languages=("fr_FR") 41 languages=("fr_FR")
42 else 42 else
43 # Supported languages 43 # Supported languages
44 languages=("fr_FR" "pt_BR" "sv_SE" "eu_ES" "ca_ES" "cs_CZ" "eo" "zh_Hant_TW" "de_DE" "es_ES" "oc" "zh_Hans_CN") 44 languages=("pl_PL" "it_IT" "ru_RU" "fr_FR" "pt_BR" "sv_SE" "eu_ES" "ca_ES" "cs_CZ" "eo" "zh_Hant_TW" "de_DE" "es_ES" "oc" "zh_Hans_CN")
45 fi 45 fi
46 46
47 for lang in "${languages[@]}"; do 47 for lang in "${languages[@]}"; do
diff --git a/scripts/clean/server/test.sh b/scripts/clean/server/test.sh
index 235ff52cc..b897c30ba 100755
--- a/scripts/clean/server/test.sh
+++ b/scripts/clean/server/test.sh
@@ -18,6 +18,7 @@ removeFiles () {
18 18
19dropRedis () { 19dropRedis () {
20 redis-cli KEYS "bull-localhost:900$1*" | grep -v empty | xargs --no-run-if-empty redis-cli DEL 20 redis-cli KEYS "bull-localhost:900$1*" | grep -v empty | xargs --no-run-if-empty redis-cli DEL
21 redis-cli KEYS "redis-localhost:900$1*" | grep -v empty | xargs --no-run-if-empty redis-cli DEL
21} 22}
22 23
23for i in $(seq 1 6); do 24for i in $(seq 1 6); do
diff --git a/scripts/generate-code-contributors.ts b/scripts/generate-code-contributors.ts
index 3d37372d1..9824bc2f5 100755
--- a/scripts/generate-code-contributors.ts
+++ b/scripts/generate-code-contributors.ts
@@ -70,11 +70,17 @@ async function fetchGithub (url: string) {
70 70
71async function fetchZanata (zanataUsername: string, zanataPassword: string) { 71async function fetchZanata (zanataUsername: string, zanataPassword: string) {
72 const today = new Date().toISOString().split('T')[0] 72 const today = new Date().toISOString().split('T')[0]
73 const url = `https://trad.framasoft.org/zanata/rest/project/peertube/version/develop/contributors/2018-01-01..${today}` 73 const year2018 = `https://trad.framasoft.org/zanata/rest/project/peertube/version/develop/contributors/2018-01-01..2019-01-01`
74 const year2019 = `https://trad.framasoft.org/zanata/rest/project/peertube/version/develop/contributors/2019-01-01..${today}`
74 75
75 const headers = { 76 const headers = {
76 'X-Auth-User': zanataUsername, 77 'X-Auth-User': zanataUsername,
77 'X-Auth-Token': zanataPassword 78 'X-Auth-Token': zanataPassword
78 } 79 }
79 return get(url, headers) 80 const [ results2018, results2019 ] = await Promise.all([
81 get(year2018, headers),
82 get(year2019, headers)
83 ])
84
85 return results2018.concat(results2019)
80} 86}
diff --git a/scripts/i18n/create-custom-files.ts b/scripts/i18n/create-custom-files.ts
index eed3182a6..ab28f94c8 100755
--- a/scripts/i18n/create-custom-files.ts
+++ b/scripts/i18n/create-custom-files.ts
@@ -42,6 +42,12 @@ values(VIDEO_CATEGORIES)
42 .concat(values(VIDEO_PRIVACIES)) 42 .concat(values(VIDEO_PRIVACIES))
43 .concat(values(VIDEO_STATES)) 43 .concat(values(VIDEO_STATES))
44 .concat(values(VIDEO_IMPORT_STATES)) 44 .concat(values(VIDEO_IMPORT_STATES))
45 .concat([
46 'This video does not exist.',
47 'We cannot fetch the video. Please try again later.',
48 'Sorry',
49 'This video is not available because the remote instance is not responding.'
50 ])
45 .forEach(v => serverKeys[v] = v) 51 .forEach(v => serverKeys[v] = v)
46 52
47// More keys 53// More keys
@@ -103,4 +109,4 @@ function saveToXliffFile (jsonTranslations: TranslationType, cb: Function) {
103function handleError (err: any) { 109function handleError (err: any) {
104 console.error(err) 110 console.error(err)
105 process.exit(-1) 111 process.exit(-1)
106} \ No newline at end of file 112}
diff --git a/scripts/prune-storage.ts b/scripts/prune-storage.ts
index 4ab0b4863..c9e4dbd4b 100755
--- a/scripts/prune-storage.ts
+++ b/scripts/prune-storage.ts
@@ -19,7 +19,8 @@ async function run () {
19 19
20 const storageOnlyOwnedToPrune = [ 20 const storageOnlyOwnedToPrune = [
21 CONFIG.STORAGE.VIDEOS_DIR, 21 CONFIG.STORAGE.VIDEOS_DIR,
22 CONFIG.STORAGE.TORRENTS_DIR 22 CONFIG.STORAGE.TORRENTS_DIR,
23 CONFIG.STORAGE.REDUNDANCY_DIR
23 ] 24 ]
24 25
25 const storageForAllToPrune = [ 26 const storageForAllToPrune = [
@@ -36,6 +37,9 @@ async function run () {
36 toDelete = toDelete.concat(await pruneDirectory(directory, false)) 37 toDelete = toDelete.concat(await pruneDirectory(directory, false))
37 } 38 }
38 39
40 const tmpFiles = await readdir(CONFIG.STORAGE.TMP_DIR)
41 toDelete = toDelete.concat(tmpFiles.map(t => join(CONFIG.STORAGE.TMP_DIR, t)))
42
39 if (toDelete.length === 0) { 43 if (toDelete.length === 0) {
40 console.log('No files to delete.') 44 console.log('No files to delete.')
41 return 45 return
@@ -91,6 +95,7 @@ async function askConfirmation () {
91 confirm: { 95 confirm: {
92 type: 'string', 96 type: 'string',
93 description: 'These following unused files can be deleted, but please check your backups first (bugs happen).' + 97 description: 'These following unused files can be deleted, but please check your backups first (bugs happen).' +
98 ' Notice PeerTube must have been stopped when your ran this script.' +
94 ' Can we delete these files?', 99 ' Can we delete these files?',
95 default: 'n', 100 default: 'n',
96 required: true 101 required: true
diff --git a/scripts/upgrade.sh b/scripts/upgrade.sh
index c70b3b42a..4f7c58edd 100755
--- a/scripts/upgrade.sh
+++ b/scripts/upgrade.sh
@@ -20,6 +20,16 @@ if [ ! -e "$PEERTUBE_PATH/versions" -o ! -e "$PEERTUBE_PATH/config/production.ya
20 exit 1 20 exit 1
21fi 21fi
22 22
23if [ -x "$(command -v awk)" ] && [ -x "$(command -v sed)" ] ; then
24 REMAINING=$(df -k $PEERTUBE_PATH | awk '{ print $4}' | sed -n 2p)
25 ONE_GB=$((1024 * 1024))
26 if [ "$REMAINING" -lt "$ONE_GB" ]; then
27 echo "Error - not enough free space for upgrading"
28 echo ""
29 echo "Make sure you have at least 1 GB of free space in $PEERTUBE_PATH"
30 exit 1
31 fi
32fi
23 33
24# Backup database 34# Backup database
25SQL_BACKUP_PATH="$PEERTUBE_PATH/backup/sql-peertube_prod-$(date +"%Y%m%d-%H%M").bak" 35SQL_BACKUP_PATH="$PEERTUBE_PATH/backup/sql-peertube_prod-$(date +"%Y%m%d-%H%M").bak"
diff --git a/server.ts b/server.ts
index 3025a6fd7..b50151859 100644
--- a/server.ts
+++ b/server.ts
@@ -28,7 +28,7 @@ import { checkMissedConfig, checkFFmpeg } from './server/initializers/checker-be
28 28
29// Do not use barrels because we don't want to load all modules here (we need to initialize database first) 29// Do not use barrels because we don't want to load all modules here (we need to initialize database first)
30import { logger } from './server/helpers/logger' 30import { logger } from './server/helpers/logger'
31import { API_VERSION, CONFIG, CACHE, HTTP_SIGNATURE } from './server/initializers/constants' 31import { API_VERSION, CONFIG, CACHE } from './server/initializers/constants'
32 32
33const missed = checkMissedConfig() 33const missed = checkMissedConfig()
34if (missed.length !== 0) { 34if (missed.length !== 0) {
@@ -53,6 +53,9 @@ if (errorMessage !== null) {
53app.set('trust proxy', CONFIG.TRUST_PROXY) 53app.set('trust proxy', CONFIG.TRUST_PROXY)
54 54
55// Security middleware 55// Security middleware
56import { baseCSP } from './server/middlewares'
57
58app.use(baseCSP)
56app.use(helmet({ 59app.use(helmet({
57 frameguard: { 60 frameguard: {
58 action: 'deny' // we only allow it for /videos/embed, see server/controllers/client.ts 61 action: 'deny' // we only allow it for /videos/embed, see server/controllers/client.ts
@@ -87,16 +90,17 @@ import {
87 servicesRouter, 90 servicesRouter,
88 webfingerRouter, 91 webfingerRouter,
89 trackerRouter, 92 trackerRouter,
90 createWebsocketServer 93 createWebsocketTrackerServer, botsRouter
91} from './server/controllers' 94} from './server/controllers'
92import { advertiseDoNotTrack } from './server/middlewares/dnt' 95import { advertiseDoNotTrack } from './server/middlewares/dnt'
93import { Redis } from './server/lib/redis' 96import { Redis } from './server/lib/redis'
94import { BadActorFollowScheduler } from './server/lib/schedulers/bad-actor-follow-scheduler' 97import { ActorFollowScheduler } from './server/lib/schedulers/actor-follow-scheduler'
95import { RemoveOldJobsScheduler } from './server/lib/schedulers/remove-old-jobs-scheduler' 98import { RemoveOldJobsScheduler } from './server/lib/schedulers/remove-old-jobs-scheduler'
96import { UpdateVideosScheduler } from './server/lib/schedulers/update-videos-scheduler' 99import { UpdateVideosScheduler } from './server/lib/schedulers/update-videos-scheduler'
97import { YoutubeDlUpdateScheduler } from './server/lib/schedulers/youtube-dl-update-scheduler' 100import { YoutubeDlUpdateScheduler } from './server/lib/schedulers/youtube-dl-update-scheduler'
98import { VideosRedundancyScheduler } from './server/lib/schedulers/videos-redundancy-scheduler' 101import { VideosRedundancyScheduler } from './server/lib/schedulers/videos-redundancy-scheduler'
99import { isHTTPSignatureDigestValid } from './server/helpers/peertube-crypto' 102import { isHTTPSignatureDigestValid } from './server/helpers/peertube-crypto'
103import { PeerTubeSocket } from './server/lib/peertube-socket'
100 104
101// ----------- Command line ----------- 105// ----------- Command line -----------
102 106
@@ -133,7 +137,7 @@ app.use(bodyParser.urlencoded({ extended: false }))
133app.use(bodyParser.json({ 137app.use(bodyParser.json({
134 type: [ 'application/json', 'application/*+json' ], 138 type: [ 'application/json', 'application/*+json' ],
135 limit: '500kb', 139 limit: '500kb',
136 verify: (req: express.Request, _, buf: Buffer, encoding: string) => { 140 verify: (req: express.Request, _, buf: Buffer) => {
137 const valid = isHTTPSignatureDigestValid(buf, req) 141 const valid = isHTTPSignatureDigestValid(buf, req)
138 if (valid !== true) throw new Error('Invalid digest') 142 if (valid !== true) throw new Error('Invalid digest')
139 } 143 }
@@ -156,6 +160,7 @@ app.use('/', activityPubRouter)
156app.use('/', feedsRouter) 160app.use('/', feedsRouter)
157app.use('/', webfingerRouter) 161app.use('/', webfingerRouter)
158app.use('/', trackerRouter) 162app.use('/', trackerRouter)
163app.use('/', botsRouter)
159 164
160// Static files 165// Static files
161app.use('/', staticRouter) 166app.use('/', staticRouter)
@@ -185,7 +190,7 @@ app.use(function (err, req, res, next) {
185 return res.status(err.status || 500).end() 190 return res.status(err.status || 500).end()
186}) 191})
187 192
188const server = createWebsocketServer(app) 193const server = createWebsocketTrackerServer(app)
189 194
190// ----------- Run ----------- 195// ----------- Run -----------
191 196
@@ -215,7 +220,7 @@ async function startApplication () {
215 VideosCaptionCache.Instance.init(CONFIG.CACHE.VIDEO_CAPTIONS.SIZE, CACHE.VIDEO_CAPTIONS.MAX_AGE) 220 VideosCaptionCache.Instance.init(CONFIG.CACHE.VIDEO_CAPTIONS.SIZE, CACHE.VIDEO_CAPTIONS.MAX_AGE)
216 221
217 // Enable Schedulers 222 // Enable Schedulers
218 BadActorFollowScheduler.Instance.enable() 223 ActorFollowScheduler.Instance.enable()
219 RemoveOldJobsScheduler.Instance.enable() 224 RemoveOldJobsScheduler.Instance.enable()
220 UpdateVideosScheduler.Instance.enable() 225 UpdateVideosScheduler.Instance.enable()
221 YoutubeDlUpdateScheduler.Instance.enable() 226 YoutubeDlUpdateScheduler.Instance.enable()
@@ -224,6 +229,8 @@ async function startApplication () {
224 // Redis initialization 229 // Redis initialization
225 Redis.Instance.init() 230 Redis.Instance.init()
226 231
232 PeerTubeSocket.Instance.init(server)
233
227 // Make server listening 234 // Make server listening
228 server.listen(port, hostname, () => { 235 server.listen(port, hostname, () => {
229 logger.info('Server listening on %s:%d', hostname, port) 236 logger.info('Server listening on %s:%d', hostname, port)
diff --git a/server/controllers/api/accounts.ts b/server/controllers/api/accounts.ts
index 86ef2aed1..8c0237203 100644
--- a/server/controllers/api/accounts.ts
+++ b/server/controllers/api/accounts.ts
@@ -14,6 +14,8 @@ import { AccountModel } from '../../models/account/account'
14import { VideoModel } from '../../models/video/video' 14import { VideoModel } from '../../models/video/video'
15import { buildNSFWFilter, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils' 15import { buildNSFWFilter, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
16import { VideoChannelModel } from '../../models/video/video-channel' 16import { VideoChannelModel } from '../../models/video/video-channel'
17import { JobQueue } from '../../lib/job-queue'
18import { logger } from '../../helpers/logger'
17 19
18const accountsRouter = express.Router() 20const accountsRouter = express.Router()
19 21
@@ -57,6 +59,11 @@ export {
57function getAccount (req: express.Request, res: express.Response, next: express.NextFunction) { 59function getAccount (req: express.Request, res: express.Response, next: express.NextFunction) {
58 const account: AccountModel = res.locals.account 60 const account: AccountModel = res.locals.account
59 61
62 if (account.isOutdated()) {
63 JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'actor', url: account.Actor.url } })
64 .catch(err => logger.error('Cannot create AP refresher job for actor %s.', account.Actor.url, { err }))
65 }
66
60 return res.json(account.toFormattedJSON()) 67 return res.json(account.toFormattedJSON())
61} 68}
62 69
@@ -74,10 +81,10 @@ async function listVideoAccountChannels (req: express.Request, res: express.Resp
74 81
75async function listAccountVideos (req: express.Request, res: express.Response, next: express.NextFunction) { 82async function listAccountVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
76 const account: AccountModel = res.locals.account 83 const account: AccountModel = res.locals.account
77 const actorId = isUserAbleToSearchRemoteURI(res) ? null : undefined 84 const followerActorId = isUserAbleToSearchRemoteURI(res) ? null : undefined
78 85
79 const resultList = await VideoModel.listForApi({ 86 const resultList = await VideoModel.listForApi({
80 actorId, 87 followerActorId,
81 start: req.query.start, 88 start: req.query.start,
82 count: req.query.count, 89 count: req.query.count,
83 sort: req.query.sort, 90 sort: req.query.sort,
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts
index 5233e9f68..255026f46 100644
--- a/server/controllers/api/config.ts
+++ b/server/controllers/api/config.ts
@@ -1,5 +1,5 @@
1import * as express from 'express' 1import * as express from 'express'
2import { omit } from 'lodash' 2import { omit, snakeCase } from 'lodash'
3import { ServerConfig, UserRight } from '../../../shared' 3import { ServerConfig, UserRight } from '../../../shared'
4import { About } from '../../../shared/models/server/about.model' 4import { About } from '../../../shared/models/server/about.model'
5import { CustomConfig } from '../../../shared/models/server/custom-config.model' 5import { CustomConfig } from '../../../shared/models/server/custom-config.model'
@@ -11,6 +11,9 @@ import { ClientHtml } from '../../lib/client-html'
11import { auditLoggerFactory, CustomConfigAuditView, getAuditIdFromRes } from '../../helpers/audit-logger' 11import { auditLoggerFactory, CustomConfigAuditView, getAuditIdFromRes } from '../../helpers/audit-logger'
12import { remove, writeJSON } from 'fs-extra' 12import { remove, writeJSON } from 'fs-extra'
13import { getServerCommit } from '../../helpers/utils' 13import { getServerCommit } from '../../helpers/utils'
14import { Emailer } from '../../lib/emailer'
15import { isNumeric } from 'validator'
16import { objectConverter } from '../../helpers/core-utils'
14 17
15const packageJSON = require('../../../../package.json') 18const packageJSON = require('../../../../package.json')
16const configRouter = express.Router() 19const configRouter = express.Router()
@@ -61,6 +64,12 @@ async function getConfig (req: express.Request, res: express.Response) {
61 css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS 64 css: CONFIG.INSTANCE.CUSTOMIZATIONS.CSS
62 } 65 }
63 }, 66 },
67 email: {
68 enabled: Emailer.isEnabled()
69 },
70 contactForm: {
71 enabled: CONFIG.CONTACT_FORM.ENABLED
72 },
64 serverVersion: packageJSON.version, 73 serverVersion: packageJSON.version,
65 serverCommit, 74 serverCommit,
66 signup: { 75 signup: {
@@ -111,6 +120,11 @@ async function getConfig (req: express.Request, res: express.Response) {
111 user: { 120 user: {
112 videoQuota: CONFIG.USER.VIDEO_QUOTA, 121 videoQuota: CONFIG.USER.VIDEO_QUOTA,
113 videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY 122 videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY
123 },
124 trending: {
125 videos: {
126 intervalDays: CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS
127 }
114 } 128 }
115 } 129 }
116 130
@@ -150,32 +164,10 @@ async function deleteCustomConfig (req: express.Request, res: express.Response,
150} 164}
151 165
152async function updateCustomConfig (req: express.Request, res: express.Response, next: express.NextFunction) { 166async function updateCustomConfig (req: express.Request, res: express.Response, next: express.NextFunction) {
153 const toUpdate: CustomConfig = req.body
154 const oldCustomConfigAuditKeys = new CustomConfigAuditView(customConfig()) 167 const oldCustomConfigAuditKeys = new CustomConfigAuditView(customConfig())
155 168
156 // Force number conversion 169 // camelCase to snake_case key + Force number conversion
157 toUpdate.cache.previews.size = parseInt('' + toUpdate.cache.previews.size, 10) 170 const toUpdateJSON = convertCustomConfigBody(req.body)
158 toUpdate.cache.captions.size = parseInt('' + toUpdate.cache.captions.size, 10)
159 toUpdate.signup.limit = parseInt('' + toUpdate.signup.limit, 10)
160 toUpdate.user.videoQuota = parseInt('' + toUpdate.user.videoQuota, 10)
161 toUpdate.user.videoQuotaDaily = parseInt('' + toUpdate.user.videoQuotaDaily, 10)
162 toUpdate.transcoding.threads = parseInt('' + toUpdate.transcoding.threads, 10)
163
164 // camelCase to snake_case key
165 const toUpdateJSON = omit(
166 toUpdate,
167 'user.videoQuota',
168 'instance.defaultClientRoute',
169 'instance.shortDescription',
170 'cache.videoCaptions',
171 'signup.requiresEmailVerification'
172 )
173 toUpdateJSON.user['video_quota'] = toUpdate.user.videoQuota
174 toUpdateJSON.user['video_quota_daily'] = toUpdate.user.videoQuotaDaily
175 toUpdateJSON.instance['default_client_route'] = toUpdate.instance.defaultClientRoute
176 toUpdateJSON.instance['short_description'] = toUpdate.instance.shortDescription
177 toUpdateJSON.instance['default_nsfw_policy'] = toUpdate.instance.defaultNSFWPolicy
178 toUpdateJSON.signup['requires_email_verification'] = toUpdate.signup.requiresEmailVerification
179 171
180 await writeJSON(CONFIG.CUSTOM_FILE, toUpdateJSON, { spaces: 2 }) 172 await writeJSON(CONFIG.CUSTOM_FILE, toUpdateJSON, { spaces: 2 })
181 173
@@ -237,12 +229,16 @@ function customConfig (): CustomConfig {
237 admin: { 229 admin: {
238 email: CONFIG.ADMIN.EMAIL 230 email: CONFIG.ADMIN.EMAIL
239 }, 231 },
232 contactForm: {
233 enabled: CONFIG.CONTACT_FORM.ENABLED
234 },
240 user: { 235 user: {
241 videoQuota: CONFIG.USER.VIDEO_QUOTA, 236 videoQuota: CONFIG.USER.VIDEO_QUOTA,
242 videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY 237 videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY
243 }, 238 },
244 transcoding: { 239 transcoding: {
245 enabled: CONFIG.TRANSCODING.ENABLED, 240 enabled: CONFIG.TRANSCODING.ENABLED,
241 allowAdditionalExtensions: CONFIG.TRANSCODING.ALLOW_ADDITIONAL_EXTENSIONS,
246 threads: CONFIG.TRANSCODING.THREADS, 242 threads: CONFIG.TRANSCODING.THREADS,
247 resolutions: { 243 resolutions: {
248 '240p': CONFIG.TRANSCODING.RESOLUTIONS[ '240p' ], 244 '240p': CONFIG.TRANSCODING.RESOLUTIONS[ '240p' ],
@@ -264,3 +260,20 @@ function customConfig (): CustomConfig {
264 } 260 }
265 } 261 }
266} 262}
263
264function convertCustomConfigBody (body: CustomConfig) {
265 function keyConverter (k: string) {
266 // Transcoding resolutions exception
267 if (/^\d{3,4}p$/.exec(k)) return k
268
269 return snakeCase(k)
270 }
271
272 function valueConverter (v: any) {
273 if (isNumeric(v + '')) return parseInt('' + v, 10)
274
275 return v
276 }
277
278 return objectConverter(body, keyConverter, valueConverter)
279}
diff --git a/server/controllers/api/server/contact.ts b/server/controllers/api/server/contact.ts
new file mode 100644
index 000000000..b1144c94e
--- /dev/null
+++ b/server/controllers/api/server/contact.ts
@@ -0,0 +1,28 @@
1import * as express from 'express'
2import { asyncMiddleware, contactAdministratorValidator } from '../../../middlewares'
3import { Redis } from '../../../lib/redis'
4import { Emailer } from '../../../lib/emailer'
5import { ContactForm } from '../../../../shared/models/server'
6
7const contactRouter = express.Router()
8
9contactRouter.post('/contact',
10 asyncMiddleware(contactAdministratorValidator),
11 asyncMiddleware(contactAdministrator)
12)
13
14async function contactAdministrator (req: express.Request, res: express.Response) {
15 const data = req.body as ContactForm
16
17 await Emailer.Instance.addContactFormJob(data.fromEmail, data.fromName, data.body)
18
19 await Redis.Instance.setContactFormIp(req.ip)
20
21 return res.status(204).end()
22}
23
24// ---------------------------------------------------------------------------
25
26export {
27 contactRouter
28}
diff --git a/server/controllers/api/server/index.ts b/server/controllers/api/server/index.ts
index c08192a8c..814248e5f 100644
--- a/server/controllers/api/server/index.ts
+++ b/server/controllers/api/server/index.ts
@@ -3,6 +3,7 @@ import { serverFollowsRouter } from './follows'
3import { statsRouter } from './stats' 3import { statsRouter } from './stats'
4import { serverRedundancyRouter } from './redundancy' 4import { serverRedundancyRouter } from './redundancy'
5import { serverBlocklistRouter } from './server-blocklist' 5import { serverBlocklistRouter } from './server-blocklist'
6import { contactRouter } from './contact'
6 7
7const serverRouter = express.Router() 8const serverRouter = express.Router()
8 9
@@ -10,6 +11,7 @@ serverRouter.use('/', serverFollowsRouter)
10serverRouter.use('/', serverRedundancyRouter) 11serverRouter.use('/', serverRedundancyRouter)
11serverRouter.use('/', statsRouter) 12serverRouter.use('/', statsRouter)
12serverRouter.use('/', serverBlocklistRouter) 13serverRouter.use('/', serverBlocklistRouter)
14serverRouter.use('/', contactRouter)
13 15
14// --------------------------------------------------------------------------- 16// ---------------------------------------------------------------------------
15 17
diff --git a/server/controllers/api/server/stats.ts b/server/controllers/api/server/stats.ts
index 85803f69e..89ffd1717 100644
--- a/server/controllers/api/server/stats.ts
+++ b/server/controllers/api/server/stats.ts
@@ -8,6 +8,7 @@ import { VideoCommentModel } from '../../../models/video/video-comment'
8import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy' 8import { VideoRedundancyModel } from '../../../models/redundancy/video-redundancy'
9import { CONFIG, ROUTE_CACHE_LIFETIME } from '../../../initializers/constants' 9import { CONFIG, ROUTE_CACHE_LIFETIME } from '../../../initializers/constants'
10import { cacheRoute } from '../../../middlewares/cache' 10import { cacheRoute } from '../../../middlewares/cache'
11import { VideoFileModel } from '../../../models/video/video-file'
11 12
12const statsRouter = express.Router() 13const statsRouter = express.Router()
13 14
@@ -16,11 +17,12 @@ statsRouter.get('/stats',
16 asyncMiddleware(getStats) 17 asyncMiddleware(getStats)
17) 18)
18 19
19async function getStats (req: express.Request, res: express.Response, next: express.NextFunction) { 20async function getStats (req: express.Request, res: express.Response) {
20 const { totalLocalVideos, totalLocalVideoViews, totalVideos } = await VideoModel.getStats() 21 const { totalLocalVideos, totalLocalVideoViews, totalVideos } = await VideoModel.getStats()
21 const { totalLocalVideoComments, totalVideoComments } = await VideoCommentModel.getStats() 22 const { totalLocalVideoComments, totalVideoComments } = await VideoCommentModel.getStats()
22 const { totalUsers } = await UserModel.getStats() 23 const { totalUsers } = await UserModel.getStats()
23 const { totalInstanceFollowers, totalInstanceFollowing } = await ActorFollowModel.getStats() 24 const { totalInstanceFollowers, totalInstanceFollowing } = await ActorFollowModel.getStats()
25 const { totalLocalVideoFilesSize } = await VideoFileModel.getStats()
24 26
25 const videosRedundancyStats = await Promise.all( 27 const videosRedundancyStats = await Promise.all(
26 CONFIG.REDUNDANCY.VIDEOS.STRATEGIES.map(r => { 28 CONFIG.REDUNDANCY.VIDEOS.STRATEGIES.map(r => {
@@ -32,8 +34,9 @@ async function getStats (req: express.Request, res: express.Response, next: expr
32 const data: ServerStats = { 34 const data: ServerStats = {
33 totalLocalVideos, 35 totalLocalVideos,
34 totalLocalVideoViews, 36 totalLocalVideoViews,
35 totalVideos, 37 totalLocalVideoFilesSize,
36 totalLocalVideoComments, 38 totalLocalVideoComments,
39 totalVideos,
37 totalVideoComments, 40 totalVideoComments,
38 totalUsers, 41 totalUsers,
39 totalInstanceFollowers, 42 totalInstanceFollowers,
diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts
index 87fab4a40..dbe0718d4 100644
--- a/server/controllers/api/users/index.ts
+++ b/server/controllers/api/users/index.ts
@@ -38,6 +38,10 @@ import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../h
38import { meRouter } from './me' 38import { meRouter } from './me'
39import { deleteUserToken } from '../../../lib/oauth-model' 39import { deleteUserToken } from '../../../lib/oauth-model'
40import { myBlocklistRouter } from './my-blocklist' 40import { myBlocklistRouter } from './my-blocklist'
41import { myVideosHistoryRouter } from './my-history'
42import { myNotificationsRouter } from './my-notifications'
43import { Notifier } from '../../../lib/notifier'
44import { mySubscriptionsRouter } from './my-subscriptions'
41 45
42const auditLogger = auditLoggerFactory('users') 46const auditLogger = auditLoggerFactory('users')
43 47
@@ -54,7 +58,10 @@ const askSendEmailLimiter = new RateLimit({
54}) 58})
55 59
56const usersRouter = express.Router() 60const usersRouter = express.Router()
61usersRouter.use('/', myNotificationsRouter)
62usersRouter.use('/', mySubscriptionsRouter)
57usersRouter.use('/', myBlocklistRouter) 63usersRouter.use('/', myBlocklistRouter)
64usersRouter.use('/', myVideosHistoryRouter)
58usersRouter.use('/', meRouter) 65usersRouter.use('/', meRouter)
59 66
60usersRouter.get('/autocomplete', 67usersRouter.get('/autocomplete',
@@ -209,6 +216,8 @@ async function registerUser (req: express.Request, res: express.Response) {
209 await sendVerifyUserEmail(user) 216 await sendVerifyUserEmail(user)
210 } 217 }
211 218
219 Notifier.Instance.notifyOnNewUserRegistration(user)
220
212 return res.type('json').status(204).end() 221 return res.type('json').status(204).end()
213} 222}
214 223
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts
index 82299747d..94a2b8732 100644
--- a/server/controllers/api/users/me.ts
+++ b/server/controllers/api/users/me.ts
@@ -2,47 +2,34 @@ import * as express from 'express'
2import 'multer' 2import 'multer'
3import { UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../../shared' 3import { UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../../shared'
4import { getFormattedObjects } from '../../../helpers/utils' 4import { getFormattedObjects } from '../../../helpers/utils'
5import { CONFIG, IMAGE_MIMETYPE_EXT, sequelizeTypescript } from '../../../initializers' 5import { CONFIG, MIMETYPES, sequelizeTypescript } from '../../../initializers'
6import { sendUpdateActor } from '../../../lib/activitypub/send' 6import { sendUpdateActor } from '../../../lib/activitypub/send'
7import { 7import {
8 asyncMiddleware, 8 asyncMiddleware,
9 asyncRetryTransactionMiddleware, 9 asyncRetryTransactionMiddleware,
10 authenticate, 10 authenticate,
11 commonVideosFiltersValidator,
12 paginationValidator, 11 paginationValidator,
13 setDefaultPagination, 12 setDefaultPagination,
14 setDefaultSort, 13 setDefaultSort,
15 userSubscriptionAddValidator,
16 userSubscriptionGetValidator,
17 usersUpdateMeValidator, 14 usersUpdateMeValidator,
18 usersVideoRatingValidator 15 usersVideoRatingValidator
19} from '../../../middlewares' 16} from '../../../middlewares'
20import { 17import { deleteMeValidator, videoImportsSortValidator, videosSortValidator } from '../../../middlewares/validators'
21 areSubscriptionsExistValidator,
22 deleteMeValidator,
23 userSubscriptionsSortValidator,
24 videoImportsSortValidator,
25 videosSortValidator
26} from '../../../middlewares/validators'
27import { AccountVideoRateModel } from '../../../models/account/account-video-rate' 18import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
28import { UserModel } from '../../../models/account/user' 19import { UserModel } from '../../../models/account/user'
29import { VideoModel } from '../../../models/video/video' 20import { VideoModel } from '../../../models/video/video'
30import { VideoSortField } from '../../../../client/src/app/shared/video/sort-field.type' 21import { VideoSortField } from '../../../../client/src/app/shared/video/sort-field.type'
31import { buildNSFWFilter, createReqFiles } from '../../../helpers/express-utils' 22import { createReqFiles } from '../../../helpers/express-utils'
32import { UserVideoQuota } from '../../../../shared/models/users/user-video-quota.model' 23import { UserVideoQuota } from '../../../../shared/models/users/user-video-quota.model'
33import { updateAvatarValidator } from '../../../middlewares/validators/avatar' 24import { updateAvatarValidator } from '../../../middlewares/validators/avatar'
34import { updateActorAvatarFile } from '../../../lib/avatar' 25import { updateActorAvatarFile } from '../../../lib/avatar'
35import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../helpers/audit-logger' 26import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../helpers/audit-logger'
36import { VideoImportModel } from '../../../models/video/video-import' 27import { VideoImportModel } from '../../../models/video/video-import'
37import { VideoFilter } from '../../../../shared/models/videos/video-query.type'
38import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
39import { JobQueue } from '../../../lib/job-queue'
40import { logger } from '../../../helpers/logger'
41import { AccountModel } from '../../../models/account/account' 28import { AccountModel } from '../../../models/account/account'
42 29
43const auditLogger = auditLoggerFactory('users-me') 30const auditLogger = auditLoggerFactory('users-me')
44 31
45const reqAvatarFile = createReqFiles([ 'avatarfile' ], IMAGE_MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.AVATARS_DIR }) 32const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR })
46 33
47const meRouter = express.Router() 34const meRouter = express.Router()
48 35
@@ -98,51 +85,6 @@ meRouter.post('/me/avatar/pick',
98 asyncRetryTransactionMiddleware(updateMyAvatar) 85 asyncRetryTransactionMiddleware(updateMyAvatar)
99) 86)
100 87
101// ##### Subscriptions part #####
102
103meRouter.get('/me/subscriptions/videos',
104 authenticate,
105 paginationValidator,
106 videosSortValidator,
107 setDefaultSort,
108 setDefaultPagination,
109 commonVideosFiltersValidator,
110 asyncMiddleware(getUserSubscriptionVideos)
111)
112
113meRouter.get('/me/subscriptions/exist',
114 authenticate,
115 areSubscriptionsExistValidator,
116 asyncMiddleware(areSubscriptionsExist)
117)
118
119meRouter.get('/me/subscriptions',
120 authenticate,
121 paginationValidator,
122 userSubscriptionsSortValidator,
123 setDefaultSort,
124 setDefaultPagination,
125 asyncMiddleware(getUserSubscriptions)
126)
127
128meRouter.post('/me/subscriptions',
129 authenticate,
130 userSubscriptionAddValidator,
131 asyncMiddleware(addUserSubscription)
132)
133
134meRouter.get('/me/subscriptions/:uri',
135 authenticate,
136 userSubscriptionGetValidator,
137 getUserSubscription
138)
139
140meRouter.delete('/me/subscriptions/:uri',
141 authenticate,
142 userSubscriptionGetValidator,
143 asyncRetryTransactionMiddleware(deleteUserSubscription)
144)
145
146// --------------------------------------------------------------------------- 88// ---------------------------------------------------------------------------
147 89
148export { 90export {
@@ -151,100 +93,6 @@ export {
151 93
152// --------------------------------------------------------------------------- 94// ---------------------------------------------------------------------------
153 95
154async function areSubscriptionsExist (req: express.Request, res: express.Response) {
155 const uris = req.query.uris as string[]
156 const user = res.locals.oauth.token.User as UserModel
157
158 const handles = uris.map(u => {
159 let [ name, host ] = u.split('@')
160 if (host === CONFIG.WEBSERVER.HOST) host = null
161
162 return { name, host, uri: u }
163 })
164
165 const results = await ActorFollowModel.listSubscribedIn(user.Account.Actor.id, handles)
166
167 const existObject: { [id: string ]: boolean } = {}
168 for (const handle of handles) {
169 const obj = results.find(r => {
170 const server = r.ActorFollowing.Server
171
172 return r.ActorFollowing.preferredUsername === handle.name &&
173 (
174 (!server && !handle.host) ||
175 (server.host === handle.host)
176 )
177 })
178
179 existObject[handle.uri] = obj !== undefined
180 }
181
182 return res.json(existObject)
183}
184
185async function addUserSubscription (req: express.Request, res: express.Response) {
186 const user = res.locals.oauth.token.User as UserModel
187 const [ name, host ] = req.body.uri.split('@')
188
189 const payload = {
190 name,
191 host,
192 followerActorId: user.Account.Actor.id
193 }
194
195 JobQueue.Instance.createJob({ type: 'activitypub-follow', payload })
196 .catch(err => logger.error('Cannot create follow job for subscription %s.', req.body.uri, err))
197
198 return res.status(204).end()
199}
200
201function getUserSubscription (req: express.Request, res: express.Response) {
202 const subscription: ActorFollowModel = res.locals.subscription
203
204 return res.json(subscription.ActorFollowing.VideoChannel.toFormattedJSON())
205}
206
207async function deleteUserSubscription (req: express.Request, res: express.Response) {
208 const subscription: ActorFollowModel = res.locals.subscription
209
210 await sequelizeTypescript.transaction(async t => {
211 return subscription.destroy({ transaction: t })
212 })
213
214 return res.type('json').status(204).end()
215}
216
217async function getUserSubscriptions (req: express.Request, res: express.Response) {
218 const user = res.locals.oauth.token.User as UserModel
219 const actorId = user.Account.Actor.id
220
221 const resultList = await ActorFollowModel.listSubscriptionsForApi(actorId, req.query.start, req.query.count, req.query.sort)
222
223 return res.json(getFormattedObjects(resultList.data, resultList.total))
224}
225
226async function getUserSubscriptionVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
227 const user = res.locals.oauth.token.User as UserModel
228 const resultList = await VideoModel.listForApi({
229 start: req.query.start,
230 count: req.query.count,
231 sort: req.query.sort,
232 includeLocalVideos: false,
233 categoryOneOf: req.query.categoryOneOf,
234 licenceOneOf: req.query.licenceOneOf,
235 languageOneOf: req.query.languageOneOf,
236 tagsOneOf: req.query.tagsOneOf,
237 tagsAllOf: req.query.tagsAllOf,
238 nsfw: buildNSFWFilter(res, req.query.nsfw),
239 filter: req.query.filter as VideoFilter,
240 withFiles: false,
241 actorId: user.Account.Actor.id,
242 user
243 })
244
245 return res.json(getFormattedObjects(resultList.data, resultList.total))
246}
247
248async function getUserVideos (req: express.Request, res: express.Response, next: express.NextFunction) { 96async function getUserVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
249 const user = res.locals.oauth.token.User as UserModel 97 const user = res.locals.oauth.token.User as UserModel
250 const resultList = await VideoModel.listUserVideosForApi( 98 const resultList = await VideoModel.listUserVideosForApi(
@@ -330,6 +178,7 @@ async function updateMe (req: express.Request, res: express.Response, next: expr
330 if (body.nsfwPolicy !== undefined) user.nsfwPolicy = body.nsfwPolicy 178 if (body.nsfwPolicy !== undefined) user.nsfwPolicy = body.nsfwPolicy
331 if (body.webTorrentEnabled !== undefined) user.webTorrentEnabled = body.webTorrentEnabled 179 if (body.webTorrentEnabled !== undefined) user.webTorrentEnabled = body.webTorrentEnabled
332 if (body.autoPlayVideo !== undefined) user.autoPlayVideo = body.autoPlayVideo 180 if (body.autoPlayVideo !== undefined) user.autoPlayVideo = body.autoPlayVideo
181 if (body.videosHistoryEnabled !== undefined) user.videosHistoryEnabled = body.videosHistoryEnabled
333 182
334 await sequelizeTypescript.transaction(async t => { 183 await sequelizeTypescript.transaction(async t => {
335 const userAccount = await AccountModel.load(user.Account.id) 184 const userAccount = await AccountModel.load(user.Account.id)
@@ -348,7 +197,7 @@ async function updateMe (req: express.Request, res: express.Response, next: expr
348 return res.sendStatus(204) 197 return res.sendStatus(204)
349} 198}
350 199
351async function updateMyAvatar (req: express.Request, res: express.Response, next: express.NextFunction) { 200async function updateMyAvatar (req: express.Request, res: express.Response) {
352 const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ] 201 const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ]
353 const user: UserModel = res.locals.oauth.token.user 202 const user: UserModel = res.locals.oauth.token.user
354 const oldUserAuditView = new UserAuditView(user.toFormattedJSON()) 203 const oldUserAuditView = new UserAuditView(user.toFormattedJSON())
diff --git a/server/controllers/api/users/my-history.ts b/server/controllers/api/users/my-history.ts
new file mode 100644
index 000000000..6cd782c47
--- /dev/null
+++ b/server/controllers/api/users/my-history.ts
@@ -0,0 +1,57 @@
1import * as express from 'express'
2import {
3 asyncMiddleware,
4 asyncRetryTransactionMiddleware,
5 authenticate,
6 paginationValidator,
7 setDefaultPagination,
8 userHistoryRemoveValidator
9} from '../../../middlewares'
10import { UserModel } from '../../../models/account/user'
11import { getFormattedObjects } from '../../../helpers/utils'
12import { UserVideoHistoryModel } from '../../../models/account/user-video-history'
13import { sequelizeTypescript } from '../../../initializers'
14
15const myVideosHistoryRouter = express.Router()
16
17myVideosHistoryRouter.get('/me/history/videos',
18 authenticate,
19 paginationValidator,
20 setDefaultPagination,
21 asyncMiddleware(listMyVideosHistory)
22)
23
24myVideosHistoryRouter.post('/me/history/videos/remove',
25 authenticate,
26 userHistoryRemoveValidator,
27 asyncRetryTransactionMiddleware(removeUserHistory)
28)
29
30// ---------------------------------------------------------------------------
31
32export {
33 myVideosHistoryRouter
34}
35
36// ---------------------------------------------------------------------------
37
38async function listMyVideosHistory (req: express.Request, res: express.Response) {
39 const user: UserModel = res.locals.oauth.token.User
40
41 const resultList = await UserVideoHistoryModel.listForApi(user, req.query.start, req.query.count)
42
43 return res.json(getFormattedObjects(resultList.data, resultList.total))
44}
45
46async function removeUserHistory (req: express.Request, res: express.Response) {
47 const user: UserModel = res.locals.oauth.token.User
48 const beforeDate = req.body.beforeDate || null
49
50 await sequelizeTypescript.transaction(t => {
51 return UserVideoHistoryModel.removeHistoryBefore(user, beforeDate, t)
52 })
53
54 // Do not send the delete to other instances, we delete OUR copy of this video abuse
55
56 return res.type('json').status(204).end()
57}
diff --git a/server/controllers/api/users/my-notifications.ts b/server/controllers/api/users/my-notifications.ts
new file mode 100644
index 000000000..76cf97587
--- /dev/null
+++ b/server/controllers/api/users/my-notifications.ts
@@ -0,0 +1,108 @@
1import * as express from 'express'
2import 'multer'
3import {
4 asyncMiddleware,
5 asyncRetryTransactionMiddleware,
6 authenticate,
7 paginationValidator,
8 setDefaultPagination,
9 setDefaultSort,
10 userNotificationsSortValidator
11} from '../../../middlewares'
12import { UserModel } from '../../../models/account/user'
13import { getFormattedObjects } from '../../../helpers/utils'
14import { UserNotificationModel } from '../../../models/account/user-notification'
15import { meRouter } from './me'
16import {
17 listUserNotificationsValidator,
18 markAsReadUserNotificationsValidator,
19 updateNotificationSettingsValidator
20} from '../../../middlewares/validators/user-notifications'
21import { UserNotificationSetting } from '../../../../shared/models/users'
22import { UserNotificationSettingModel } from '../../../models/account/user-notification-setting'
23
24const myNotificationsRouter = express.Router()
25
26meRouter.put('/me/notification-settings',
27 authenticate,
28 updateNotificationSettingsValidator,
29 asyncRetryTransactionMiddleware(updateNotificationSettings)
30)
31
32myNotificationsRouter.get('/me/notifications',
33 authenticate,
34 paginationValidator,
35 userNotificationsSortValidator,
36 setDefaultSort,
37 setDefaultPagination,
38 listUserNotificationsValidator,
39 asyncMiddleware(listUserNotifications)
40)
41
42myNotificationsRouter.post('/me/notifications/read',
43 authenticate,
44 markAsReadUserNotificationsValidator,
45 asyncMiddleware(markAsReadUserNotifications)
46)
47
48myNotificationsRouter.post('/me/notifications/read-all',
49 authenticate,
50 asyncMiddleware(markAsReadAllUserNotifications)
51)
52
53export {
54 myNotificationsRouter
55}
56
57// ---------------------------------------------------------------------------
58
59async function updateNotificationSettings (req: express.Request, res: express.Response) {
60 const user: UserModel = res.locals.oauth.token.User
61 const body = req.body
62
63 const query = {
64 where: {
65 userId: user.id
66 }
67 }
68
69 const values: UserNotificationSetting = {
70 newVideoFromSubscription: body.newVideoFromSubscription,
71 newCommentOnMyVideo: body.newCommentOnMyVideo,
72 videoAbuseAsModerator: body.videoAbuseAsModerator,
73 blacklistOnMyVideo: body.blacklistOnMyVideo,
74 myVideoPublished: body.myVideoPublished,
75 myVideoImportFinished: body.myVideoImportFinished,
76 newFollow: body.newFollow,
77 newUserRegistration: body.newUserRegistration,
78 commentMention: body.commentMention
79 }
80
81 await UserNotificationSettingModel.update(values, query)
82
83 return res.status(204).end()
84}
85
86async function listUserNotifications (req: express.Request, res: express.Response) {
87 const user: UserModel = res.locals.oauth.token.User
88
89 const resultList = await UserNotificationModel.listForApi(user.id, req.query.start, req.query.count, req.query.sort, req.query.unread)
90
91 return res.json(getFormattedObjects(resultList.data, resultList.total))
92}
93
94async function markAsReadUserNotifications (req: express.Request, res: express.Response) {
95 const user: UserModel = res.locals.oauth.token.User
96
97 await UserNotificationModel.markAsRead(user.id, req.body.ids)
98
99 return res.status(204).end()
100}
101
102async function markAsReadAllUserNotifications (req: express.Request, res: express.Response) {
103 const user: UserModel = res.locals.oauth.token.User
104
105 await UserNotificationModel.markAllAsRead(user.id)
106
107 return res.status(204).end()
108}
diff --git a/server/controllers/api/users/my-subscriptions.ts b/server/controllers/api/users/my-subscriptions.ts
new file mode 100644
index 000000000..accca6d52
--- /dev/null
+++ b/server/controllers/api/users/my-subscriptions.ts
@@ -0,0 +1,170 @@
1import * as express from 'express'
2import 'multer'
3import { getFormattedObjects } from '../../../helpers/utils'
4import { CONFIG, sequelizeTypescript } from '../../../initializers'
5import {
6 asyncMiddleware,
7 asyncRetryTransactionMiddleware,
8 authenticate,
9 commonVideosFiltersValidator,
10 paginationValidator,
11 setDefaultPagination,
12 setDefaultSort,
13 userSubscriptionAddValidator,
14 userSubscriptionGetValidator
15} from '../../../middlewares'
16import { areSubscriptionsExistValidator, userSubscriptionsSortValidator, videosSortValidator } from '../../../middlewares/validators'
17import { UserModel } from '../../../models/account/user'
18import { VideoModel } from '../../../models/video/video'
19import { buildNSFWFilter } from '../../../helpers/express-utils'
20import { VideoFilter } from '../../../../shared/models/videos/video-query.type'
21import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
22import { JobQueue } from '../../../lib/job-queue'
23import { logger } from '../../../helpers/logger'
24
25const mySubscriptionsRouter = express.Router()
26
27mySubscriptionsRouter.get('/me/subscriptions/videos',
28 authenticate,
29 paginationValidator,
30 videosSortValidator,
31 setDefaultSort,
32 setDefaultPagination,
33 commonVideosFiltersValidator,
34 asyncMiddleware(getUserSubscriptionVideos)
35)
36
37mySubscriptionsRouter.get('/me/subscriptions/exist',
38 authenticate,
39 areSubscriptionsExistValidator,
40 asyncMiddleware(areSubscriptionsExist)
41)
42
43mySubscriptionsRouter.get('/me/subscriptions',
44 authenticate,
45 paginationValidator,
46 userSubscriptionsSortValidator,
47 setDefaultSort,
48 setDefaultPagination,
49 asyncMiddleware(getUserSubscriptions)
50)
51
52mySubscriptionsRouter.post('/me/subscriptions',
53 authenticate,
54 userSubscriptionAddValidator,
55 asyncMiddleware(addUserSubscription)
56)
57
58mySubscriptionsRouter.get('/me/subscriptions/:uri',
59 authenticate,
60 userSubscriptionGetValidator,
61 getUserSubscription
62)
63
64mySubscriptionsRouter.delete('/me/subscriptions/:uri',
65 authenticate,
66 userSubscriptionGetValidator,
67 asyncRetryTransactionMiddleware(deleteUserSubscription)
68)
69
70// ---------------------------------------------------------------------------
71
72export {
73 mySubscriptionsRouter
74}
75
76// ---------------------------------------------------------------------------
77
78async function areSubscriptionsExist (req: express.Request, res: express.Response) {
79 const uris = req.query.uris as string[]
80 const user = res.locals.oauth.token.User as UserModel
81
82 const handles = uris.map(u => {
83 let [ name, host ] = u.split('@')
84 if (host === CONFIG.WEBSERVER.HOST) host = null
85
86 return { name, host, uri: u }
87 })
88
89 const results = await ActorFollowModel.listSubscribedIn(user.Account.Actor.id, handles)
90
91 const existObject: { [id: string ]: boolean } = {}
92 for (const handle of handles) {
93 const obj = results.find(r => {
94 const server = r.ActorFollowing.Server
95
96 return r.ActorFollowing.preferredUsername === handle.name &&
97 (
98 (!server && !handle.host) ||
99 (server.host === handle.host)
100 )
101 })
102
103 existObject[handle.uri] = obj !== undefined
104 }
105
106 return res.json(existObject)
107}
108
109async function addUserSubscription (req: express.Request, res: express.Response) {
110 const user = res.locals.oauth.token.User as UserModel
111 const [ name, host ] = req.body.uri.split('@')
112
113 const payload = {
114 name,
115 host,
116 followerActorId: user.Account.Actor.id
117 }
118
119 JobQueue.Instance.createJob({ type: 'activitypub-follow', payload })
120 .catch(err => logger.error('Cannot create follow job for subscription %s.', req.body.uri, err))
121
122 return res.status(204).end()
123}
124
125function getUserSubscription (req: express.Request, res: express.Response) {
126 const subscription: ActorFollowModel = res.locals.subscription
127
128 return res.json(subscription.ActorFollowing.VideoChannel.toFormattedJSON())
129}
130
131async function deleteUserSubscription (req: express.Request, res: express.Response) {
132 const subscription: ActorFollowModel = res.locals.subscription
133
134 await sequelizeTypescript.transaction(async t => {
135 return subscription.destroy({ transaction: t })
136 })
137
138 return res.type('json').status(204).end()
139}
140
141async function getUserSubscriptions (req: express.Request, res: express.Response) {
142 const user = res.locals.oauth.token.User as UserModel
143 const actorId = user.Account.Actor.id
144
145 const resultList = await ActorFollowModel.listSubscriptionsForApi(actorId, req.query.start, req.query.count, req.query.sort)
146
147 return res.json(getFormattedObjects(resultList.data, resultList.total))
148}
149
150async function getUserSubscriptionVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
151 const user = res.locals.oauth.token.User as UserModel
152 const resultList = await VideoModel.listForApi({
153 start: req.query.start,
154 count: req.query.count,
155 sort: req.query.sort,
156 includeLocalVideos: false,
157 categoryOneOf: req.query.categoryOneOf,
158 licenceOneOf: req.query.licenceOneOf,
159 languageOneOf: req.query.languageOneOf,
160 tagsOneOf: req.query.tagsOneOf,
161 tagsAllOf: req.query.tagsAllOf,
162 nsfw: buildNSFWFilter(res, req.query.nsfw),
163 filter: req.query.filter as VideoFilter,
164 withFiles: false,
165 followerActorId: user.Account.Actor.id,
166 user
167 })
168
169 return res.json(getFormattedObjects(resultList.data, resultList.total))
170}
diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts
index 9bf3c5fd8..db7602139 100644
--- a/server/controllers/api/video-channel.ts
+++ b/server/controllers/api/video-channel.ts
@@ -22,7 +22,7 @@ import { createVideoChannel } from '../../lib/video-channel'
22import { buildNSFWFilter, createReqFiles, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils' 22import { buildNSFWFilter, createReqFiles, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
23import { setAsyncActorKeys } from '../../lib/activitypub' 23import { setAsyncActorKeys } from '../../lib/activitypub'
24import { AccountModel } from '../../models/account/account' 24import { AccountModel } from '../../models/account/account'
25import { CONFIG, IMAGE_MIMETYPE_EXT, sequelizeTypescript } from '../../initializers' 25import { CONFIG, MIMETYPES, sequelizeTypescript } from '../../initializers'
26import { logger } from '../../helpers/logger' 26import { logger } from '../../helpers/logger'
27import { VideoModel } from '../../models/video/video' 27import { VideoModel } from '../../models/video/video'
28import { updateAvatarValidator } from '../../middlewares/validators/avatar' 28import { updateAvatarValidator } from '../../middlewares/validators/avatar'
@@ -30,9 +30,10 @@ import { updateActorAvatarFile } from '../../lib/avatar'
30import { auditLoggerFactory, getAuditIdFromRes, VideoChannelAuditView } from '../../helpers/audit-logger' 30import { auditLoggerFactory, getAuditIdFromRes, VideoChannelAuditView } from '../../helpers/audit-logger'
31import { resetSequelizeInstance } from '../../helpers/database-utils' 31import { resetSequelizeInstance } from '../../helpers/database-utils'
32import { UserModel } from '../../models/account/user' 32import { UserModel } from '../../models/account/user'
33import { JobQueue } from '../../lib/job-queue'
33 34
34const auditLogger = auditLoggerFactory('channels') 35const auditLogger = auditLoggerFactory('channels')
35const reqAvatarFile = createReqFiles([ 'avatarfile' ], IMAGE_MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.AVATARS_DIR }) 36const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR })
36 37
37const videoChannelRouter = express.Router() 38const videoChannelRouter = express.Router()
38 39
@@ -197,15 +198,20 @@ async function removeVideoChannel (req: express.Request, res: express.Response)
197async function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) { 198async function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) {
198 const videoChannelWithVideos = await VideoChannelModel.loadAndPopulateAccountAndVideos(res.locals.videoChannel.id) 199 const videoChannelWithVideos = await VideoChannelModel.loadAndPopulateAccountAndVideos(res.locals.videoChannel.id)
199 200
201 if (videoChannelWithVideos.isOutdated()) {
202 JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'actor', url: videoChannelWithVideos.Actor.url } })
203 .catch(err => logger.error('Cannot create AP refresher job for actor %s.', videoChannelWithVideos.Actor.url, { err }))
204 }
205
200 return res.json(videoChannelWithVideos.toFormattedJSON()) 206 return res.json(videoChannelWithVideos.toFormattedJSON())
201} 207}
202 208
203async function listVideoChannelVideos (req: express.Request, res: express.Response, next: express.NextFunction) { 209async function listVideoChannelVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
204 const videoChannelInstance: VideoChannelModel = res.locals.videoChannel 210 const videoChannelInstance: VideoChannelModel = res.locals.videoChannel
205 const actorId = isUserAbleToSearchRemoteURI(res) ? null : undefined 211 const followerActorId = isUserAbleToSearchRemoteURI(res) ? null : undefined
206 212
207 const resultList = await VideoModel.listForApi({ 213 const resultList = await VideoModel.listForApi({
208 actorId, 214 followerActorId,
209 start: req.query.start, 215 start: req.query.start,
210 count: req.query.count, 216 count: req.query.count,
211 sort: req.query.sort, 217 sort: req.query.sort,
diff --git a/server/controllers/api/videos/abuse.ts b/server/controllers/api/videos/abuse.ts
index d0c81804b..fe0a95cd5 100644
--- a/server/controllers/api/videos/abuse.ts
+++ b/server/controllers/api/videos/abuse.ts
@@ -22,6 +22,7 @@ import { VideoModel } from '../../../models/video/video'
22import { VideoAbuseModel } from '../../../models/video/video-abuse' 22import { VideoAbuseModel } from '../../../models/video/video-abuse'
23import { auditLoggerFactory, VideoAbuseAuditView } from '../../../helpers/audit-logger' 23import { auditLoggerFactory, VideoAbuseAuditView } from '../../../helpers/audit-logger'
24import { UserModel } from '../../../models/account/user' 24import { UserModel } from '../../../models/account/user'
25import { Notifier } from '../../../lib/notifier'
25 26
26const auditLogger = auditLoggerFactory('abuse') 27const auditLogger = auditLoggerFactory('abuse')
27const abuseVideoRouter = express.Router() 28const abuseVideoRouter = express.Router()
@@ -117,6 +118,8 @@ async function reportVideoAbuse (req: express.Request, res: express.Response) {
117 await sendVideoAbuse(reporterAccount.Actor, videoAbuseInstance, videoInstance) 118 await sendVideoAbuse(reporterAccount.Actor, videoAbuseInstance, videoInstance)
118 } 119 }
119 120
121 Notifier.Instance.notifyOnNewVideoAbuse(videoAbuseInstance)
122
120 auditLogger.create(reporterAccount.Actor.getIdentifier(), new VideoAbuseAuditView(videoAbuseInstance.toFormattedJSON())) 123 auditLogger.create(reporterAccount.Actor.getIdentifier(), new VideoAbuseAuditView(videoAbuseInstance.toFormattedJSON()))
121 124
122 return videoAbuseInstance 125 return videoAbuseInstance
diff --git a/server/controllers/api/videos/blacklist.ts b/server/controllers/api/videos/blacklist.ts
index 7f803c8e9..43b0516e7 100644
--- a/server/controllers/api/videos/blacklist.ts
+++ b/server/controllers/api/videos/blacklist.ts
@@ -16,6 +16,10 @@ import {
16} from '../../../middlewares' 16} from '../../../middlewares'
17import { VideoBlacklistModel } from '../../../models/video/video-blacklist' 17import { VideoBlacklistModel } from '../../../models/video/video-blacklist'
18import { sequelizeTypescript } from '../../../initializers' 18import { sequelizeTypescript } from '../../../initializers'
19import { Notifier } from '../../../lib/notifier'
20import { VideoModel } from '../../../models/video/video'
21import { sendCreateVideo, sendDeleteVideo, sendUpdateVideo } from '../../../lib/activitypub/send'
22import { federateVideoIfNeeded } from '../../../lib/activitypub'
19 23
20const blacklistRouter = express.Router() 24const blacklistRouter = express.Router()
21 25
@@ -64,16 +68,26 @@ async function addVideoToBlacklist (req: express.Request, res: express.Response)
64 68
65 const toCreate = { 69 const toCreate = {
66 videoId: videoInstance.id, 70 videoId: videoInstance.id,
71 unfederated: body.unfederate === true,
67 reason: body.reason 72 reason: body.reason
68 } 73 }
69 74
70 await VideoBlacklistModel.create(toCreate) 75 const blacklist = await VideoBlacklistModel.create(toCreate)
76 blacklist.Video = videoInstance
77
78 if (body.unfederate === true) {
79 await sendDeleteVideo(videoInstance, undefined)
80 }
81
82 Notifier.Instance.notifyOnVideoBlacklist(blacklist)
83
84 logger.info('Video %s blacklisted.', res.locals.video.uuid)
85
71 return res.type('json').status(204).end() 86 return res.type('json').status(204).end()
72} 87}
73 88
74async function updateVideoBlacklistController (req: express.Request, res: express.Response) { 89async function updateVideoBlacklistController (req: express.Request, res: express.Response) {
75 const videoBlacklist = res.locals.videoBlacklist as VideoBlacklistModel 90 const videoBlacklist = res.locals.videoBlacklist as VideoBlacklistModel
76 logger.info(videoBlacklist)
77 91
78 if (req.body.reason !== undefined) videoBlacklist.reason = req.body.reason 92 if (req.body.reason !== undefined) videoBlacklist.reason = req.body.reason
79 93
@@ -92,11 +106,20 @@ async function listBlacklist (req: express.Request, res: express.Response, next:
92 106
93async function removeVideoFromBlacklistController (req: express.Request, res: express.Response, next: express.NextFunction) { 107async function removeVideoFromBlacklistController (req: express.Request, res: express.Response, next: express.NextFunction) {
94 const videoBlacklist = res.locals.videoBlacklist as VideoBlacklistModel 108 const videoBlacklist = res.locals.videoBlacklist as VideoBlacklistModel
109 const video: VideoModel = res.locals.video
95 110
96 await sequelizeTypescript.transaction(t => { 111 await sequelizeTypescript.transaction(async t => {
97 return videoBlacklist.destroy({ transaction: t }) 112 const unfederated = videoBlacklist.unfederated
113 await videoBlacklist.destroy({ transaction: t })
114
115 // Re federate the video
116 if (unfederated === true) {
117 await federateVideoIfNeeded(video, true, t)
118 }
98 }) 119 })
99 120
121 Notifier.Instance.notifyOnVideoUnblacklist(video)
122
100 logger.info('Video %s removed from blacklist.', res.locals.video.uuid) 123 logger.info('Video %s removed from blacklist.', res.locals.video.uuid)
101 124
102 return res.type('json').status(204).end() 125 return res.type('json').status(204).end()
diff --git a/server/controllers/api/videos/captions.ts b/server/controllers/api/videos/captions.ts
index 3ba918189..9b3661368 100644
--- a/server/controllers/api/videos/captions.ts
+++ b/server/controllers/api/videos/captions.ts
@@ -2,7 +2,7 @@ import * as express from 'express'
2import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate } from '../../../middlewares' 2import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate } from '../../../middlewares'
3import { addVideoCaptionValidator, deleteVideoCaptionValidator, listVideoCaptionsValidator } from '../../../middlewares/validators' 3import { addVideoCaptionValidator, deleteVideoCaptionValidator, listVideoCaptionsValidator } from '../../../middlewares/validators'
4import { createReqFiles } from '../../../helpers/express-utils' 4import { createReqFiles } from '../../../helpers/express-utils'
5import { CONFIG, sequelizeTypescript, VIDEO_CAPTIONS_MIMETYPE_EXT } from '../../../initializers' 5import { CONFIG, MIMETYPES, sequelizeTypescript } from '../../../initializers'
6import { getFormattedObjects } from '../../../helpers/utils' 6import { getFormattedObjects } from '../../../helpers/utils'
7import { VideoCaptionModel } from '../../../models/video/video-caption' 7import { VideoCaptionModel } from '../../../models/video/video-caption'
8import { VideoModel } from '../../../models/video/video' 8import { VideoModel } from '../../../models/video/video'
@@ -12,7 +12,7 @@ import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils'
12 12
13const reqVideoCaptionAdd = createReqFiles( 13const reqVideoCaptionAdd = createReqFiles(
14 [ 'captionfile' ], 14 [ 'captionfile' ],
15 VIDEO_CAPTIONS_MIMETYPE_EXT, 15 MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT,
16 { 16 {
17 captionfile: CONFIG.STORAGE.CAPTIONS_DIR 17 captionfile: CONFIG.STORAGE.CAPTIONS_DIR
18 } 18 }
diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts
index 3875c8f79..70c1148ba 100644
--- a/server/controllers/api/videos/comment.ts
+++ b/server/controllers/api/videos/comment.ts
@@ -26,6 +26,7 @@ import { VideoCommentModel } from '../../../models/video/video-comment'
26import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../../helpers/audit-logger' 26import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../../helpers/audit-logger'
27import { AccountModel } from '../../../models/account/account' 27import { AccountModel } from '../../../models/account/account'
28import { UserModel } from '../../../models/account/user' 28import { UserModel } from '../../../models/account/user'
29import { Notifier } from '../../../lib/notifier'
29 30
30const auditLogger = auditLoggerFactory('comments') 31const auditLogger = auditLoggerFactory('comments')
31const videoCommentRouter = express.Router() 32const videoCommentRouter = express.Router()
@@ -119,6 +120,7 @@ async function addVideoCommentThread (req: express.Request, res: express.Respons
119 }, t) 120 }, t)
120 }) 121 })
121 122
123 Notifier.Instance.notifyOnNewComment(comment)
122 auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON())) 124 auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
123 125
124 return res.json({ 126 return res.json({
@@ -140,6 +142,7 @@ async function addVideoCommentReply (req: express.Request, res: express.Response
140 }, t) 142 }, t)
141 }) 143 })
142 144
145 Notifier.Instance.notifyOnNewComment(comment)
143 auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON())) 146 auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
144 147
145 return res.json({ comment: comment.toFormattedJSON() }).end() 148 return res.json({ comment: comment.toFormattedJSON() }).end()
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts
index 398fd5a7f..98366cd82 100644
--- a/server/controllers/api/videos/import.ts
+++ b/server/controllers/api/videos/import.ts
@@ -3,14 +3,7 @@ import * as magnetUtil from 'magnet-uri'
3import 'multer' 3import 'multer'
4import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger' 4import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger'
5import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares' 5import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoImportAddValidator } from '../../../middlewares'
6import { 6import { CONFIG, MIMETYPES, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE } from '../../../initializers'
7 CONFIG,
8 IMAGE_MIMETYPE_EXT,
9 PREVIEWS_SIZE,
10 sequelizeTypescript,
11 THUMBNAILS_SIZE,
12 TORRENT_MIMETYPE_EXT
13} from '../../../initializers'
14import { getYoutubeDLInfo, YoutubeDLInfo } from '../../../helpers/youtube-dl' 7import { getYoutubeDLInfo, YoutubeDLInfo } from '../../../helpers/youtube-dl'
15import { createReqFiles } from '../../../helpers/express-utils' 8import { createReqFiles } from '../../../helpers/express-utils'
16import { logger } from '../../../helpers/logger' 9import { logger } from '../../../helpers/logger'
@@ -28,18 +21,18 @@ import { VideoChannelModel } from '../../../models/video/video-channel'
28import * as Bluebird from 'bluebird' 21import * as Bluebird from 'bluebird'
29import * as parseTorrent from 'parse-torrent' 22import * as parseTorrent from 'parse-torrent'
30import { getSecureTorrentName } from '../../../helpers/utils' 23import { getSecureTorrentName } from '../../../helpers/utils'
31import { readFile, rename } from 'fs-extra' 24import { readFile, move } from 'fs-extra'
32 25
33const auditLogger = auditLoggerFactory('video-imports') 26const auditLogger = auditLoggerFactory('video-imports')
34const videoImportsRouter = express.Router() 27const videoImportsRouter = express.Router()
35 28
36const reqVideoFileImport = createReqFiles( 29const reqVideoFileImport = createReqFiles(
37 [ 'thumbnailfile', 'previewfile', 'torrentfile' ], 30 [ 'thumbnailfile', 'previewfile', 'torrentfile' ],
38 Object.assign({}, TORRENT_MIMETYPE_EXT, IMAGE_MIMETYPE_EXT), 31 Object.assign({}, MIMETYPES.TORRENT.MIMETYPE_EXT, MIMETYPES.IMAGE.MIMETYPE_EXT),
39 { 32 {
40 thumbnailfile: CONFIG.STORAGE.THUMBNAILS_DIR, 33 thumbnailfile: CONFIG.STORAGE.TMP_DIR,
41 previewfile: CONFIG.STORAGE.PREVIEWS_DIR, 34 previewfile: CONFIG.STORAGE.TMP_DIR,
42 torrentfile: CONFIG.STORAGE.TORRENTS_DIR 35 torrentfile: CONFIG.STORAGE.TMP_DIR
43 } 36 }
44) 37)
45 38
@@ -78,7 +71,7 @@ async function addTorrentImport (req: express.Request, res: express.Response, to
78 71
79 // Rename the torrent to a secured name 72 // Rename the torrent to a secured name
80 const newTorrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, getSecureTorrentName(torrentName)) 73 const newTorrentPath = join(CONFIG.STORAGE.TORRENTS_DIR, getSecureTorrentName(torrentName))
81 await rename(torrentfile.path, newTorrentPath) 74 await move(torrentfile.path, newTorrentPath)
82 torrentfile.path = newTorrentPath 75 torrentfile.path = newTorrentPath
83 76
84 const buf = await readFile(torrentfile.path) 77 const buf = await readFile(torrentfile.path)
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 3d1b2e1a2..2b2dfa7ca 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -8,14 +8,13 @@ import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../
8import { getFormattedObjects, getServerActor } from '../../../helpers/utils' 8import { getFormattedObjects, getServerActor } from '../../../helpers/utils'
9import { 9import {
10 CONFIG, 10 CONFIG,
11 IMAGE_MIMETYPE_EXT, 11 MIMETYPES,
12 PREVIEWS_SIZE, 12 PREVIEWS_SIZE,
13 sequelizeTypescript, 13 sequelizeTypescript,
14 THUMBNAILS_SIZE, 14 THUMBNAILS_SIZE,
15 VIDEO_CATEGORIES, 15 VIDEO_CATEGORIES,
16 VIDEO_LANGUAGES, 16 VIDEO_LANGUAGES,
17 VIDEO_LICENCES, 17 VIDEO_LICENCES,
18 VIDEO_MIMETYPE_EXT,
19 VIDEO_PRIVACIES 18 VIDEO_PRIVACIES
20} from '../../../initializers' 19} from '../../../initializers'
21import { 20import {
@@ -57,27 +56,28 @@ import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-u
57import { videoCaptionsRouter } from './captions' 56import { videoCaptionsRouter } from './captions'
58import { videoImportsRouter } from './import' 57import { videoImportsRouter } from './import'
59import { resetSequelizeInstance } from '../../../helpers/database-utils' 58import { resetSequelizeInstance } from '../../../helpers/database-utils'
60import { rename } from 'fs-extra' 59import { move } from 'fs-extra'
61import { watchingRouter } from './watching' 60import { watchingRouter } from './watching'
61import { Notifier } from '../../../lib/notifier'
62 62
63const auditLogger = auditLoggerFactory('videos') 63const auditLogger = auditLoggerFactory('videos')
64const videosRouter = express.Router() 64const videosRouter = express.Router()
65 65
66const reqVideoFileAdd = createReqFiles( 66const reqVideoFileAdd = createReqFiles(
67 [ 'videofile', 'thumbnailfile', 'previewfile' ], 67 [ 'videofile', 'thumbnailfile', 'previewfile' ],
68 Object.assign({}, VIDEO_MIMETYPE_EXT, IMAGE_MIMETYPE_EXT), 68 Object.assign({}, MIMETYPES.VIDEO.MIMETYPE_EXT, MIMETYPES.IMAGE.MIMETYPE_EXT),
69 { 69 {
70 videofile: CONFIG.STORAGE.VIDEOS_DIR, 70 videofile: CONFIG.STORAGE.TMP_DIR,
71 thumbnailfile: CONFIG.STORAGE.THUMBNAILS_DIR, 71 thumbnailfile: CONFIG.STORAGE.TMP_DIR,
72 previewfile: CONFIG.STORAGE.PREVIEWS_DIR 72 previewfile: CONFIG.STORAGE.TMP_DIR
73 } 73 }
74) 74)
75const reqVideoFileUpdate = createReqFiles( 75const reqVideoFileUpdate = createReqFiles(
76 [ 'thumbnailfile', 'previewfile' ], 76 [ 'thumbnailfile', 'previewfile' ],
77 IMAGE_MIMETYPE_EXT, 77 MIMETYPES.IMAGE.MIMETYPE_EXT,
78 { 78 {
79 thumbnailfile: CONFIG.STORAGE.THUMBNAILS_DIR, 79 thumbnailfile: CONFIG.STORAGE.TMP_DIR,
80 previewfile: CONFIG.STORAGE.PREVIEWS_DIR 80 previewfile: CONFIG.STORAGE.TMP_DIR
81 } 81 }
82) 82)
83 83
@@ -208,7 +208,7 @@ async function addVideo (req: express.Request, res: express.Response) {
208 // Move physical file 208 // Move physical file
209 const videoDir = CONFIG.STORAGE.VIDEOS_DIR 209 const videoDir = CONFIG.STORAGE.VIDEOS_DIR
210 const destination = join(videoDir, video.getVideoFilename(videoFile)) 210 const destination = join(videoDir, video.getVideoFilename(videoFile))
211 await rename(videoPhysicalFile.path, destination) 211 await move(videoPhysicalFile.path, destination)
212 // This is important in case if there is another attempt in the retry process 212 // This is important in case if there is another attempt in the retry process
213 videoPhysicalFile.filename = video.getVideoFilename(videoFile) 213 videoPhysicalFile.filename = video.getVideoFilename(videoFile)
214 videoPhysicalFile.path = destination 214 videoPhysicalFile.path = destination
@@ -271,6 +271,8 @@ async function addVideo (req: express.Request, res: express.Response) {
271 return videoCreated 271 return videoCreated
272 }) 272 })
273 273
274 Notifier.Instance.notifyOnNewVideo(videoCreated)
275
274 if (video.state === VideoState.TO_TRANSCODE) { 276 if (video.state === VideoState.TO_TRANSCODE) {
275 // Put uuid because we don't have id auto incremented for now 277 // Put uuid because we don't have id auto incremented for now
276 const dataInput = { 278 const dataInput = {
@@ -295,6 +297,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
295 const oldVideoAuditView = new VideoAuditView(videoInstance.toFormattedDetailsJSON()) 297 const oldVideoAuditView = new VideoAuditView(videoInstance.toFormattedDetailsJSON())
296 const videoInfoToUpdate: VideoUpdate = req.body 298 const videoInfoToUpdate: VideoUpdate = req.body
297 const wasPrivateVideo = videoInstance.privacy === VideoPrivacy.PRIVATE 299 const wasPrivateVideo = videoInstance.privacy === VideoPrivacy.PRIVATE
300 const wasUnlistedVideo = videoInstance.privacy === VideoPrivacy.UNLISTED
298 301
299 // Process thumbnail or create it from the video 302 // Process thumbnail or create it from the video
300 if (req.files && req.files['thumbnailfile']) { 303 if (req.files && req.files['thumbnailfile']) {
@@ -309,10 +312,8 @@ async function updateVideo (req: express.Request, res: express.Response) {
309 } 312 }
310 313
311 try { 314 try {
312 await sequelizeTypescript.transaction(async t => { 315 const videoInstanceUpdated = await sequelizeTypescript.transaction(async t => {
313 const sequelizeOptions = { 316 const sequelizeOptions = { transaction: t }
314 transaction: t
315 }
316 const oldVideoChannel = videoInstance.VideoChannel 317 const oldVideoChannel = videoInstance.VideoChannel
317 318
318 if (videoInfoToUpdate.name !== undefined) videoInstance.set('name', videoInfoToUpdate.name) 319 if (videoInfoToUpdate.name !== undefined) videoInstance.set('name', videoInfoToUpdate.name)
@@ -363,7 +364,11 @@ async function updateVideo (req: express.Request, res: express.Response) {
363 } 364 }
364 365
365 const isNewVideo = wasPrivateVideo && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE 366 const isNewVideo = wasPrivateVideo && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE
366 await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo, t) 367
368 // Don't send update if the video was unfederated
369 if (!videoInstanceUpdated.VideoBlacklist || videoInstanceUpdated.VideoBlacklist.unfederated === false) {
370 await federateVideoIfNeeded(videoInstanceUpdated, isNewVideo, t)
371 }
367 372
368 auditLogger.update( 373 auditLogger.update(
369 getAuditIdFromRes(res), 374 getAuditIdFromRes(res),
@@ -371,7 +376,13 @@ async function updateVideo (req: express.Request, res: express.Response) {
371 oldVideoAuditView 376 oldVideoAuditView
372 ) 377 )
373 logger.info('Video with name %s and uuid %s updated.', videoInstance.name, videoInstance.uuid) 378 logger.info('Video with name %s and uuid %s updated.', videoInstance.name, videoInstance.uuid)
379
380 return videoInstanceUpdated
374 }) 381 })
382
383 if (wasUnlistedVideo || wasPrivateVideo) {
384 Notifier.Instance.notifyOnNewVideo(videoInstanceUpdated)
385 }
375 } catch (err) { 386 } catch (err) {
376 // Force fields we want to update 387 // Force fields we want to update
377 // If the transaction is retried, sequelize will think the object has not changed 388 // If the transaction is retried, sequelize will think the object has not changed
@@ -388,7 +399,7 @@ function getVideo (req: express.Request, res: express.Response) {
388 const videoInstance = res.locals.video 399 const videoInstance = res.locals.video
389 400
390 if (videoInstance.isOutdated()) { 401 if (videoInstance.isOutdated()) {
391 JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', videoUrl: videoInstance.url } }) 402 JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', url: videoInstance.url } })
392 .catch(err => logger.error('Cannot create AP refresher job for video %s.', videoInstance.url, { err })) 403 .catch(err => logger.error('Cannot create AP refresher job for video %s.', videoInstance.url, { err }))
393 } 404 }
394 405
diff --git a/server/controllers/bots.ts b/server/controllers/bots.ts
new file mode 100644
index 000000000..2db86a2d8
--- /dev/null
+++ b/server/controllers/bots.ts
@@ -0,0 +1,101 @@
1import * as express from 'express'
2import { asyncMiddleware } from '../middlewares'
3import { CONFIG, ROUTE_CACHE_LIFETIME } from '../initializers'
4import * as sitemapModule from 'sitemap'
5import { logger } from '../helpers/logger'
6import { VideoModel } from '../models/video/video'
7import { VideoChannelModel } from '../models/video/video-channel'
8import { AccountModel } from '../models/account/account'
9import { cacheRoute } from '../middlewares/cache'
10import { buildNSFWFilter } from '../helpers/express-utils'
11import { truncate } from 'lodash'
12
13const botsRouter = express.Router()
14
15// Special route that add OpenGraph and oEmbed tags
16// Do not use a template engine for a so little thing
17botsRouter.use('/sitemap.xml',
18 asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.SITEMAP)),
19 asyncMiddleware(getSitemap)
20)
21
22// ---------------------------------------------------------------------------
23
24export {
25 botsRouter
26}
27
28// ---------------------------------------------------------------------------
29
30async function getSitemap (req: express.Request, res: express.Response) {
31 let urls = getSitemapBasicUrls()
32
33 urls = urls.concat(await getSitemapLocalVideoUrls())
34 urls = urls.concat(await getSitemapVideoChannelUrls())
35 urls = urls.concat(await getSitemapAccountUrls())
36
37 const sitemap = sitemapModule.createSitemap({
38 hostname: CONFIG.WEBSERVER.URL,
39 urls: urls
40 })
41
42 sitemap.toXML((err, xml) => {
43 if (err) {
44 logger.error('Cannot generate sitemap.', { err })
45 return res.sendStatus(500)
46 }
47
48 res.header('Content-Type', 'application/xml')
49 res.send(xml)
50 })
51}
52
53async function getSitemapVideoChannelUrls () {
54 const rows = await VideoChannelModel.listLocalsForSitemap('createdAt')
55
56 return rows.map(channel => ({
57 url: CONFIG.WEBSERVER.URL + '/video-channels/' + channel.Actor.preferredUsername
58 }))
59}
60
61async function getSitemapAccountUrls () {
62 const rows = await AccountModel.listLocalsForSitemap('createdAt')
63
64 return rows.map(channel => ({
65 url: CONFIG.WEBSERVER.URL + '/accounts/' + channel.Actor.preferredUsername
66 }))
67}
68
69async function getSitemapLocalVideoUrls () {
70 const resultList = await VideoModel.listForApi({
71 start: 0,
72 count: undefined,
73 sort: 'createdAt',
74 includeLocalVideos: true,
75 nsfw: buildNSFWFilter(),
76 filter: 'local',
77 withFiles: false
78 })
79
80 return resultList.data.map(v => ({
81 url: CONFIG.WEBSERVER.URL + '/videos/watch/' + v.uuid,
82 video: [
83 {
84 title: v.name,
85 // Sitemap description should be < 2000 characters
86 description: truncate(v.description || v.name, { length: 2000, omission: '...' }),
87 player_loc: CONFIG.WEBSERVER.URL + '/videos/embed/' + v.uuid,
88 thumbnail_loc: CONFIG.WEBSERVER.URL + v.getThumbnailStaticPath()
89 }
90 ]
91 }))
92}
93
94function getSitemapBasicUrls () {
95 const paths = [
96 '/about/instance',
97 '/videos/local'
98 ]
99
100 return paths.map(p => ({ url: CONFIG.WEBSERVER.URL + p }))
101}
diff --git a/server/controllers/client.ts b/server/controllers/client.ts
index 73b40cf65..f17f2a5d2 100644
--- a/server/controllers/client.ts
+++ b/server/controllers/client.ts
@@ -2,7 +2,7 @@ import * as express from 'express'
2import { join } from 'path' 2import { join } from 'path'
3import { root } from '../helpers/core-utils' 3import { root } from '../helpers/core-utils'
4import { ACCEPT_HEADERS, STATIC_MAX_AGE } from '../initializers' 4import { ACCEPT_HEADERS, STATIC_MAX_AGE } from '../initializers'
5import { asyncMiddleware } from '../middlewares' 5import { asyncMiddleware, embedCSP } from '../middlewares'
6import { buildFileLocale, getCompleteLocale, is18nLocale, LOCALE_FILES } from '../../shared/models/i18n/i18n' 6import { buildFileLocale, getCompleteLocale, is18nLocale, LOCALE_FILES } from '../../shared/models/i18n/i18n'
7import { ClientHtml } from '../lib/client-html' 7import { ClientHtml } from '../lib/client-html'
8import { logger } from '../helpers/logger' 8import { logger } from '../helpers/logger'
@@ -16,21 +16,20 @@ const testEmbedPath = join(distPath, 'standalone', 'videos', 'test-embed.html')
16 16
17// Special route that add OpenGraph and oEmbed tags 17// Special route that add OpenGraph and oEmbed tags
18// Do not use a template engine for a so little thing 18// Do not use a template engine for a so little thing
19clientsRouter.use('/videos/watch/:id', 19clientsRouter.use('/videos/watch/:id', asyncMiddleware(generateWatchHtmlPage))
20 asyncMiddleware(generateWatchHtmlPage)
21)
22 20
23clientsRouter.use('' + 21clientsRouter.use(
24 '/videos/embed', 22 '/videos/embed',
25 (req: express.Request, res: express.Response, next: express.NextFunction) => { 23 embedCSP,
24 (req: express.Request, res: express.Response) => {
26 res.removeHeader('X-Frame-Options') 25 res.removeHeader('X-Frame-Options')
27 res.sendFile(embedPath) 26 res.sendFile(embedPath)
28 } 27 }
29) 28)
30clientsRouter.use('' + 29clientsRouter.use(
31 '/videos/test-embed', (req: express.Request, res: express.Response, next: express.NextFunction) => { 30 '/videos/test-embed',
32 res.sendFile(testEmbedPath) 31 (req: express.Request, res: express.Response) => res.sendFile(testEmbedPath)
33}) 32)
34 33
35// Static HTML/CSS/JS client files 34// Static HTML/CSS/JS client files
36 35
@@ -89,7 +88,7 @@ export {
89// --------------------------------------------------------------------------- 88// ---------------------------------------------------------------------------
90 89
91async function generateHTMLPage (req: express.Request, res: express.Response, paramLang?: string) { 90async function generateHTMLPage (req: express.Request, res: express.Response, paramLang?: string) {
92 const html = await ClientHtml.getIndexHTML(req, res, paramLang) 91 const html = await ClientHtml.getDefaultHTMLPage(req, res, paramLang)
93 92
94 return sendHTML(html, res) 93 return sendHTML(html, res)
95} 94}
diff --git a/server/controllers/feeds.ts b/server/controllers/feeds.ts
index ccb9b6029..960085af1 100644
--- a/server/controllers/feeds.ts
+++ b/server/controllers/feeds.ts
@@ -56,7 +56,7 @@ async function generateVideoCommentsFeed (req: express.Request, res: express.Res
56 56
57 // Adding video items to the feed, one at a time 57 // Adding video items to the feed, one at a time
58 comments.forEach(comment => { 58 comments.forEach(comment => {
59 const link = CONFIG.WEBSERVER.URL + '/videos/watch/' + comment.Video.uuid + ';threadId=' + comment.getThreadId() 59 const link = CONFIG.WEBSERVER.URL + comment.getCommentStaticPath()
60 60
61 feed.addItem({ 61 feed.addItem({
62 title: `${comment.Video.name} - ${comment.Account.getDisplayName()}`, 62 title: `${comment.Video.name} - ${comment.Account.getDisplayName()}`,
diff --git a/server/controllers/index.ts b/server/controllers/index.ts
index 197fa897a..a88a03c79 100644
--- a/server/controllers/index.ts
+++ b/server/controllers/index.ts
@@ -6,3 +6,4 @@ export * from './services'
6export * from './static' 6export * from './static'
7export * from './webfinger' 7export * from './webfinger'
8export * from './tracker' 8export * from './tracker'
9export * from './bots'
diff --git a/server/controllers/static.ts b/server/controllers/static.ts
index 75e30353c..4fd58f70c 100644
--- a/server/controllers/static.ts
+++ b/server/controllers/static.ts
@@ -34,13 +34,18 @@ staticRouter.use(
34) 34)
35 35
36// Videos path for webseeding 36// Videos path for webseeding
37const videosPhysicalPath = CONFIG.STORAGE.VIDEOS_DIR
38staticRouter.use( 37staticRouter.use(
39 STATIC_PATHS.WEBSEED, 38 STATIC_PATHS.WEBSEED,
40 cors(), 39 cors(),
41 express.static(videosPhysicalPath) 40 express.static(CONFIG.STORAGE.VIDEOS_DIR, { fallthrough: false }) // 404 because we don't have this video
42) 41)
43staticRouter.use( 42staticRouter.use(
43 STATIC_PATHS.REDUNDANCY,
44 cors(),
45 express.static(CONFIG.STORAGE.REDUNDANCY_DIR, { fallthrough: false }) // 404 because we don't have this video
46)
47
48staticRouter.use(
44 STATIC_DOWNLOAD_PATHS.VIDEOS + ':id-:resolution([0-9]+).:extension', 49 STATIC_DOWNLOAD_PATHS.VIDEOS + ':id-:resolution([0-9]+).:extension',
45 asyncMiddleware(videosGetValidator), 50 asyncMiddleware(videosGetValidator),
46 asyncMiddleware(downloadVideoFile) 51 asyncMiddleware(downloadVideoFile)
@@ -131,6 +136,12 @@ staticRouter.use('/.well-known/dnt/',
131 } 136 }
132) 137)
133 138
139staticRouter.use('/.well-known/change-password',
140 (_, res: express.Response) => {
141 res.redirect('/my-account/settings')
142 }
143)
144
134// --------------------------------------------------------------------------- 145// ---------------------------------------------------------------------------
135 146
136export { 147export {
diff --git a/server/controllers/tracker.ts b/server/controllers/tracker.ts
index 9bc7586d1..1deb8c402 100644
--- a/server/controllers/tracker.ts
+++ b/server/controllers/tracker.ts
@@ -6,6 +6,7 @@ import * as proxyAddr from 'proxy-addr'
6import { Server as WebSocketServer } from 'ws' 6import { Server as WebSocketServer } from 'ws'
7import { CONFIG, TRACKER_RATE_LIMITS } from '../initializers/constants' 7import { CONFIG, TRACKER_RATE_LIMITS } from '../initializers/constants'
8import { VideoFileModel } from '../models/video/video-file' 8import { VideoFileModel } from '../models/video/video-file'
9import { parse } from 'url'
9 10
10const TrackerServer = bitTorrentTracker.Server 11const TrackerServer = bitTorrentTracker.Server
11 12
@@ -59,16 +60,26 @@ const onHttpRequest = trackerServer.onHttpRequest.bind(trackerServer)
59trackerRouter.get('/tracker/announce', (req, res) => onHttpRequest(req, res, { action: 'announce' })) 60trackerRouter.get('/tracker/announce', (req, res) => onHttpRequest(req, res, { action: 'announce' }))
60trackerRouter.get('/tracker/scrape', (req, res) => onHttpRequest(req, res, { action: 'scrape' })) 61trackerRouter.get('/tracker/scrape', (req, res) => onHttpRequest(req, res, { action: 'scrape' }))
61 62
62function createWebsocketServer (app: express.Application) { 63function createWebsocketTrackerServer (app: express.Application) {
63 const server = http.createServer(app) 64 const server = http.createServer(app)
64 const wss = new WebSocketServer({ server: server, path: '/tracker/socket' }) 65 const wss = new WebSocketServer({ noServer: true })
66
65 wss.on('connection', function (ws, req) { 67 wss.on('connection', function (ws, req) {
66 const ip = proxyAddr(req, CONFIG.TRUST_PROXY) 68 ws['ip'] = proxyAddr(req, CONFIG.TRUST_PROXY)
67 ws['ip'] = ip
68 69
69 trackerServer.onWebSocketConnection(ws) 70 trackerServer.onWebSocketConnection(ws)
70 }) 71 })
71 72
73 server.on('upgrade', (request, socket, head) => {
74 const pathname = parse(request.url).pathname
75
76 if (pathname === '/tracker/socket') {
77 wss.handleUpgrade(request, socket, head, ws => wss.emit('connection', ws, request))
78 }
79
80 // Don't destroy socket, we have Socket.IO too
81 })
82
72 return server 83 return server
73} 84}
74 85
@@ -76,7 +87,7 @@ function createWebsocketServer (app: express.Application) {
76 87
77export { 88export {
78 trackerRouter, 89 trackerRouter,
79 createWebsocketServer 90 createWebsocketTrackerServer
80} 91}
81 92
82// --------------------------------------------------------------------------- 93// ---------------------------------------------------------------------------
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts
index 79b76fa0b..f1430055f 100644
--- a/server/helpers/activitypub.ts
+++ b/server/helpers/activitypub.ts
@@ -106,7 +106,7 @@ function buildSignedActivity (byActor: ActorModel, data: Object) {
106 return signJsonLDObject(byActor, activity) as Promise<Activity> 106 return signJsonLDObject(byActor, activity) as Promise<Activity>
107} 107}
108 108
109function getAPUrl (activity: string | { id: string }) { 109function getAPId (activity: string | { id: string }) {
110 if (typeof activity === 'string') return activity 110 if (typeof activity === 'string') return activity
111 111
112 return activity.id 112 return activity.id
@@ -123,7 +123,7 @@ function checkUrlsSameHost (url1: string, url2: string) {
123 123
124export { 124export {
125 checkUrlsSameHost, 125 checkUrlsSameHost,
126 getAPUrl, 126 getAPId,
127 activityPubContextify, 127 activityPubContextify,
128 activityPubCollectionPagination, 128 activityPubCollectionPagination,
129 buildSignedActivity 129 buildSignedActivity
diff --git a/server/helpers/captions-utils.ts b/server/helpers/captions-utils.ts
index 660dce65c..0fb11a125 100644
--- a/server/helpers/captions-utils.ts
+++ b/server/helpers/captions-utils.ts
@@ -2,7 +2,7 @@ import { join } from 'path'
2import { CONFIG } from '../initializers' 2import { CONFIG } from '../initializers'
3import { VideoCaptionModel } from '../models/video/video-caption' 3import { VideoCaptionModel } from '../models/video/video-caption'
4import * as srt2vtt from 'srt-to-vtt' 4import * as srt2vtt from 'srt-to-vtt'
5import { createReadStream, createWriteStream, remove, rename } from 'fs-extra' 5import { createReadStream, createWriteStream, remove, move } from 'fs-extra'
6 6
7async function moveAndProcessCaptionFile (physicalFile: { filename: string, path: string }, videoCaption: VideoCaptionModel) { 7async function moveAndProcessCaptionFile (physicalFile: { filename: string, path: string }, videoCaption: VideoCaptionModel) {
8 const videoCaptionsDir = CONFIG.STORAGE.CAPTIONS_DIR 8 const videoCaptionsDir = CONFIG.STORAGE.CAPTIONS_DIR
@@ -13,7 +13,7 @@ async function moveAndProcessCaptionFile (physicalFile: { filename: string, path
13 await convertSrtToVtt(physicalFile.path, destination) 13 await convertSrtToVtt(physicalFile.path, destination)
14 await remove(physicalFile.path) 14 await remove(physicalFile.path)
15 } else { // Just move the vtt file 15 } else { // Just move the vtt file
16 await rename(physicalFile.path, destination) 16 await move(physicalFile.path, destination, { overwrite: true })
17 } 17 }
18 18
19 // This is important in case if there is another attempt in the retry process 19 // This is important in case if there is another attempt in the retry process
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts
index 84e33c0e9..3fb824e36 100644
--- a/server/helpers/core-utils.ts
+++ b/server/helpers/core-utils.ts
@@ -11,6 +11,25 @@ import * as pem from 'pem'
11import { URL } from 'url' 11import { URL } from 'url'
12import { truncate } from 'lodash' 12import { truncate } from 'lodash'
13import { exec } from 'child_process' 13import { exec } from 'child_process'
14import { isArray } from './custom-validators/misc'
15
16const objectConverter = (oldObject: any, keyConverter: (e: string) => string, valueConverter: (e: any) => any) => {
17 if (!oldObject || typeof oldObject !== 'object') {
18 return valueConverter(oldObject)
19 }
20
21 if (isArray(oldObject)) {
22 return oldObject.map(e => objectConverter(e, keyConverter, valueConverter))
23 }
24
25 const newObject = {}
26 Object.keys(oldObject).forEach(oldKey => {
27 const newKey = keyConverter(oldKey)
28 newObject[ newKey ] = objectConverter(oldObject[ oldKey ], keyConverter, valueConverter)
29 })
30
31 return newObject
32}
14 33
15const timeTable = { 34const timeTable = {
16 ms: 1, 35 ms: 1,
@@ -235,6 +254,7 @@ export {
235 isTestInstance, 254 isTestInstance,
236 isProdInstance, 255 isProdInstance,
237 256
257 objectConverter,
238 root, 258 root,
239 escapeHTML, 259 escapeHTML,
240 pageToStartAndCount, 260 pageToStartAndCount,
diff --git a/server/helpers/custom-validators/activitypub/activity.ts b/server/helpers/custom-validators/activitypub/activity.ts
index 2562ead9b..b24590d9d 100644
--- a/server/helpers/custom-validators/activitypub/activity.ts
+++ b/server/helpers/custom-validators/activitypub/activity.ts
@@ -1,26 +1,14 @@
1import * as validator from 'validator' 1import * as validator from 'validator'
2import { Activity, ActivityType } from '../../../../shared/models/activitypub' 2import { Activity, ActivityType } from '../../../../shared/models/activitypub'
3import { 3import { sanitizeAndCheckActorObject } from './actor'
4 isActorAcceptActivityValid, 4import { isActivityPubUrlValid, isBaseActivityValid, isObjectValid } from './misc'
5 isActorDeleteActivityValid, 5import { isDislikeActivityValid } from './rate'
6 isActorFollowActivityValid, 6import { sanitizeAndCheckVideoCommentObject } from './video-comments'
7 isActorRejectActivityValid, 7import { sanitizeAndCheckVideoTorrentObject } from './videos'
8 isActorUpdateActivityValid
9} from './actor'
10import { isAnnounceActivityValid } from './announce'
11import { isActivityPubUrlValid } from './misc'
12import { isDislikeActivityValid, isLikeActivityValid } from './rate'
13import { isUndoActivityValid } from './undo'
14import { isVideoCommentCreateActivityValid, isVideoCommentDeleteActivityValid } from './video-comments'
15import {
16 isVideoFlagValid,
17 isVideoTorrentDeleteActivityValid,
18 sanitizeAndCheckVideoTorrentCreateActivity,
19 sanitizeAndCheckVideoTorrentUpdateActivity
20} from './videos'
21import { isViewActivityValid } from './view' 8import { isViewActivityValid } from './view'
22import { exists } from '../misc' 9import { exists } from '../misc'
23import { isCacheFileCreateActivityValid, isCacheFileUpdateActivityValid } from './cache-file' 10import { isCacheFileObjectValid } from './cache-file'
11import { isFlagActivityValid } from './flag'
24 12
25function isRootActivityValid (activity: any) { 13function isRootActivityValid (activity: any) {
26 return Array.isArray(activity['@context']) && ( 14 return Array.isArray(activity['@context']) && (
@@ -46,7 +34,10 @@ const activityCheckers: { [ P in ActivityType ]: (activity: Activity) => boolean
46 Reject: checkRejectActivity, 34 Reject: checkRejectActivity,
47 Announce: checkAnnounceActivity, 35 Announce: checkAnnounceActivity,
48 Undo: checkUndoActivity, 36 Undo: checkUndoActivity,
49 Like: checkLikeActivity 37 Like: checkLikeActivity,
38 View: checkViewActivity,
39 Flag: checkFlagActivity,
40 Dislike: checkDislikeActivity
50} 41}
51 42
52function isActivityValid (activity: any) { 43function isActivityValid (activity: any) {
@@ -66,47 +57,79 @@ export {
66 57
67// --------------------------------------------------------------------------- 58// ---------------------------------------------------------------------------
68 59
60function checkViewActivity (activity: any) {
61 return isBaseActivityValid(activity, 'View') &&
62 isViewActivityValid(activity)
63}
64
65function checkFlagActivity (activity: any) {
66 return isBaseActivityValid(activity, 'Flag') &&
67 isFlagActivityValid(activity)
68}
69
70function checkDislikeActivity (activity: any) {
71 return isBaseActivityValid(activity, 'Dislike') &&
72 isDislikeActivityValid(activity)
73}
74
69function checkCreateActivity (activity: any) { 75function checkCreateActivity (activity: any) {
70 return isViewActivityValid(activity) || 76 return isBaseActivityValid(activity, 'Create') &&
71 isDislikeActivityValid(activity) || 77 (
72 sanitizeAndCheckVideoTorrentCreateActivity(activity) || 78 isViewActivityValid(activity.object) ||
73 isVideoFlagValid(activity) || 79 isDislikeActivityValid(activity.object) ||
74 isVideoCommentCreateActivityValid(activity) || 80 isFlagActivityValid(activity.object) ||
75 isCacheFileCreateActivityValid(activity) 81
82 isCacheFileObjectValid(activity.object) ||
83 sanitizeAndCheckVideoCommentObject(activity.object) ||
84 sanitizeAndCheckVideoTorrentObject(activity.object)
85 )
76} 86}
77 87
78function checkUpdateActivity (activity: any) { 88function checkUpdateActivity (activity: any) {
79 return isCacheFileUpdateActivityValid(activity) || 89 return isBaseActivityValid(activity, 'Update') &&
80 sanitizeAndCheckVideoTorrentUpdateActivity(activity) || 90 (
81 isActorUpdateActivityValid(activity) 91 isCacheFileObjectValid(activity.object) ||
92 sanitizeAndCheckVideoTorrentObject(activity.object) ||
93 sanitizeAndCheckActorObject(activity.object)
94 )
82} 95}
83 96
84function checkDeleteActivity (activity: any) { 97function checkDeleteActivity (activity: any) {
85 return isVideoTorrentDeleteActivityValid(activity) || 98 // We don't really check objects
86 isActorDeleteActivityValid(activity) || 99 return isBaseActivityValid(activity, 'Delete') &&
87 isVideoCommentDeleteActivityValid(activity) 100 isObjectValid(activity.object)
88} 101}
89 102
90function checkFollowActivity (activity: any) { 103function checkFollowActivity (activity: any) {
91 return isActorFollowActivityValid(activity) 104 return isBaseActivityValid(activity, 'Follow') &&
105 isObjectValid(activity.object)
92} 106}
93 107
94function checkAcceptActivity (activity: any) { 108function checkAcceptActivity (activity: any) {
95 return isActorAcceptActivityValid(activity) 109 return isBaseActivityValid(activity, 'Accept')
96} 110}
97 111
98function checkRejectActivity (activity: any) { 112function checkRejectActivity (activity: any) {
99 return isActorRejectActivityValid(activity) 113 return isBaseActivityValid(activity, 'Reject')
100} 114}
101 115
102function checkAnnounceActivity (activity: any) { 116function checkAnnounceActivity (activity: any) {
103 return isAnnounceActivityValid(activity) 117 return isBaseActivityValid(activity, 'Announce') &&
118 isObjectValid(activity.object)
104} 119}
105 120
106function checkUndoActivity (activity: any) { 121function checkUndoActivity (activity: any) {
107 return isUndoActivityValid(activity) 122 return isBaseActivityValid(activity, 'Undo') &&
123 (
124 checkFollowActivity(activity.object) ||
125 checkLikeActivity(activity.object) ||
126 checkDislikeActivity(activity.object) ||
127 checkAnnounceActivity(activity.object) ||
128 checkCreateActivity(activity.object)
129 )
108} 130}
109 131
110function checkLikeActivity (activity: any) { 132function checkLikeActivity (activity: any) {
111 return isLikeActivityValid(activity) 133 return isBaseActivityValid(activity, 'Like') &&
134 isObjectValid(activity.object)
112} 135}
diff --git a/server/helpers/custom-validators/activitypub/actor.ts b/server/helpers/custom-validators/activitypub/actor.ts
index 77c003cdf..c05f60f14 100644
--- a/server/helpers/custom-validators/activitypub/actor.ts
+++ b/server/helpers/custom-validators/activitypub/actor.ts
@@ -27,7 +27,8 @@ function isActorPublicKeyValid (publicKey: string) {
27 validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACTORS.PUBLIC_KEY) 27 validator.isLength(publicKey, CONSTRAINTS_FIELDS.ACTORS.PUBLIC_KEY)
28} 28}
29 29
30const actorNameRegExp = new RegExp('^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_\.]+$') 30const actorNameAlphabet = '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\\-_.]'
31const actorNameRegExp = new RegExp(`^${actorNameAlphabet}+$`)
31function isActorPreferredUsernameValid (preferredUsername: string) { 32function isActorPreferredUsernameValid (preferredUsername: string) {
32 return exists(preferredUsername) && validator.matches(preferredUsername, actorNameRegExp) 33 return exists(preferredUsername) && validator.matches(preferredUsername, actorNameRegExp)
33} 34}
@@ -72,24 +73,10 @@ function isActorDeleteActivityValid (activity: any) {
72 return isBaseActivityValid(activity, 'Delete') 73 return isBaseActivityValid(activity, 'Delete')
73} 74}
74 75
75function isActorFollowActivityValid (activity: any) { 76function sanitizeAndCheckActorObject (object: any) {
76 return isBaseActivityValid(activity, 'Follow') && 77 normalizeActor(object)
77 isActivityPubUrlValid(activity.object)
78}
79
80function isActorAcceptActivityValid (activity: any) {
81 return isBaseActivityValid(activity, 'Accept')
82}
83
84function isActorRejectActivityValid (activity: any) {
85 return isBaseActivityValid(activity, 'Reject')
86}
87
88function isActorUpdateActivityValid (activity: any) {
89 normalizeActor(activity.object)
90 78
91 return isBaseActivityValid(activity, 'Update') && 79 return isActorObjectValid(object)
92 isActorObjectValid(activity.object)
93} 80}
94 81
95function normalizeActor (actor: any) { 82function normalizeActor (actor: any) {
@@ -127,6 +114,7 @@ function areValidActorHandles (handles: string[]) {
127 114
128export { 115export {
129 normalizeActor, 116 normalizeActor,
117 actorNameAlphabet,
130 areValidActorHandles, 118 areValidActorHandles,
131 isActorEndpointsObjectValid, 119 isActorEndpointsObjectValid,
132 isActorPublicKeyObjectValid, 120 isActorPublicKeyObjectValid,
@@ -137,10 +125,7 @@ export {
137 isActorObjectValid, 125 isActorObjectValid,
138 isActorFollowingCountValid, 126 isActorFollowingCountValid,
139 isActorFollowersCountValid, 127 isActorFollowersCountValid,
140 isActorFollowActivityValid,
141 isActorAcceptActivityValid,
142 isActorRejectActivityValid,
143 isActorDeleteActivityValid, 128 isActorDeleteActivityValid,
144 isActorUpdateActivityValid, 129 sanitizeAndCheckActorObject,
145 isValidActorHandle 130 isValidActorHandle
146} 131}
diff --git a/server/helpers/custom-validators/activitypub/announce.ts b/server/helpers/custom-validators/activitypub/announce.ts
deleted file mode 100644
index 0519c6026..000000000
--- a/server/helpers/custom-validators/activitypub/announce.ts
+++ /dev/null
@@ -1,13 +0,0 @@
1import { isActivityPubUrlValid, isBaseActivityValid } from './misc'
2
3function isAnnounceActivityValid (activity: any) {
4 return isBaseActivityValid(activity, 'Announce') &&
5 (
6 isActivityPubUrlValid(activity.object) ||
7 (activity.object && isActivityPubUrlValid(activity.object.id))
8 )
9}
10
11export {
12 isAnnounceActivityValid
13}
diff --git a/server/helpers/custom-validators/activitypub/cache-file.ts b/server/helpers/custom-validators/activitypub/cache-file.ts
index bd70934c8..e2bd0c55e 100644
--- a/server/helpers/custom-validators/activitypub/cache-file.ts
+++ b/server/helpers/custom-validators/activitypub/cache-file.ts
@@ -1,18 +1,8 @@
1import { isActivityPubUrlValid, isBaseActivityValid } from './misc' 1import { isActivityPubUrlValid } from './misc'
2import { isRemoteVideoUrlValid } from './videos' 2import { isRemoteVideoUrlValid } from './videos'
3import { isDateValid, exists } from '../misc' 3import { exists, isDateValid } from '../misc'
4import { CacheFileObject } from '../../../../shared/models/activitypub/objects' 4import { CacheFileObject } from '../../../../shared/models/activitypub/objects'
5 5
6function isCacheFileCreateActivityValid (activity: any) {
7 return isBaseActivityValid(activity, 'Create') &&
8 isCacheFileObjectValid(activity.object)
9}
10
11function isCacheFileUpdateActivityValid (activity: any) {
12 return isBaseActivityValid(activity, 'Update') &&
13 isCacheFileObjectValid(activity.object)
14}
15
16function isCacheFileObjectValid (object: CacheFileObject) { 6function isCacheFileObjectValid (object: CacheFileObject) {
17 return exists(object) && 7 return exists(object) &&
18 object.type === 'CacheFile' && 8 object.type === 'CacheFile' &&
@@ -22,7 +12,5 @@ function isCacheFileObjectValid (object: CacheFileObject) {
22} 12}
23 13
24export { 14export {
25 isCacheFileUpdateActivityValid,
26 isCacheFileCreateActivityValid,
27 isCacheFileObjectValid 15 isCacheFileObjectValid
28} 16}
diff --git a/server/helpers/custom-validators/activitypub/flag.ts b/server/helpers/custom-validators/activitypub/flag.ts
new file mode 100644
index 000000000..6452e297c
--- /dev/null
+++ b/server/helpers/custom-validators/activitypub/flag.ts
@@ -0,0 +1,14 @@
1import { isActivityPubUrlValid } from './misc'
2import { isVideoAbuseReasonValid } from '../video-abuses'
3
4function isFlagActivityValid (activity: any) {
5 return activity.type === 'Flag' &&
6 isVideoAbuseReasonValid(activity.content) &&
7 isActivityPubUrlValid(activity.object)
8}
9
10// ---------------------------------------------------------------------------
11
12export {
13 isFlagActivityValid
14}
diff --git a/server/helpers/custom-validators/activitypub/misc.ts b/server/helpers/custom-validators/activitypub/misc.ts
index 4e2c57f04..f1762d11c 100644
--- a/server/helpers/custom-validators/activitypub/misc.ts
+++ b/server/helpers/custom-validators/activitypub/misc.ts
@@ -28,15 +28,20 @@ function isBaseActivityValid (activity: any, type: string) {
28 return (activity['@context'] === undefined || Array.isArray(activity['@context'])) && 28 return (activity['@context'] === undefined || Array.isArray(activity['@context'])) &&
29 activity.type === type && 29 activity.type === type &&
30 isActivityPubUrlValid(activity.id) && 30 isActivityPubUrlValid(activity.id) &&
31 exists(activity.actor) && 31 isObjectValid(activity.actor) &&
32 (isActivityPubUrlValid(activity.actor) || isActivityPubUrlValid(activity.actor.id)) && 32 isUrlCollectionValid(activity.to) &&
33 ( 33 isUrlCollectionValid(activity.cc)
34 activity.to === undefined || 34}
35 (Array.isArray(activity.to) && activity.to.every(t => isActivityPubUrlValid(t))) 35
36 ) && 36function isUrlCollectionValid (collection: any) {
37 return collection === undefined ||
38 (Array.isArray(collection) && collection.every(t => isActivityPubUrlValid(t)))
39}
40
41function isObjectValid (object: any) {
42 return exists(object) &&
37 ( 43 (
38 activity.cc === undefined || 44 isActivityPubUrlValid(object) || isActivityPubUrlValid(object.id)
39 (Array.isArray(activity.cc) && activity.cc.every(t => isActivityPubUrlValid(t)))
40 ) 45 )
41} 46}
42 47
@@ -57,5 +62,6 @@ export {
57 isUrlValid, 62 isUrlValid,
58 isActivityPubUrlValid, 63 isActivityPubUrlValid,
59 isBaseActivityValid, 64 isBaseActivityValid,
60 setValidAttributedTo 65 setValidAttributedTo,
66 isObjectValid
61} 67}
diff --git a/server/helpers/custom-validators/activitypub/rate.ts b/server/helpers/custom-validators/activitypub/rate.ts
index e70bd94b8..ba68e8074 100644
--- a/server/helpers/custom-validators/activitypub/rate.ts
+++ b/server/helpers/custom-validators/activitypub/rate.ts
@@ -1,20 +1,13 @@
1import { isActivityPubUrlValid, isBaseActivityValid } from './misc' 1import { isActivityPubUrlValid, isObjectValid } from './misc'
2
3function isLikeActivityValid (activity: any) {
4 return isBaseActivityValid(activity, 'Like') &&
5 isActivityPubUrlValid(activity.object)
6}
7 2
8function isDislikeActivityValid (activity: any) { 3function isDislikeActivityValid (activity: any) {
9 return isBaseActivityValid(activity, 'Create') && 4 return activity.type === 'Dislike' &&
10 activity.object.type === 'Dislike' && 5 isActivityPubUrlValid(activity.actor) &&
11 isActivityPubUrlValid(activity.object.actor) && 6 isObjectValid(activity.object)
12 isActivityPubUrlValid(activity.object.object)
13} 7}
14 8
15// --------------------------------------------------------------------------- 9// ---------------------------------------------------------------------------
16 10
17export { 11export {
18 isLikeActivityValid,
19 isDislikeActivityValid 12 isDislikeActivityValid
20} 13}
diff --git a/server/helpers/custom-validators/activitypub/undo.ts b/server/helpers/custom-validators/activitypub/undo.ts
deleted file mode 100644
index 578035893..000000000
--- a/server/helpers/custom-validators/activitypub/undo.ts
+++ /dev/null
@@ -1,20 +0,0 @@
1import { isActorFollowActivityValid } from './actor'
2import { isBaseActivityValid } from './misc'
3import { isDislikeActivityValid, isLikeActivityValid } from './rate'
4import { isAnnounceActivityValid } from './announce'
5import { isCacheFileCreateActivityValid } from './cache-file'
6
7function isUndoActivityValid (activity: any) {
8 return isBaseActivityValid(activity, 'Undo') &&
9 (
10 isActorFollowActivityValid(activity.object) ||
11 isLikeActivityValid(activity.object) ||
12 isDislikeActivityValid(activity.object) ||
13 isAnnounceActivityValid(activity.object) ||
14 isCacheFileCreateActivityValid(activity.object)
15 )
16}
17
18export {
19 isUndoActivityValid
20}
diff --git a/server/helpers/custom-validators/activitypub/video-comments.ts b/server/helpers/custom-validators/activitypub/video-comments.ts
index 051c4565a..0415db21c 100644
--- a/server/helpers/custom-validators/activitypub/video-comments.ts
+++ b/server/helpers/custom-validators/activitypub/video-comments.ts
@@ -3,11 +3,6 @@ import { ACTIVITY_PUB, CONSTRAINTS_FIELDS } from '../../../initializers'
3import { exists, isArray, isDateValid } from '../misc' 3import { exists, isArray, isDateValid } from '../misc'
4import { isActivityPubUrlValid, isBaseActivityValid } from './misc' 4import { isActivityPubUrlValid, isBaseActivityValid } from './misc'
5 5
6function isVideoCommentCreateActivityValid (activity: any) {
7 return isBaseActivityValid(activity, 'Create') &&
8 sanitizeAndCheckVideoCommentObject(activity.object)
9}
10
11function sanitizeAndCheckVideoCommentObject (comment: any) { 6function sanitizeAndCheckVideoCommentObject (comment: any) {
12 if (!comment || comment.type !== 'Note') return false 7 if (!comment || comment.type !== 'Note') return false
13 8
@@ -25,15 +20,9 @@ function sanitizeAndCheckVideoCommentObject (comment: any) {
25 ) // Only accept public comments 20 ) // Only accept public comments
26} 21}
27 22
28function isVideoCommentDeleteActivityValid (activity: any) {
29 return isBaseActivityValid(activity, 'Delete')
30}
31
32// --------------------------------------------------------------------------- 23// ---------------------------------------------------------------------------
33 24
34export { 25export {
35 isVideoCommentCreateActivityValid,
36 isVideoCommentDeleteActivityValid,
37 sanitizeAndCheckVideoCommentObject 26 sanitizeAndCheckVideoCommentObject
38} 27}
39 28
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts
index 95fe824b9..0f34aab21 100644
--- a/server/helpers/custom-validators/activitypub/videos.ts
+++ b/server/helpers/custom-validators/activitypub/videos.ts
@@ -14,27 +14,11 @@ import { isActivityPubUrlValid, isBaseActivityValid, setValidAttributedTo } from
14import { VideoState } from '../../../../shared/models/videos' 14import { VideoState } from '../../../../shared/models/videos'
15import { isVideoAbuseReasonValid } from '../video-abuses' 15import { isVideoAbuseReasonValid } from '../video-abuses'
16 16
17function sanitizeAndCheckVideoTorrentCreateActivity (activity: any) {
18 return isBaseActivityValid(activity, 'Create') &&
19 sanitizeAndCheckVideoTorrentObject(activity.object)
20}
21
22function sanitizeAndCheckVideoTorrentUpdateActivity (activity: any) { 17function sanitizeAndCheckVideoTorrentUpdateActivity (activity: any) {
23 return isBaseActivityValid(activity, 'Update') && 18 return isBaseActivityValid(activity, 'Update') &&
24 sanitizeAndCheckVideoTorrentObject(activity.object) 19 sanitizeAndCheckVideoTorrentObject(activity.object)
25} 20}
26 21
27function isVideoTorrentDeleteActivityValid (activity: any) {
28 return isBaseActivityValid(activity, 'Delete')
29}
30
31function isVideoFlagValid (activity: any) {
32 return isBaseActivityValid(activity, 'Create') &&
33 activity.object.type === 'Flag' &&
34 isVideoAbuseReasonValid(activity.object.content) &&
35 isActivityPubUrlValid(activity.object.object)
36}
37
38function isActivityPubVideoDurationValid (value: string) { 22function isActivityPubVideoDurationValid (value: string) {
39 // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration 23 // https://www.w3.org/TR/activitystreams-vocabulary/#dfn-duration
40 return exists(value) && 24 return exists(value) &&
@@ -103,11 +87,8 @@ function isRemoteVideoUrlValid (url: any) {
103// --------------------------------------------------------------------------- 87// ---------------------------------------------------------------------------
104 88
105export { 89export {
106 sanitizeAndCheckVideoTorrentCreateActivity,
107 sanitizeAndCheckVideoTorrentUpdateActivity, 90 sanitizeAndCheckVideoTorrentUpdateActivity,
108 isVideoTorrentDeleteActivityValid,
109 isRemoteStringIdentifierValid, 91 isRemoteStringIdentifierValid,
110 isVideoFlagValid,
111 sanitizeAndCheckVideoTorrentObject, 92 sanitizeAndCheckVideoTorrentObject,
112 isRemoteVideoUrlValid 93 isRemoteVideoUrlValid
113} 94}
diff --git a/server/helpers/custom-validators/activitypub/view.ts b/server/helpers/custom-validators/activitypub/view.ts
index 7a3aca6f5..41d16469f 100644
--- a/server/helpers/custom-validators/activitypub/view.ts
+++ b/server/helpers/custom-validators/activitypub/view.ts
@@ -1,11 +1,11 @@
1import { isActivityPubUrlValid, isBaseActivityValid } from './misc' 1import { isActivityPubUrlValid } from './misc'
2 2
3function isViewActivityValid (activity: any) { 3function isViewActivityValid (activity: any) {
4 return isBaseActivityValid(activity, 'Create') && 4 return activity.type === 'View' &&
5 activity.object.type === 'View' && 5 isActivityPubUrlValid(activity.actor) &&
6 isActivityPubUrlValid(activity.object.actor) && 6 isActivityPubUrlValid(activity.object)
7 isActivityPubUrlValid(activity.object.object)
8} 7}
8
9// --------------------------------------------------------------------------- 9// ---------------------------------------------------------------------------
10 10
11export { 11export {
diff --git a/server/helpers/custom-validators/misc.ts b/server/helpers/custom-validators/misc.ts
index 6d10a65a8..b6f0ebe6f 100644
--- a/server/helpers/custom-validators/misc.ts
+++ b/server/helpers/custom-validators/misc.ts
@@ -9,6 +9,10 @@ function isArray (value: any) {
9 return Array.isArray(value) 9 return Array.isArray(value)
10} 10}
11 11
12function isNotEmptyIntArray (value: any) {
13 return Array.isArray(value) && value.every(v => validator.isInt('' + v)) && value.length !== 0
14}
15
12function isDateValid (value: string) { 16function isDateValid (value: string) {
13 return exists(value) && validator.isISO8601(value) 17 return exists(value) && validator.isISO8601(value)
14} 18}
@@ -78,6 +82,7 @@ function isFileValid (
78 82
79export { 83export {
80 exists, 84 exists,
85 isNotEmptyIntArray,
81 isArray, 86 isArray,
82 isIdValid, 87 isIdValid,
83 isUUIDValid, 88 isUUIDValid,
diff --git a/server/helpers/custom-validators/servers.ts b/server/helpers/custom-validators/servers.ts
index d5021bf38..18c80ec8f 100644
--- a/server/helpers/custom-validators/servers.ts
+++ b/server/helpers/custom-validators/servers.ts
@@ -3,6 +3,7 @@ import 'express-validator'
3 3
4import { isArray, exists } from './misc' 4import { isArray, exists } from './misc'
5import { isTestInstance } from '../core-utils' 5import { isTestInstance } from '../core-utils'
6import { CONSTRAINTS_FIELDS } from '../../initializers'
6 7
7function isHostValid (host: string) { 8function isHostValid (host: string) {
8 const isURLOptions = { 9 const isURLOptions = {
@@ -26,9 +27,19 @@ function isEachUniqueHostValid (hosts: string[]) {
26 }) 27 })
27} 28}
28 29
30function isValidContactBody (value: any) {
31 return exists(value) && validator.isLength(value, CONSTRAINTS_FIELDS.CONTACT_FORM.BODY)
32}
33
34function isValidContactFromName (value: any) {
35 return exists(value) && validator.isLength(value, CONSTRAINTS_FIELDS.CONTACT_FORM.FROM_NAME)
36}
37
29// --------------------------------------------------------------------------- 38// ---------------------------------------------------------------------------
30 39
31export { 40export {
41 isValidContactBody,
42 isValidContactFromName,
32 isEachUniqueHostValid, 43 isEachUniqueHostValid,
33 isHostValid 44 isHostValid
34} 45}
diff --git a/server/helpers/custom-validators/user-notifications.ts b/server/helpers/custom-validators/user-notifications.ts
new file mode 100644
index 000000000..02ea3bbc2
--- /dev/null
+++ b/server/helpers/custom-validators/user-notifications.ts
@@ -0,0 +1,23 @@
1import { exists } from './misc'
2import * as validator from 'validator'
3import { UserNotificationType } from '../../../shared/models/users'
4import { UserNotificationSettingValue } from '../../../shared/models/users/user-notification-setting.model'
5
6function isUserNotificationTypeValid (value: any) {
7 return exists(value) && validator.isInt('' + value) && UserNotificationType[value] !== undefined
8}
9
10function isUserNotificationSettingValid (value: any) {
11 return exists(value) &&
12 validator.isInt('' + value) && (
13 value === UserNotificationSettingValue.NONE ||
14 value === UserNotificationSettingValue.WEB ||
15 value === UserNotificationSettingValue.EMAIL ||
16 value === (UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL)
17 )
18}
19
20export {
21 isUserNotificationSettingValid,
22 isUserNotificationTypeValid
23}
diff --git a/server/helpers/custom-validators/users.ts b/server/helpers/custom-validators/users.ts
index 1cb5e5b0f..80652b479 100644
--- a/server/helpers/custom-validators/users.ts
+++ b/server/helpers/custom-validators/users.ts
@@ -46,6 +46,10 @@ function isUserWebTorrentEnabledValid (value: any) {
46 return isBooleanValid(value) 46 return isBooleanValid(value)
47} 47}
48 48
49function isUserVideosHistoryEnabledValid (value: any) {
50 return isBooleanValid(value)
51}
52
49function isUserAutoPlayVideoValid (value: any) { 53function isUserAutoPlayVideoValid (value: any) {
50 return isBooleanValid(value) 54 return isBooleanValid(value)
51} 55}
@@ -73,6 +77,7 @@ function isAvatarFile (files: { [ fieldname: string ]: Express.Multer.File[] } |
73// --------------------------------------------------------------------------- 77// ---------------------------------------------------------------------------
74 78
75export { 79export {
80 isUserVideosHistoryEnabledValid,
76 isUserBlockedValid, 81 isUserBlockedValid,
77 isUserPasswordValid, 82 isUserPasswordValid,
78 isUserBlockedReasonValid, 83 isUserBlockedReasonValid,
diff --git a/server/helpers/custom-validators/video-captions.ts b/server/helpers/custom-validators/video-captions.ts
index 177e9e86e..b33d90e18 100644
--- a/server/helpers/custom-validators/video-captions.ts
+++ b/server/helpers/custom-validators/video-captions.ts
@@ -1,4 +1,4 @@
1import { CONSTRAINTS_FIELDS, VIDEO_CAPTIONS_MIMETYPE_EXT, VIDEO_LANGUAGES } from '../../initializers' 1import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_LANGUAGES } from '../../initializers'
2import { exists, isFileValid } from './misc' 2import { exists, isFileValid } from './misc'
3import { Response } from 'express' 3import { Response } from 'express'
4import { VideoModel } from '../../models/video/video' 4import { VideoModel } from '../../models/video/video'
@@ -8,7 +8,7 @@ function isVideoCaptionLanguageValid (value: any) {
8 return exists(value) && VIDEO_LANGUAGES[ value ] !== undefined 8 return exists(value) && VIDEO_LANGUAGES[ value ] !== undefined
9} 9}
10 10
11const videoCaptionTypes = Object.keys(VIDEO_CAPTIONS_MIMETYPE_EXT) 11const videoCaptionTypes = Object.keys(MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT)
12 .concat([ 'application/octet-stream' ]) // MacOS sends application/octet-stream >< 12 .concat([ 'application/octet-stream' ]) // MacOS sends application/octet-stream ><
13 .map(m => `(${m})`) 13 .map(m => `(${m})`)
14const videoCaptionTypesRegex = videoCaptionTypes.join('|') 14const videoCaptionTypesRegex = videoCaptionTypes.join('|')
diff --git a/server/helpers/custom-validators/video-imports.ts b/server/helpers/custom-validators/video-imports.ts
index 4d6ab1fa4..ce9e9193c 100644
--- a/server/helpers/custom-validators/video-imports.ts
+++ b/server/helpers/custom-validators/video-imports.ts
@@ -1,7 +1,7 @@
1import 'express-validator' 1import 'express-validator'
2import 'multer' 2import 'multer'
3import * as validator from 'validator' 3import * as validator from 'validator'
4import { CONSTRAINTS_FIELDS, TORRENT_MIMETYPE_EXT, VIDEO_IMPORT_STATES } from '../../initializers' 4import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_IMPORT_STATES } from '../../initializers'
5import { exists, isFileValid } from './misc' 5import { exists, isFileValid } from './misc'
6import * as express from 'express' 6import * as express from 'express'
7import { VideoImportModel } from '../../models/video/video-import' 7import { VideoImportModel } from '../../models/video/video-import'
@@ -24,7 +24,7 @@ function isVideoImportStateValid (value: any) {
24 return exists(value) && VIDEO_IMPORT_STATES[ value ] !== undefined 24 return exists(value) && VIDEO_IMPORT_STATES[ value ] !== undefined
25} 25}
26 26
27const videoTorrentImportTypes = Object.keys(TORRENT_MIMETYPE_EXT).map(m => `(${m})`) 27const videoTorrentImportTypes = Object.keys(MIMETYPES.TORRENT.MIMETYPE_EXT).map(m => `(${m})`)
28const videoTorrentImportRegex = videoTorrentImportTypes.join('|') 28const videoTorrentImportRegex = videoTorrentImportTypes.join('|')
29function isVideoImportTorrentFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { 29function isVideoImportTorrentFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
30 return isFileValid(files, videoTorrentImportRegex, 'torrentfile', CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_FILE.FILE_SIZE.max, true) 30 return isFileValid(files, videoTorrentImportRegex, 'torrentfile', CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_FILE.FILE_SIZE.max, true)
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts
index a13b09ac8..95e256b8f 100644
--- a/server/helpers/custom-validators/videos.ts
+++ b/server/helpers/custom-validators/videos.ts
@@ -5,10 +5,9 @@ import 'multer'
5import * as validator from 'validator' 5import * as validator from 'validator'
6import { UserRight, VideoFilter, VideoPrivacy, VideoRateType } from '../../../shared' 6import { UserRight, VideoFilter, VideoPrivacy, VideoRateType } from '../../../shared'
7import { 7import {
8 CONSTRAINTS_FIELDS, 8 CONSTRAINTS_FIELDS, MIMETYPES,
9 VIDEO_CATEGORIES, 9 VIDEO_CATEGORIES,
10 VIDEO_LICENCES, 10 VIDEO_LICENCES,
11 VIDEO_MIMETYPE_EXT,
12 VIDEO_PRIVACIES, 11 VIDEO_PRIVACIES,
13 VIDEO_RATE_TYPES, 12 VIDEO_RATE_TYPES,
14 VIDEO_STATES 13 VIDEO_STATES
@@ -83,10 +82,15 @@ function isVideoRatingTypeValid (value: string) {
83 return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1 82 return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
84} 83}
85 84
86const videoFileTypes = Object.keys(VIDEO_MIMETYPE_EXT).map(m => `(${m})`) 85function isVideoFileExtnameValid (value: string) {
87const videoFileTypesRegex = videoFileTypes.join('|') 86 return exists(value) && MIMETYPES.VIDEO.EXT_MIMETYPE[value] !== undefined
87}
88 88
89function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) { 89function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
90 const videoFileTypesRegex = Object.keys(MIMETYPES.VIDEO.MIMETYPE_EXT)
91 .map(m => `(${m})`)
92 .join('|')
93
90 return isFileValid(files, videoFileTypesRegex, 'videofile', null) 94 return isFileValid(files, videoFileTypesRegex, 'videofile', null)
91} 95}
92 96
@@ -221,6 +225,7 @@ export {
221 isVideoStateValid, 225 isVideoStateValid,
222 isVideoViewsValid, 226 isVideoViewsValid,
223 isVideoRatingTypeValid, 227 isVideoRatingTypeValid,
228 isVideoFileExtnameValid,
224 isVideoDurationValid, 229 isVideoDurationValid,
225 isVideoTagValid, 230 isVideoTagValid,
226 isVideoPrivacyValid, 231 isVideoPrivacyValid,
diff --git a/server/helpers/express-utils.ts b/server/helpers/express-utils.ts
index 162fe2244..9a72ee96d 100644
--- a/server/helpers/express-utils.ts
+++ b/server/helpers/express-utils.ts
@@ -7,12 +7,12 @@ import { extname } from 'path'
7import { isArray } from './custom-validators/misc' 7import { isArray } from './custom-validators/misc'
8import { UserModel } from '../models/account/user' 8import { UserModel } from '../models/account/user'
9 9
10function buildNSFWFilter (res: express.Response, paramNSFW?: string) { 10function buildNSFWFilter (res?: express.Response, paramNSFW?: string) {
11 if (paramNSFW === 'true') return true 11 if (paramNSFW === 'true') return true
12 if (paramNSFW === 'false') return false 12 if (paramNSFW === 'false') return false
13 if (paramNSFW === 'both') return undefined 13 if (paramNSFW === 'both') return undefined
14 14
15 if (res.locals.oauth) { 15 if (res && res.locals.oauth) {
16 const user: UserModel = res.locals.oauth.token.User 16 const user: UserModel = res.locals.oauth.token.User
17 17
18 // User does not want NSFW videos 18 // User does not want NSFW videos
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts
index b59e7e40e..132f4690e 100644
--- a/server/helpers/ffmpeg-utils.ts
+++ b/server/helpers/ffmpeg-utils.ts
@@ -41,7 +41,7 @@ async function getVideoFileResolution (path: string) {
41async function getVideoFileFPS (path: string) { 41async function getVideoFileFPS (path: string) {
42 const videoStream = await getVideoFileStream(path) 42 const videoStream = await getVideoFileStream(path)
43 43
44 for (const key of [ 'r_frame_rate' , 'avg_frame_rate' ]) { 44 for (const key of [ 'avg_frame_rate', 'r_frame_rate' ]) {
45 const valuesText: string = videoStream[key] 45 const valuesText: string = videoStream[key]
46 if (!valuesText) continue 46 if (!valuesText) continue
47 47
@@ -184,7 +184,7 @@ function getVideoFileStream (path: string) {
184 if (err) return rej(err) 184 if (err) return rej(err)
185 185
186 const videoStream = metadata.streams.find(s => s.codec_type === 'video') 186 const videoStream = metadata.streams.find(s => s.codec_type === 'video')
187 if (!videoStream) throw new Error('Cannot find video stream of ' + path) 187 if (!videoStream) return rej(new Error('Cannot find video stream of ' + path))
188 188
189 return res(videoStream) 189 return res(videoStream)
190 }) 190 })
@@ -328,10 +328,10 @@ async function presetH264 (command: ffmpeg.FfmpegCommand, resolution: VideoResol
328 const audioCodecName = parsedAudio.audioStream[ 'codec_name' ] 328 const audioCodecName = parsedAudio.audioStream[ 'codec_name' ]
329 let bitrate: number 329 let bitrate: number
330 if (audio.bitrate[ audioCodecName ]) { 330 if (audio.bitrate[ audioCodecName ]) {
331 bitrate = audio.bitrate[ audioCodecName ](parsedAudio.audioStream[ 'bit_rate' ]) 331 localCommand = localCommand.audioCodec('aac')
332 332
333 if (bitrate === -1) localCommand = localCommand.audioCodec('copy') 333 bitrate = audio.bitrate[ audioCodecName ](parsedAudio.audioStream[ 'bit_rate' ])
334 else if (bitrate !== undefined) localCommand = localCommand.audioBitrate(bitrate) 334 if (bitrate !== undefined && bitrate !== -1) localCommand = localCommand.audioBitrate(bitrate)
335 } 335 }
336 } 336 }
337 337
diff --git a/server/helpers/image-utils.ts b/server/helpers/image-utils.ts
index da3285b13..e43ea3f1d 100644
--- a/server/helpers/image-utils.ts
+++ b/server/helpers/image-utils.ts
@@ -1,6 +1,7 @@
1import 'multer' 1import 'multer'
2import * as sharp from 'sharp' 2import * as sharp from 'sharp'
3import { move, remove } from 'fs-extra' 3import { readFile, remove } from 'fs-extra'
4import { logger } from './logger'
4 5
5async function processImage ( 6async function processImage (
6 physicalFile: { path: string }, 7 physicalFile: { path: string },
@@ -11,14 +12,11 @@ async function processImage (
11 throw new Error('Sharp needs an input path different that the output path.') 12 throw new Error('Sharp needs an input path different that the output path.')
12 } 13 }
13 14
14 const sharpInstance = sharp(physicalFile.path) 15 logger.debug('Processing image %s to %s.', physicalFile.path, destination)
15 const metadata = await sharpInstance.metadata()
16 16
17 // No need to resize 17 // Avoid sharp cache
18 if (metadata.width === newSize.width && metadata.height === newSize.height) { 18 const buf = await readFile(physicalFile.path)
19 await move(physicalFile.path, destination, { overwrite: true }) 19 const sharpInstance = sharp(buf)
20 return
21 }
22 20
23 await remove(destination) 21 await remove(destination)
24 22
diff --git a/server/helpers/regexp.ts b/server/helpers/regexp.ts
new file mode 100644
index 000000000..2336654b0
--- /dev/null
+++ b/server/helpers/regexp.ts
@@ -0,0 +1,23 @@
1// Thanks to https://regex101.com
2function regexpCapture (str: string, regex: RegExp, maxIterations = 100) {
3 let m: RegExpExecArray
4 let i = 0
5 let result: RegExpExecArray[] = []
6
7 // tslint:disable:no-conditional-assignment
8 while ((m = regex.exec(str)) !== null && i < maxIterations) {
9 // This is necessary to avoid infinite loops with zero-width matches
10 if (m.index === regex.lastIndex) {
11 regex.lastIndex++
12 }
13
14 result.push(m)
15 i++
16 }
17
18 return result
19}
20
21export {
22 regexpCapture
23}
diff --git a/server/helpers/requests.ts b/server/helpers/requests.ts
index 805930a9f..3fc776f1a 100644
--- a/server/helpers/requests.ts
+++ b/server/helpers/requests.ts
@@ -1,8 +1,9 @@
1import * as Bluebird from 'bluebird' 1import * as Bluebird from 'bluebird'
2import { createWriteStream } from 'fs-extra' 2import { createWriteStream } from 'fs-extra'
3import * as request from 'request' 3import * as request from 'request'
4import { ACTIVITY_PUB } from '../initializers' 4import { ACTIVITY_PUB, CONFIG } from '../initializers'
5import { processImage } from './image-utils' 5import { processImage } from './image-utils'
6import { join } from 'path'
6 7
7function doRequest <T> ( 8function doRequest <T> (
8 requestOptions: request.CoreOptions & request.UriOptions & { activityPub?: boolean } 9 requestOptions: request.CoreOptions & request.UriOptions & { activityPub?: boolean }
@@ -28,11 +29,11 @@ function doRequestAndSaveToFile (requestOptions: request.CoreOptions & request.U
28 }) 29 })
29} 30}
30 31
31async function downloadImage (url: string, destPath: string, size: { width: number, height: number }) { 32async function downloadImage (url: string, destDir: string, destName: string, size: { width: number, height: number }) {
32 const tmpPath = destPath + '.tmp' 33 const tmpPath = join(CONFIG.STORAGE.TMP_DIR, 'pending-' + destName)
33
34 await doRequestAndSaveToFile({ method: 'GET', uri: url }, tmpPath) 34 await doRequestAndSaveToFile({ method: 'GET', uri: url }, tmpPath)
35 35
36 const destPath = join(destDir, destName)
36 await processImage({ path: tmpPath }, destPath, size) 37 await processImage({ path: tmpPath }, destPath, size)
37} 38}
38 39
diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts
index 5c9d6fe2f..3c3406e38 100644
--- a/server/helpers/utils.ts
+++ b/server/helpers/utils.ts
@@ -7,6 +7,7 @@ import { join } from 'path'
7import { Instance as ParseTorrent } from 'parse-torrent' 7import { Instance as ParseTorrent } from 'parse-torrent'
8import { remove } from 'fs-extra' 8import { remove } from 'fs-extra'
9import * as memoizee from 'memoizee' 9import * as memoizee from 'memoizee'
10import { isArray } from './custom-validators/misc'
10 11
11function deleteFileAsync (path: string) { 12function deleteFileAsync (path: string) {
12 remove(path) 13 remove(path)
@@ -19,10 +20,7 @@ async function generateRandomString (size: number) {
19 return raw.toString('hex') 20 return raw.toString('hex')
20} 21}
21 22
22interface FormattableToJSON { 23interface FormattableToJSON { toFormattedJSON (args?: any) }
23 toFormattedJSON (args?: any)
24}
25
26function getFormattedObjects<U, T extends FormattableToJSON> (objects: T[], objectsTotal: number, formattedArg?: any) { 24function getFormattedObjects<U, T extends FormattableToJSON> (objects: T[], objectsTotal: number, formattedArg?: any) {
27 const formattedObjects: U[] = [] 25 const formattedObjects: U[] = []
28 26
@@ -46,11 +44,11 @@ const getServerActor = memoizee(async function () {
46 return actor 44 return actor
47}) 45})
48 46
49function generateVideoTmpPath (target: string | ParseTorrent) { 47function generateVideoImportTmpPath (target: string | ParseTorrent) {
50 const id = typeof target === 'string' ? target : target.infoHash 48 const id = typeof target === 'string' ? target : target.infoHash
51 49
52 const hash = sha256(id) 50 const hash = sha256(id)
53 return join(CONFIG.STORAGE.VIDEOS_DIR, hash + '-import.mp4') 51 return join(CONFIG.STORAGE.TMP_DIR, hash + '-import.mp4')
54} 52}
55 53
56function getSecureTorrentName (originalName: string) { 54function getSecureTorrentName (originalName: string) {
@@ -103,6 +101,6 @@ export {
103 getSecureTorrentName, 101 getSecureTorrentName,
104 getServerActor, 102 getServerActor,
105 getServerCommit, 103 getServerCommit,
106 generateVideoTmpPath, 104 generateVideoImportTmpPath,
107 getUUIDFromFilename 105 getUUIDFromFilename
108} 106}
diff --git a/server/helpers/webtorrent.ts b/server/helpers/webtorrent.ts
index ce35b87da..3c9a0b96a 100644
--- a/server/helpers/webtorrent.ts
+++ b/server/helpers/webtorrent.ts
@@ -1,5 +1,5 @@
1import { logger } from './logger' 1import { logger } from './logger'
2import { generateVideoTmpPath } from './utils' 2import { generateVideoImportTmpPath } from './utils'
3import * as WebTorrent from 'webtorrent' 3import * as WebTorrent from 'webtorrent'
4import { createWriteStream, ensureDir, remove } from 'fs-extra' 4import { createWriteStream, ensureDir, remove } from 'fs-extra'
5import { CONFIG } from '../initializers' 5import { CONFIG } from '../initializers'
@@ -9,10 +9,10 @@ async function downloadWebTorrentVideo (target: { magnetUri: string, torrentName
9 const id = target.magnetUri || target.torrentName 9 const id = target.magnetUri || target.torrentName
10 let timer 10 let timer
11 11
12 const path = generateVideoTmpPath(id) 12 const path = generateVideoImportTmpPath(id)
13 logger.info('Importing torrent video %s', id) 13 logger.info('Importing torrent video %s', id)
14 14
15 const directoryPath = join(CONFIG.STORAGE.VIDEOS_DIR, 'import') 15 const directoryPath = join(CONFIG.STORAGE.TMP_DIR, 'webtorrent')
16 await ensureDir(directoryPath) 16 await ensureDir(directoryPath)
17 17
18 return new Promise<string>((res, rej) => { 18 return new Promise<string>((res, rej) => {
diff --git a/server/helpers/youtube-dl.ts b/server/helpers/youtube-dl.ts
index 2a5663042..b74351b42 100644
--- a/server/helpers/youtube-dl.ts
+++ b/server/helpers/youtube-dl.ts
@@ -1,7 +1,7 @@
1import { truncate } from 'lodash' 1import { truncate } from 'lodash'
2import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES } from '../initializers' 2import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES } from '../initializers'
3import { logger } from './logger' 3import { logger } from './logger'
4import { generateVideoTmpPath } from './utils' 4import { generateVideoImportTmpPath } from './utils'
5import { join } from 'path' 5import { join } from 'path'
6import { root } from './core-utils' 6import { root } from './core-utils'
7import { ensureDir, writeFile, remove } from 'fs-extra' 7import { ensureDir, writeFile, remove } from 'fs-extra'
@@ -40,7 +40,7 @@ function getYoutubeDLInfo (url: string, opts?: string[]): Promise<YoutubeDLInfo>
40} 40}
41 41
42function downloadYoutubeDLVideo (url: string, timeout: number) { 42function downloadYoutubeDLVideo (url: string, timeout: number) {
43 const path = generateVideoTmpPath(url) 43 const path = generateVideoImportTmpPath(url)
44 let timer 44 let timer
45 45
46 logger.info('Importing youtubeDL video %s', url) 46 logger.info('Importing youtubeDL video %s', url)
diff --git a/server/initializers/checker-after-init.ts b/server/initializers/checker-after-init.ts
index 72d846957..955d55206 100644
--- a/server/initializers/checker-after-init.ts
+++ b/server/initializers/checker-after-init.ts
@@ -10,6 +10,7 @@ import { getServerActor } from '../helpers/utils'
10import { RecentlyAddedStrategy } from '../../shared/models/redundancy' 10import { RecentlyAddedStrategy } from '../../shared/models/redundancy'
11import { isArray } from '../helpers/custom-validators/misc' 11import { isArray } from '../helpers/custom-validators/misc'
12import { uniq } from 'lodash' 12import { uniq } from 'lodash'
13import { Emailer } from '../lib/emailer'
13 14
14async function checkActivityPubUrls () { 15async function checkActivityPubUrls () {
15 const actor = await getServerActor() 16 const actor = await getServerActor()
@@ -32,9 +33,19 @@ async function checkActivityPubUrls () {
32// Some checks on configuration files 33// Some checks on configuration files
33// Return an error message, or null if everything is okay 34// Return an error message, or null if everything is okay
34function checkConfig () { 35function checkConfig () {
35 const defaultNSFWPolicy = CONFIG.INSTANCE.DEFAULT_NSFW_POLICY 36
37 if (!Emailer.isEnabled()) {
38 if (CONFIG.SIGNUP.ENABLED && CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) {
39 return 'Emailer is disabled but you require signup email verification.'
40 }
41
42 if (CONFIG.CONTACT_FORM.ENABLED) {
43 logger.warn('Emailer is disabled so the contact form will not work.')
44 }
45 }
36 46
37 // NSFW policy 47 // NSFW policy
48 const defaultNSFWPolicy = CONFIG.INSTANCE.DEFAULT_NSFW_POLICY
38 { 49 {
39 const available = [ 'do_not_list', 'blur', 'display' ] 50 const available = [ 'do_not_list', 'blur', 'display' ]
40 if (available.indexOf(defaultNSFWPolicy) === -1) { 51 if (available.indexOf(defaultNSFWPolicy) === -1) {
@@ -68,6 +79,7 @@ function checkConfig () {
68 } 79 }
69 } 80 }
70 81
82 // Check storage directory locations
71 if (isProdInstance()) { 83 if (isProdInstance()) {
72 const configStorage = config.get('storage') 84 const configStorage = config.get('storage')
73 for (const key of Object.keys(configStorage)) { 85 for (const key of Object.keys(configStorage)) {
diff --git a/server/initializers/checker-before-init.ts b/server/initializers/checker-before-init.ts
index 9dfb5d68c..7905d9ffa 100644
--- a/server/initializers/checker-before-init.ts
+++ b/server/initializers/checker-before-init.ts
@@ -12,13 +12,14 @@ function checkMissedConfig () {
12 'database.hostname', 'database.port', 'database.suffix', 'database.username', 'database.password', 'database.pool.max', 12 'database.hostname', 'database.port', 'database.suffix', 'database.username', 'database.password', 'database.pool.max',
13 'smtp.hostname', 'smtp.port', 'smtp.username', 'smtp.password', 'smtp.tls', 'smtp.from_address', 13 'smtp.hostname', 'smtp.port', 'smtp.username', 'smtp.password', 'smtp.tls', 'smtp.from_address',
14 'storage.avatars', 'storage.videos', 'storage.logs', 'storage.previews', 'storage.thumbnails', 'storage.torrents', 'storage.cache', 14 'storage.avatars', 'storage.videos', 'storage.logs', 'storage.previews', 'storage.thumbnails', 'storage.torrents', 'storage.cache',
15 'storage.redundancy', 'storage.tmp',
15 'log.level', 16 'log.level',
16 'user.video_quota', 'user.video_quota_daily', 17 'user.video_quota', 'user.video_quota_daily',
17 'cache.previews.size', 'admin.email', 18 'cache.previews.size', 'admin.email', 'contact_form.enabled',
18 'signup.enabled', 'signup.limit', 'signup.requires_email_verification', 19 'signup.enabled', 'signup.limit', 'signup.requires_email_verification',
19 'signup.filters.cidr.whitelist', 'signup.filters.cidr.blacklist', 20 'signup.filters.cidr.whitelist', 'signup.filters.cidr.blacklist',
20 'redundancy.videos.strategies', 'redundancy.videos.check_interval', 21 'redundancy.videos.strategies', 'redundancy.videos.check_interval',
21 'transcoding.enabled', 'transcoding.threads', 22 'transcoding.enabled', 'transcoding.threads', 'transcoding.allow_additional_extensions',
22 'import.videos.http.enabled', 'import.videos.torrent.enabled', 23 'import.videos.http.enabled', 'import.videos.torrent.enabled',
23 'trending.videos.interval_days', 24 'trending.videos.interval_days',
24 'instance.name', 'instance.short_description', 'instance.description', 'instance.terms', 'instance.default_client_route', 25 'instance.name', 'instance.short_description', 'instance.description', 'instance.terms', 'instance.default_client_route',
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index aa243859c..6f3ebb9aa 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -16,7 +16,7 @@ let config: IConfig = require('config')
16 16
17// --------------------------------------------------------------------------- 17// ---------------------------------------------------------------------------
18 18
19const LAST_MIGRATION_VERSION = 290 19const LAST_MIGRATION_VERSION = 325
20 20
21// --------------------------------------------------------------------------- 21// ---------------------------------------------------------------------------
22 22
@@ -50,7 +50,9 @@ const SORTABLE_COLUMNS = {
50 VIDEO_CHANNELS_SEARCH: [ 'match', 'displayName', 'createdAt' ], 50 VIDEO_CHANNELS_SEARCH: [ 'match', 'displayName', 'createdAt' ],
51 51
52 ACCOUNTS_BLOCKLIST: [ 'createdAt' ], 52 ACCOUNTS_BLOCKLIST: [ 'createdAt' ],
53 SERVERS_BLOCKLIST: [ 'createdAt' ] 53 SERVERS_BLOCKLIST: [ 'createdAt' ],
54
55 USER_NOTIFICATIONS: [ 'createdAt' ]
54} 56}
55 57
56const OAUTH_LIFETIME = { 58const OAUTH_LIFETIME = {
@@ -61,6 +63,7 @@ const OAUTH_LIFETIME = {
61const ROUTE_CACHE_LIFETIME = { 63const ROUTE_CACHE_LIFETIME = {
62 FEEDS: '15 minutes', 64 FEEDS: '15 minutes',
63 ROBOTS: '2 hours', 65 ROBOTS: '2 hours',
66 SITEMAP: '1 day',
64 SECURITYTXT: '2 hours', 67 SECURITYTXT: '2 hours',
65 NODEINFO: '10 minutes', 68 NODEINFO: '10 minutes',
66 DNT_POLICY: '1 week', 69 DNT_POLICY: '1 week',
@@ -143,7 +146,7 @@ const VIDEO_IMPORT_TIMEOUT = 1000 * 3600 // 1 hour
143 146
144// 1 hour 147// 1 hour
145let SCHEDULER_INTERVALS_MS = { 148let SCHEDULER_INTERVALS_MS = {
146 badActorFollow: 60000 * 60, // 1 hour 149 actorFollowScores: 60000 * 60, // 1 hour
147 removeOldJobs: 60000 * 60, // 1 hour 150 removeOldJobs: 60000 * 60, // 1 hour
148 updateVideos: 60000, // 1 minute 151 updateVideos: 60000, // 1 minute
149 youtubeDLUpdate: 60000 * 60 * 24 // 1 day 152 youtubeDLUpdate: 60000 * 60 * 24 // 1 day
@@ -185,9 +188,11 @@ const CONFIG = {
185 FROM_ADDRESS: config.get<string>('smtp.from_address') 188 FROM_ADDRESS: config.get<string>('smtp.from_address')
186 }, 189 },
187 STORAGE: { 190 STORAGE: {
191 TMP_DIR: buildPath(config.get<string>('storage.tmp')),
188 AVATARS_DIR: buildPath(config.get<string>('storage.avatars')), 192 AVATARS_DIR: buildPath(config.get<string>('storage.avatars')),
189 LOG_DIR: buildPath(config.get<string>('storage.logs')), 193 LOG_DIR: buildPath(config.get<string>('storage.logs')),
190 VIDEOS_DIR: buildPath(config.get<string>('storage.videos')), 194 VIDEOS_DIR: buildPath(config.get<string>('storage.videos')),
195 REDUNDANCY_DIR: buildPath(config.get<string>('storage.redundancy')),
191 THUMBNAILS_DIR: buildPath(config.get<string>('storage.thumbnails')), 196 THUMBNAILS_DIR: buildPath(config.get<string>('storage.thumbnails')),
192 PREVIEWS_DIR: buildPath(config.get<string>('storage.previews')), 197 PREVIEWS_DIR: buildPath(config.get<string>('storage.previews')),
193 CAPTIONS_DIR: buildPath(config.get<string>('storage.captions')), 198 CAPTIONS_DIR: buildPath(config.get<string>('storage.captions')),
@@ -226,6 +231,9 @@ const CONFIG = {
226 ADMIN: { 231 ADMIN: {
227 get EMAIL () { return config.get<string>('admin.email') } 232 get EMAIL () { return config.get<string>('admin.email') }
228 }, 233 },
234 CONTACT_FORM: {
235 get ENABLED () { return config.get<boolean>('contact_form.enabled') }
236 },
229 SIGNUP: { 237 SIGNUP: {
230 get ENABLED () { return config.get<boolean>('signup.enabled') }, 238 get ENABLED () { return config.get<boolean>('signup.enabled') },
231 get LIMIT () { return config.get<number>('signup.limit') }, 239 get LIMIT () { return config.get<number>('signup.limit') },
@@ -243,6 +251,7 @@ const CONFIG = {
243 }, 251 },
244 TRANSCODING: { 252 TRANSCODING: {
245 get ENABLED () { return config.get<boolean>('transcoding.enabled') }, 253 get ENABLED () { return config.get<boolean>('transcoding.enabled') },
254 get ALLOW_ADDITIONAL_EXTENSIONS () { return config.get<boolean>('transcoding.allow_additional_extensions') },
246 get THREADS () { return config.get<number>('transcoding.threads') }, 255 get THREADS () { return config.get<number>('transcoding.threads') },
247 RESOLUTIONS: { 256 RESOLUTIONS: {
248 get '240p' () { return config.get<boolean>('transcoding.resolutions.240p') }, 257 get '240p' () { return config.get<boolean>('transcoding.resolutions.240p') },
@@ -286,6 +295,7 @@ const CONFIG = {
286 get SECURITYTXT_CONTACT () { return config.get<string>('admin.email') } 295 get SECURITYTXT_CONTACT () { return config.get<string>('admin.email') }
287 }, 296 },
288 SERVICES: { 297 SERVICES: {
298 get 'CSP-LOGGER' () { return config.get<string>('services.csp-logger') },
289 TWITTER: { 299 TWITTER: {
290 get USERNAME () { return config.get<string>('services.twitter.username') }, 300 get USERNAME () { return config.get<string>('services.twitter.username') },
291 get WHITELISTED () { return config.get<boolean>('services.twitter.whitelisted') } 301 get WHITELISTED () { return config.get<boolean>('services.twitter.whitelisted') }
@@ -295,25 +305,25 @@ const CONFIG = {
295 305
296// --------------------------------------------------------------------------- 306// ---------------------------------------------------------------------------
297 307
298const CONSTRAINTS_FIELDS = { 308let CONSTRAINTS_FIELDS = {
299 USERS: { 309 USERS: {
300 NAME: { min: 3, max: 120 }, // Length 310 NAME: { min: 1, max: 120 }, // Length
301 DESCRIPTION: { min: 3, max: 1000 }, // Length 311 DESCRIPTION: { min: 3, max: 1000 }, // Length
302 USERNAME: { min: 3, max: 20 }, // Length 312 USERNAME: { min: 1, max: 50 }, // Length
303 PASSWORD: { min: 6, max: 255 }, // Length 313 PASSWORD: { min: 6, max: 255 }, // Length
304 VIDEO_QUOTA: { min: -1 }, 314 VIDEO_QUOTA: { min: -1 },
305 VIDEO_QUOTA_DAILY: { min: -1 }, 315 VIDEO_QUOTA_DAILY: { min: -1 },
306 BLOCKED_REASON: { min: 3, max: 250 } // Length 316 BLOCKED_REASON: { min: 3, max: 250 } // Length
307 }, 317 },
308 VIDEO_ABUSES: { 318 VIDEO_ABUSES: {
309 REASON: { min: 2, max: 300 }, // Length 319 REASON: { min: 2, max: 3000 }, // Length
310 MODERATION_COMMENT: { min: 2, max: 300 } // Length 320 MODERATION_COMMENT: { min: 2, max: 3000 } // Length
311 }, 321 },
312 VIDEO_BLACKLIST: { 322 VIDEO_BLACKLIST: {
313 REASON: { min: 2, max: 300 } // Length 323 REASON: { min: 2, max: 300 } // Length
314 }, 324 },
315 VIDEO_CHANNELS: { 325 VIDEO_CHANNELS: {
316 NAME: { min: 3, max: 120 }, // Length 326 NAME: { min: 1, max: 120 }, // Length
317 DESCRIPTION: { min: 3, max: 1000 }, // Length 327 DESCRIPTION: { min: 3, max: 1000 }, // Length
318 SUPPORT: { min: 3, max: 1000 }, // Length 328 SUPPORT: { min: 3, max: 1000 }, // Length
319 URL: { min: 3, max: 2000 } // Length 329 URL: { min: 3, max: 2000 } // Length
@@ -354,7 +364,7 @@ const CONSTRAINTS_FIELDS = {
354 max: 2 * 1024 * 1024 // 2MB 364 max: 2 * 1024 * 1024 // 2MB
355 } 365 }
356 }, 366 },
357 EXTNAME: [ '.mp4', '.ogv', '.webm' ], 367 EXTNAME: buildVideosExtname(),
358 INFO_HASH: { min: 40, max: 40 }, // Length, info hash is 20 bytes length but we represent it in hexadecimal so 20 * 2 368 INFO_HASH: { min: 40, max: 40 }, // Length, info hash is 20 bytes length but we represent it in hexadecimal so 20 * 2
359 DURATION: { min: 0 }, // Number 369 DURATION: { min: 0 }, // Number
360 TAGS: { min: 0, max: 5 }, // Number of total tags 370 TAGS: { min: 0, max: 5 }, // Number of total tags
@@ -387,6 +397,10 @@ const CONSTRAINTS_FIELDS = {
387 }, 397 },
388 VIDEO_SHARE: { 398 VIDEO_SHARE: {
389 URL: { min: 3, max: 2000 } // Length 399 URL: { min: 3, max: 2000 } // Length
400 },
401 CONTACT_FORM: {
402 FROM_NAME: { min: 1, max: 120 }, // Length
403 BODY: { min: 3, max: 5000 } // Length
390 } 404 }
391} 405}
392 406
@@ -402,6 +416,8 @@ const RATES_LIMIT = {
402} 416}
403 417
404let VIDEO_VIEW_LIFETIME = 60000 * 60 // 1 hour 418let VIDEO_VIEW_LIFETIME = 60000 * 60 // 1 hour
419let CONTACT_FORM_LIFETIME = 60000 * 60 // 1 hour
420
405const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = { 421const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = {
406 MIN: 10, 422 MIN: 10,
407 AVERAGE: 30, 423 AVERAGE: 30,
@@ -477,27 +493,31 @@ const VIDEO_ABUSE_STATES = {
477 [VideoAbuseState.ACCEPTED]: 'Accepted' 493 [VideoAbuseState.ACCEPTED]: 'Accepted'
478} 494}
479 495
480const VIDEO_MIMETYPE_EXT = { 496const MIMETYPES = {
481 'video/webm': '.webm', 497 VIDEO: {
482 'video/ogg': '.ogv', 498 MIMETYPE_EXT: buildVideoMimetypeExt(),
483 'video/mp4': '.mp4' 499 EXT_MIMETYPE: null as { [ id: string ]: string }
484} 500 },
485const VIDEO_EXT_MIMETYPE = invert(VIDEO_MIMETYPE_EXT) 501 IMAGE: {
486 502 MIMETYPE_EXT: {
487const IMAGE_MIMETYPE_EXT = { 503 'image/png': '.png',
488 'image/png': '.png', 504 'image/jpg': '.jpg',
489 'image/jpg': '.jpg', 505 'image/jpeg': '.jpg'
490 'image/jpeg': '.jpg' 506 }
491} 507 },
492 508 VIDEO_CAPTIONS: {
493const VIDEO_CAPTIONS_MIMETYPE_EXT = { 509 MIMETYPE_EXT: {
494 'text/vtt': '.vtt', 510 'text/vtt': '.vtt',
495 'application/x-subrip': '.srt' 511 'application/x-subrip': '.srt'
496} 512 }
497 513 },
498const TORRENT_MIMETYPE_EXT = { 514 TORRENT: {
499 'application/x-bittorrent': '.torrent' 515 MIMETYPE_EXT: {
516 'application/x-bittorrent': '.torrent'
517 }
518 }
500} 519}
520MIMETYPES.VIDEO.EXT_MIMETYPE = invert(MIMETYPES.VIDEO.MIMETYPE_EXT)
501 521
502// --------------------------------------------------------------------------- 522// ---------------------------------------------------------------------------
503 523
@@ -523,7 +543,7 @@ const ACTIVITY_PUB = {
523 COLLECTION_ITEMS_PER_PAGE: 10, 543 COLLECTION_ITEMS_PER_PAGE: 10,
524 FETCH_PAGE_LIMIT: 100, 544 FETCH_PAGE_LIMIT: 100,
525 URL_MIME_TYPES: { 545 URL_MIME_TYPES: {
526 VIDEO: Object.keys(VIDEO_MIMETYPE_EXT), 546 VIDEO: Object.keys(MIMETYPES.VIDEO.MIMETYPE_EXT),
527 TORRENT: [ 'application/x-bittorrent' ], 547 TORRENT: [ 'application/x-bittorrent' ],
528 MAGNET: [ 'application/x-bittorrent;x-scheme-handler/magnet' ] 548 MAGNET: [ 'application/x-bittorrent;x-scheme-handler/magnet' ]
529 }, 549 },
@@ -569,6 +589,7 @@ const STATIC_PATHS = {
569 THUMBNAILS: '/static/thumbnails/', 589 THUMBNAILS: '/static/thumbnails/',
570 TORRENTS: '/static/torrents/', 590 TORRENTS: '/static/torrents/',
571 WEBSEED: '/static/webseed/', 591 WEBSEED: '/static/webseed/',
592 REDUNDANCY: '/static/redundancy/',
572 AVATARS: '/static/avatars/', 593 AVATARS: '/static/avatars/',
573 VIDEO_CAPTIONS: '/static/video-captions/' 594 VIDEO_CAPTIONS: '/static/video-captions/'
574} 595}
@@ -665,7 +686,7 @@ if (isTestInstance() === true) {
665 686
666 CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max = 100 * 1024 // 100KB 687 CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max = 100 * 1024 // 100KB
667 688
668 SCHEDULER_INTERVALS_MS.badActorFollow = 10000 689 SCHEDULER_INTERVALS_MS.actorFollowScores = 1000
669 SCHEDULER_INTERVALS_MS.removeOldJobs = 10000 690 SCHEDULER_INTERVALS_MS.removeOldJobs = 10000
670 SCHEDULER_INTERVALS_MS.updateVideos = 5000 691 SCHEDULER_INTERVALS_MS.updateVideos = 5000
671 REPEAT_JOBS['videos-views'] = { every: 5000 } 692 REPEAT_JOBS['videos-views'] = { every: 5000 }
@@ -673,6 +694,7 @@ if (isTestInstance() === true) {
673 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1 694 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1
674 695
675 VIDEO_VIEW_LIFETIME = 1000 // 1 second 696 VIDEO_VIEW_LIFETIME = 1000 // 1 second
697 CONTACT_FORM_LIFETIME = 1000 // 1 second
676 698
677 JOB_ATTEMPTS['email'] = 1 699 JOB_ATTEMPTS['email'] = 1
678 700
@@ -681,13 +703,12 @@ if (isTestInstance() === true) {
681 ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS = '0ms' 703 ROUTE_CACHE_LIFETIME.OVERVIEWS.VIDEOS = '0ms'
682} 704}
683 705
684updateWebserverConfig() 706updateWebserverUrls()
685 707
686// --------------------------------------------------------------------------- 708// ---------------------------------------------------------------------------
687 709
688export { 710export {
689 API_VERSION, 711 API_VERSION,
690 VIDEO_CAPTIONS_MIMETYPE_EXT,
691 AVATARS_SIZE, 712 AVATARS_SIZE,
692 ACCEPT_HEADERS, 713 ACCEPT_HEADERS,
693 BCRYPT_SALT_SIZE, 714 BCRYPT_SALT_SIZE,
@@ -715,7 +736,6 @@ export {
715 FEEDS, 736 FEEDS,
716 JOB_TTL, 737 JOB_TTL,
717 NSFW_POLICY_TYPES, 738 NSFW_POLICY_TYPES,
718 TORRENT_MIMETYPE_EXT,
719 STATIC_MAX_AGE, 739 STATIC_MAX_AGE,
720 STATIC_PATHS, 740 STATIC_PATHS,
721 VIDEO_IMPORT_TIMEOUT, 741 VIDEO_IMPORT_TIMEOUT,
@@ -728,7 +748,6 @@ export {
728 VIDEO_LICENCES, 748 VIDEO_LICENCES,
729 VIDEO_STATES, 749 VIDEO_STATES,
730 VIDEO_RATE_TYPES, 750 VIDEO_RATE_TYPES,
731 VIDEO_MIMETYPE_EXT,
732 VIDEO_TRANSCODING_FPS, 751 VIDEO_TRANSCODING_FPS,
733 FFMPEG_NICE, 752 FFMPEG_NICE,
734 VIDEO_ABUSE_STATES, 753 VIDEO_ABUSE_STATES,
@@ -736,18 +755,18 @@ export {
736 USER_PASSWORD_RESET_LIFETIME, 755 USER_PASSWORD_RESET_LIFETIME,
737 MEMOIZE_TTL, 756 MEMOIZE_TTL,
738 USER_EMAIL_VERIFY_LIFETIME, 757 USER_EMAIL_VERIFY_LIFETIME,
739 IMAGE_MIMETYPE_EXT,
740 OVERVIEWS, 758 OVERVIEWS,
741 SCHEDULER_INTERVALS_MS, 759 SCHEDULER_INTERVALS_MS,
742 REPEAT_JOBS, 760 REPEAT_JOBS,
743 STATIC_DOWNLOAD_PATHS, 761 STATIC_DOWNLOAD_PATHS,
744 RATES_LIMIT, 762 RATES_LIMIT,
745 VIDEO_EXT_MIMETYPE, 763 MIMETYPES,
746 CRAWL_REQUEST_CONCURRENCY, 764 CRAWL_REQUEST_CONCURRENCY,
747 JOB_COMPLETED_LIFETIME, 765 JOB_COMPLETED_LIFETIME,
748 HTTP_SIGNATURE, 766 HTTP_SIGNATURE,
749 VIDEO_IMPORT_STATES, 767 VIDEO_IMPORT_STATES,
750 VIDEO_VIEW_LIFETIME, 768 VIDEO_VIEW_LIFETIME,
769 CONTACT_FORM_LIFETIME,
751 buildLanguages 770 buildLanguages
752} 771}
753 772
@@ -764,16 +783,50 @@ function getLocalConfigFilePath () {
764 return join(dirname(configSources[ 0 ].name), filename + '.json') 783 return join(dirname(configSources[ 0 ].name), filename + '.json')
765} 784}
766 785
767function updateWebserverConfig () { 786function buildVideoMimetypeExt () {
787 const data = {
788 'video/webm': '.webm',
789 'video/ogg': '.ogv',
790 'video/mp4': '.mp4'
791 }
792
793 if (CONFIG.TRANSCODING.ENABLED && CONFIG.TRANSCODING.ALLOW_ADDITIONAL_EXTENSIONS) {
794 Object.assign(data, {
795 'video/quicktime': '.mov',
796 'video/x-msvideo': '.avi',
797 'video/x-flv': '.flv',
798 'video/x-matroska': '.mkv',
799 'application/octet-stream': '.mkv',
800 'video/avi': '.avi'
801 })
802 }
803
804 return data
805}
806
807function updateWebserverUrls () {
768 CONFIG.WEBSERVER.URL = sanitizeUrl(CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT) 808 CONFIG.WEBSERVER.URL = sanitizeUrl(CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT)
769 CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP) 809 CONFIG.WEBSERVER.HOST = sanitizeHost(CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT, REMOTE_SCHEME.HTTP)
770} 810}
771 811
812function updateWebserverConfig () {
813 CONSTRAINTS_FIELDS.VIDEOS.EXTNAME = buildVideosExtname()
814
815 MIMETYPES.VIDEO.MIMETYPE_EXT = buildVideoMimetypeExt()
816 MIMETYPES.VIDEO.EXT_MIMETYPE = invert(MIMETYPES.VIDEO.MIMETYPE_EXT)
817}
818
819function buildVideosExtname () {
820 return CONFIG.TRANSCODING.ENABLED && CONFIG.TRANSCODING.ALLOW_ADDITIONAL_EXTENSIONS
821 ? [ '.mp4', '.ogv', '.webm', '.mkv', '.mov', '.avi', '.flv' ]
822 : [ '.mp4', '.ogv', '.webm' ]
823}
824
772function buildVideosRedundancy (objs: any[]): VideosRedundancy[] { 825function buildVideosRedundancy (objs: any[]): VideosRedundancy[] {
773 if (!objs) return [] 826 if (!objs) return []
774 827
775 return objs.map(obj => { 828 return objs.map(obj => {
776 return Object.assign(obj, { 829 return Object.assign({}, obj, {
777 minLifetime: parseDuration(obj.min_lifetime), 830 minLifetime: parseDuration(obj.min_lifetime),
778 size: bytes.parse(obj.size), 831 size: bytes.parse(obj.size),
779 minViews: obj.min_views 832 minViews: obj.min_views
@@ -850,4 +903,5 @@ export function reloadConfig () {
850 config = require('config') 903 config = require('config')
851 904
852 updateWebserverConfig() 905 updateWebserverConfig()
906 updateWebserverUrls()
853} 907}
diff --git a/server/initializers/database.ts b/server/initializers/database.ts
index 40cd659ab..84ad2079b 100644
--- a/server/initializers/database.ts
+++ b/server/initializers/database.ts
@@ -31,6 +31,8 @@ import { VideoRedundancyModel } from '../models/redundancy/video-redundancy'
31import { UserVideoHistoryModel } from '../models/account/user-video-history' 31import { UserVideoHistoryModel } from '../models/account/user-video-history'
32import { AccountBlocklistModel } from '../models/account/account-blocklist' 32import { AccountBlocklistModel } from '../models/account/account-blocklist'
33import { ServerBlocklistModel } from '../models/server/server-blocklist' 33import { ServerBlocklistModel } from '../models/server/server-blocklist'
34import { UserNotificationModel } from '../models/account/user-notification'
35import { UserNotificationSettingModel } from '../models/account/user-notification-setting'
34 36
35require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string 37require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string
36 38
@@ -95,7 +97,9 @@ async function initDatabaseModels (silent: boolean) {
95 VideoRedundancyModel, 97 VideoRedundancyModel,
96 UserVideoHistoryModel, 98 UserVideoHistoryModel,
97 AccountBlocklistModel, 99 AccountBlocklistModel,
98 ServerBlocklistModel 100 ServerBlocklistModel,
101 UserNotificationModel,
102 UserNotificationSettingModel
99 ]) 103 ])
100 104
101 // Check extensions exist in the database 105 // Check extensions exist in the database
diff --git a/server/initializers/migrations/0295-video-file-extname.ts b/server/initializers/migrations/0295-video-file-extname.ts
new file mode 100644
index 000000000..dbf249f66
--- /dev/null
+++ b/server/initializers/migrations/0295-video-file-extname.ts
@@ -0,0 +1,49 @@
1import * as Sequelize from 'sequelize'
2
3async function up (utils: {
4 transaction: Sequelize.Transaction,
5 queryInterface: Sequelize.QueryInterface,
6 sequelize: Sequelize.Sequelize,
7 db: any
8}): Promise<void> {
9 {
10 await utils.queryInterface.renameColumn('videoFile', 'extname', 'extname_old')
11 }
12
13 {
14 const data = {
15 type: Sequelize.STRING,
16 defaultValue: null,
17 allowNull: true
18 }
19
20 await utils.queryInterface.addColumn('videoFile', 'extname', data)
21 }
22
23 {
24 const query = 'UPDATE "videoFile" SET "extname" = "extname_old"::text'
25 await utils.sequelize.query(query)
26 }
27
28 {
29 const data = {
30 type: Sequelize.STRING,
31 defaultValue: null,
32 allowNull: false
33 }
34 await utils.queryInterface.changeColumn('videoFile', 'extname', data)
35 }
36
37 {
38 await utils.queryInterface.removeColumn('videoFile', 'extname_old')
39 }
40}
41
42function down (options) {
43 throw new Error('Not implemented.')
44}
45
46export {
47 up,
48 down
49}
diff --git a/server/initializers/migrations/0300-user-videos-history-enabled.ts b/server/initializers/migrations/0300-user-videos-history-enabled.ts
new file mode 100644
index 000000000..aa5fc21fb
--- /dev/null
+++ b/server/initializers/migrations/0300-user-videos-history-enabled.ts
@@ -0,0 +1,27 @@
1import * as Sequelize from 'sequelize'
2
3async function up (utils: {
4 transaction: Sequelize.Transaction,
5 queryInterface: Sequelize.QueryInterface,
6 sequelize: Sequelize.Sequelize,
7 db: any
8}): Promise<void> {
9 {
10 const data = {
11 type: Sequelize.BOOLEAN,
12 allowNull: false,
13 defaultValue: true
14 }
15
16 await utils.queryInterface.addColumn('user', 'videosHistoryEnabled', data)
17 }
18}
19
20function down (options) {
21 throw new Error('Not implemented.')
22}
23
24export {
25 up,
26 down
27}
diff --git a/server/initializers/migrations/0305-fix-unfederated-videos.ts b/server/initializers/migrations/0305-fix-unfederated-videos.ts
new file mode 100644
index 000000000..be206601f
--- /dev/null
+++ b/server/initializers/migrations/0305-fix-unfederated-videos.ts
@@ -0,0 +1,52 @@
1import * as Sequelize from 'sequelize'
2
3async function up (utils: {
4 transaction: Sequelize.Transaction,
5 queryInterface: Sequelize.QueryInterface,
6 sequelize: Sequelize.Sequelize,
7 db: any
8}): Promise<void> {
9 {
10 const query = `INSERT INTO "videoShare" (url, "actorId", "videoId", "createdAt", "updatedAt") ` +
11 `(` +
12 `SELECT ` +
13 `video.url || '/announces/' || "videoChannel"."actorId" as url, ` +
14 `"videoChannel"."actorId" AS "actorId", ` +
15 `"video"."id" AS "videoId", ` +
16 `NOW() AS "createdAt", ` +
17 `NOW() AS "updatedAt" ` +
18 `FROM video ` +
19 `INNER JOIN "videoChannel" ON "video"."channelId" = "videoChannel"."id" ` +
20 `WHERE "video"."remote" = false AND "video"."privacy" != 3 AND "video"."state" = 1` +
21 `) ` +
22 `ON CONFLICT DO NOTHING`
23
24 await utils.sequelize.query(query)
25 }
26
27 {
28 const query = `INSERT INTO "videoShare" (url, "actorId", "videoId", "createdAt", "updatedAt") ` +
29 `(` +
30 `SELECT ` +
31 `video.url || '/announces/' || (SELECT id FROM actor WHERE "preferredUsername" = 'peertube' ORDER BY id ASC LIMIT 1) as url, ` +
32 `(SELECT id FROM actor WHERE "preferredUsername" = 'peertube' ORDER BY id ASC LIMIT 1) AS "actorId", ` +
33 `"video"."id" AS "videoId", ` +
34 `NOW() AS "createdAt", ` +
35 `NOW() AS "updatedAt" ` +
36 `FROM video ` +
37 `WHERE "video"."remote" = false AND "video"."privacy" != 3 AND "video"."state" = 1` +
38 `) ` +
39 `ON CONFLICT DO NOTHING`
40
41 await utils.sequelize.query(query)
42 }
43}
44
45function down (options) {
46 throw new Error('Not implemented.')
47}
48
49export {
50 up,
51 down
52}
diff --git a/server/initializers/migrations/0310-drop-unused-video-indexes.ts b/server/initializers/migrations/0310-drop-unused-video-indexes.ts
new file mode 100644
index 000000000..d51f430c0
--- /dev/null
+++ b/server/initializers/migrations/0310-drop-unused-video-indexes.ts
@@ -0,0 +1,32 @@
1import * as Sequelize from 'sequelize'
2
3async function up (utils: {
4 transaction: Sequelize.Transaction,
5 queryInterface: Sequelize.QueryInterface,
6 sequelize: Sequelize.Sequelize,
7 db: any
8}): Promise<void> {
9 const indexNames = [
10 'video_category',
11 'video_licence',
12 'video_nsfw',
13 'video_language',
14 'video_wait_transcoding',
15 'video_state',
16 'video_remote',
17 'video_likes'
18 ]
19
20 for (const indexName of indexNames) {
21 await utils.sequelize.query('DROP INDEX IF EXISTS "' + indexName + '";')
22 }
23}
24
25function down (options) {
26 throw new Error('Not implemented.')
27}
28
29export {
30 up,
31 down
32}
diff --git a/server/initializers/migrations/0315-user-notifications.ts b/server/initializers/migrations/0315-user-notifications.ts
new file mode 100644
index 000000000..8284c58a0
--- /dev/null
+++ b/server/initializers/migrations/0315-user-notifications.ts
@@ -0,0 +1,47 @@
1import * as Sequelize from 'sequelize'
2
3async function up (utils: {
4 transaction: Sequelize.Transaction,
5 queryInterface: Sequelize.QueryInterface,
6 sequelize: Sequelize.Sequelize
7}): Promise<void> {
8
9 {
10 const query = `
11CREATE TABLE IF NOT EXISTS "userNotificationSetting" ("id" SERIAL,
12"newVideoFromSubscription" INTEGER NOT NULL DEFAULT NULL,
13"newCommentOnMyVideo" INTEGER NOT NULL DEFAULT NULL,
14"videoAbuseAsModerator" INTEGER NOT NULL DEFAULT NULL,
15"blacklistOnMyVideo" INTEGER NOT NULL DEFAULT NULL,
16"myVideoPublished" INTEGER NOT NULL DEFAULT NULL,
17"myVideoImportFinished" INTEGER NOT NULL DEFAULT NULL,
18"newUserRegistration" INTEGER NOT NULL DEFAULT NULL,
19"newFollow" INTEGER NOT NULL DEFAULT NULL,
20"commentMention" INTEGER NOT NULL DEFAULT NULL,
21"userId" INTEGER REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
22"createdAt" TIMESTAMP WITH TIME ZONE NOT NULL,
23"updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL,
24PRIMARY KEY ("id"))
25`
26 await utils.sequelize.query(query)
27 }
28
29 {
30 const query = 'INSERT INTO "userNotificationSetting" ' +
31 '("newVideoFromSubscription", "newCommentOnMyVideo", "videoAbuseAsModerator", "blacklistOnMyVideo", ' +
32 '"myVideoPublished", "myVideoImportFinished", "newUserRegistration", "newFollow", "commentMention", ' +
33 '"userId", "createdAt", "updatedAt") ' +
34 '(SELECT 1, 1, 3, 3, 1, 1, 1, 1, 1, id, NOW(), NOW() FROM "user")'
35
36 await utils.sequelize.query(query)
37 }
38}
39
40function down (options) {
41 throw new Error('Not implemented.')
42}
43
44export {
45 up,
46 down
47}
diff --git a/server/initializers/migrations/0320-blacklist-unfederate.ts b/server/initializers/migrations/0320-blacklist-unfederate.ts
new file mode 100644
index 000000000..6fb7bbb90
--- /dev/null
+++ b/server/initializers/migrations/0320-blacklist-unfederate.ts
@@ -0,0 +1,27 @@
1import * as Sequelize from 'sequelize'
2
3async function up (utils: {
4 transaction: Sequelize.Transaction,
5 queryInterface: Sequelize.QueryInterface,
6 sequelize: Sequelize.Sequelize
7}): Promise<void> {
8
9 {
10 const data = {
11 type: Sequelize.BOOLEAN,
12 allowNull: false,
13 defaultValue: false
14 }
15
16 await utils.queryInterface.addColumn('videoBlacklist', 'unfederated', data)
17 }
18}
19
20function down (options) {
21 throw new Error('Not implemented.')
22}
23
24export {
25 up,
26 down
27}
diff --git a/server/initializers/migrations/0325-video-abuse-fields.ts b/server/initializers/migrations/0325-video-abuse-fields.ts
new file mode 100644
index 000000000..fca6d666f
--- /dev/null
+++ b/server/initializers/migrations/0325-video-abuse-fields.ts
@@ -0,0 +1,37 @@
1import * as Sequelize from 'sequelize'
2
3async function up (utils: {
4 transaction: Sequelize.Transaction,
5 queryInterface: Sequelize.QueryInterface,
6 sequelize: Sequelize.Sequelize
7}): Promise<void> {
8
9 {
10 const data = {
11 type: Sequelize.STRING(3000),
12 allowNull: false,
13 defaultValue: null
14 }
15
16 await utils.queryInterface.changeColumn('videoAbuse', 'reason', data)
17 }
18
19 {
20 const data = {
21 type: Sequelize.STRING(3000),
22 allowNull: true,
23 defaultValue: null
24 }
25
26 await utils.queryInterface.changeColumn('videoAbuse', 'moderationComment', data)
27 }
28}
29
30function down (options) {
31 throw new Error('Not implemented.')
32}
33
34export {
35 up,
36 down
37}
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts
index 504263c99..8215840da 100644
--- a/server/lib/activitypub/actor.ts
+++ b/server/lib/activitypub/actor.ts
@@ -1,11 +1,10 @@
1import * as Bluebird from 'bluebird' 1import * as Bluebird from 'bluebird'
2import { join } from 'path'
3import { Transaction } from 'sequelize' 2import { Transaction } from 'sequelize'
4import * as url from 'url' 3import * as url from 'url'
5import * as uuidv4 from 'uuid/v4' 4import * as uuidv4 from 'uuid/v4'
6import { ActivityPubActor, ActivityPubActorType } from '../../../shared/models/activitypub' 5import { ActivityPubActor, ActivityPubActorType } from '../../../shared/models/activitypub'
7import { ActivityPubAttributedTo } from '../../../shared/models/activitypub/objects' 6import { ActivityPubAttributedTo } from '../../../shared/models/activitypub/objects'
8import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub' 7import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
9import { isActorObjectValid, normalizeActor } from '../../helpers/custom-validators/activitypub/actor' 8import { isActorObjectValid, normalizeActor } from '../../helpers/custom-validators/activitypub/actor'
10import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 9import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
11import { retryTransactionWrapper, updateInstanceWithAnother } from '../../helpers/database-utils' 10import { retryTransactionWrapper, updateInstanceWithAnother } from '../../helpers/database-utils'
@@ -13,7 +12,7 @@ import { logger } from '../../helpers/logger'
13import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto' 12import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto'
14import { doRequest, downloadImage } from '../../helpers/requests' 13import { doRequest, downloadImage } from '../../helpers/requests'
15import { getUrlFromWebfinger } from '../../helpers/webfinger' 14import { getUrlFromWebfinger } from '../../helpers/webfinger'
16import { AVATARS_SIZE, CONFIG, IMAGE_MIMETYPE_EXT, sequelizeTypescript } from '../../initializers' 15import { AVATARS_SIZE, CONFIG, MIMETYPES, sequelizeTypescript } from '../../initializers'
17import { AccountModel } from '../../models/account/account' 16import { AccountModel } from '../../models/account/account'
18import { ActorModel } from '../../models/activitypub/actor' 17import { ActorModel } from '../../models/activitypub/actor'
19import { AvatarModel } from '../../models/avatar/avatar' 18import { AvatarModel } from '../../models/avatar/avatar'
@@ -43,7 +42,7 @@ async function getOrCreateActorAndServerAndModel (
43 recurseIfNeeded = true, 42 recurseIfNeeded = true,
44 updateCollections = false 43 updateCollections = false
45) { 44) {
46 const actorUrl = getAPUrl(activityActor) 45 const actorUrl = getAPId(activityActor)
47 let created = false 46 let created = false
48 47
49 let actor = await fetchActorByUrl(actorUrl, fetchType) 48 let actor = await fetchActorByUrl(actorUrl, fetchType)
@@ -172,15 +171,13 @@ async function fetchActorTotalItems (url: string) {
172 171
173async function fetchAvatarIfExists (actorJSON: ActivityPubActor) { 172async function fetchAvatarIfExists (actorJSON: ActivityPubActor) {
174 if ( 173 if (
175 actorJSON.icon && actorJSON.icon.type === 'Image' && IMAGE_MIMETYPE_EXT[actorJSON.icon.mediaType] !== undefined && 174 actorJSON.icon && actorJSON.icon.type === 'Image' && MIMETYPES.IMAGE.MIMETYPE_EXT[actorJSON.icon.mediaType] !== undefined &&
176 isActivityPubUrlValid(actorJSON.icon.url) 175 isActivityPubUrlValid(actorJSON.icon.url)
177 ) { 176 ) {
178 const extension = IMAGE_MIMETYPE_EXT[actorJSON.icon.mediaType] 177 const extension = MIMETYPES.IMAGE.MIMETYPE_EXT[actorJSON.icon.mediaType]
179 178
180 const avatarName = uuidv4() + extension 179 const avatarName = uuidv4() + extension
181 const destPath = join(CONFIG.STORAGE.AVATARS_DIR, avatarName) 180 await downloadImage(actorJSON.icon.url, CONFIG.STORAGE.AVATARS_DIR, avatarName, AVATARS_SIZE)
182
183 await downloadImage(actorJSON.icon.url, destPath, AVATARS_SIZE)
184 181
185 return avatarName 182 return avatarName
186 } 183 }
@@ -204,6 +201,69 @@ async function addFetchOutboxJob (actor: ActorModel) {
204 return JobQueue.Instance.createJob({ type: 'activitypub-http-fetcher', payload }) 201 return JobQueue.Instance.createJob({ type: 'activitypub-http-fetcher', payload })
205} 202}
206 203
204async function refreshActorIfNeeded (
205 actorArg: ActorModel,
206 fetchedType: ActorFetchByUrlType
207): Promise<{ actor: ActorModel, refreshed: boolean }> {
208 if (!actorArg.isOutdated()) return { actor: actorArg, refreshed: false }
209
210 // We need more attributes
211 const actor = fetchedType === 'all' ? actorArg : await ActorModel.loadByUrlAndPopulateAccountAndChannel(actorArg.url)
212
213 try {
214 let actorUrl: string
215 try {
216 actorUrl = await getUrlFromWebfinger(actor.preferredUsername + '@' + actor.getHost())
217 } catch (err) {
218 logger.warn('Cannot get actor URL from webfinger, keeping the old one.', err)
219 actorUrl = actor.url
220 }
221
222 const { result, statusCode } = await fetchRemoteActor(actorUrl)
223
224 if (statusCode === 404) {
225 logger.info('Deleting actor %s because there is a 404 in refresh actor.', actor.url)
226 actor.Account ? actor.Account.destroy() : actor.VideoChannel.destroy()
227 return { actor: undefined, refreshed: false }
228 }
229
230 if (result === undefined) {
231 logger.warn('Cannot fetch remote actor in refresh actor.')
232 return { actor, refreshed: false }
233 }
234
235 return sequelizeTypescript.transaction(async t => {
236 updateInstanceWithAnother(actor, result.actor)
237
238 if (result.avatarName !== undefined) {
239 await updateActorAvatarInstance(actor, result.avatarName, t)
240 }
241
242 // Force update
243 actor.setDataValue('updatedAt', new Date())
244 await actor.save({ transaction: t })
245
246 if (actor.Account) {
247 actor.Account.set('name', result.name)
248 actor.Account.set('description', result.summary)
249
250 await actor.Account.save({ transaction: t })
251 } else if (actor.VideoChannel) {
252 actor.VideoChannel.set('name', result.name)
253 actor.VideoChannel.set('description', result.summary)
254 actor.VideoChannel.set('support', result.support)
255
256 await actor.VideoChannel.save({ transaction: t })
257 }
258
259 return { refreshed: true, actor }
260 })
261 } catch (err) {
262 logger.warn('Cannot refresh actor.', { err })
263 return { actor, refreshed: false }
264 }
265}
266
207export { 267export {
208 getOrCreateActorAndServerAndModel, 268 getOrCreateActorAndServerAndModel,
209 buildActorInstance, 269 buildActorInstance,
@@ -211,6 +271,7 @@ export {
211 fetchActorTotalItems, 271 fetchActorTotalItems,
212 fetchAvatarIfExists, 272 fetchAvatarIfExists,
213 updateActorInstance, 273 updateActorInstance,
274 refreshActorIfNeeded,
214 updateActorAvatarInstance, 275 updateActorAvatarInstance,
215 addFetchOutboxJob 276 addFetchOutboxJob
216} 277}
@@ -299,7 +360,7 @@ async function fetchRemoteActor (actorUrl: string): Promise<{ statusCode?: numbe
299 360
300 const actorJSON: ActivityPubActor = requestResult.body 361 const actorJSON: ActivityPubActor = requestResult.body
301 if (isActorObjectValid(actorJSON) === false) { 362 if (isActorObjectValid(actorJSON) === false) {
302 logger.debug('Remote actor JSON is not valid.', { actorJSON: actorJSON }) 363 logger.debug('Remote actor JSON is not valid.', { actorJSON })
303 return { result: undefined, statusCode: requestResult.response.statusCode } 364 return { result: undefined, statusCode: requestResult.response.statusCode }
304 } 365 }
305 366
@@ -375,59 +436,3 @@ async function saveVideoChannel (actor: ActorModel, result: FetchRemoteActorResu
375 436
376 return videoChannelCreated 437 return videoChannelCreated
377} 438}
378
379async function refreshActorIfNeeded (
380 actorArg: ActorModel,
381 fetchedType: ActorFetchByUrlType
382): Promise<{ actor: ActorModel, refreshed: boolean }> {
383 if (!actorArg.isOutdated()) return { actor: actorArg, refreshed: false }
384
385 // We need more attributes
386 const actor = fetchedType === 'all' ? actorArg : await ActorModel.loadByUrlAndPopulateAccountAndChannel(actorArg.url)
387
388 try {
389 const actorUrl = await getUrlFromWebfinger(actor.preferredUsername + '@' + actor.getHost())
390 const { result, statusCode } = await fetchRemoteActor(actorUrl)
391
392 if (statusCode === 404) {
393 logger.info('Deleting actor %s because there is a 404 in refresh actor.', actor.url)
394 actor.Account ? actor.Account.destroy() : actor.VideoChannel.destroy()
395 return { actor: undefined, refreshed: false }
396 }
397
398 if (result === undefined) {
399 logger.warn('Cannot fetch remote actor in refresh actor.')
400 return { actor, refreshed: false }
401 }
402
403 return sequelizeTypescript.transaction(async t => {
404 updateInstanceWithAnother(actor, result.actor)
405
406 if (result.avatarName !== undefined) {
407 await updateActorAvatarInstance(actor, result.avatarName, t)
408 }
409
410 // Force update
411 actor.setDataValue('updatedAt', new Date())
412 await actor.save({ transaction: t })
413
414 if (actor.Account) {
415 actor.Account.set('name', result.name)
416 actor.Account.set('description', result.summary)
417
418 await actor.Account.save({ transaction: t })
419 } else if (actor.VideoChannel) {
420 actor.VideoChannel.set('name', result.name)
421 actor.VideoChannel.set('description', result.summary)
422 actor.VideoChannel.set('support', result.support)
423
424 await actor.VideoChannel.save({ transaction: t })
425 }
426
427 return { refreshed: true, actor }
428 })
429 } catch (err) {
430 logger.warn('Cannot refresh actor.', { err })
431 return { actor, refreshed: false }
432 }
433}
diff --git a/server/lib/activitypub/process/process-accept.ts b/server/lib/activitypub/process/process-accept.ts
index 89bda9c32..ebb275e34 100644
--- a/server/lib/activitypub/process/process-accept.ts
+++ b/server/lib/activitypub/process/process-accept.ts
@@ -24,6 +24,7 @@ async function processAccept (actor: ActorModel, targetActor: ActorModel) {
24 if (follow.state !== 'accepted') { 24 if (follow.state !== 'accepted') {
25 follow.set('state', 'accepted') 25 follow.set('state', 'accepted')
26 await follow.save() 26 await follow.save()
27
27 await addFetchOutboxJob(targetActor) 28 await addFetchOutboxJob(targetActor)
28 } 29 }
29} 30}
diff --git a/server/lib/activitypub/process/process-announce.ts b/server/lib/activitypub/process/process-announce.ts
index cc88b5423..23310b41e 100644
--- a/server/lib/activitypub/process/process-announce.ts
+++ b/server/lib/activitypub/process/process-announce.ts
@@ -5,6 +5,8 @@ import { ActorModel } from '../../../models/activitypub/actor'
5import { VideoShareModel } from '../../../models/video/video-share' 5import { VideoShareModel } from '../../../models/video/video-share'
6import { forwardVideoRelatedActivity } from '../send/utils' 6import { forwardVideoRelatedActivity } from '../send/utils'
7import { getOrCreateVideoAndAccountAndChannel } from '../videos' 7import { getOrCreateVideoAndAccountAndChannel } from '../videos'
8import { VideoPrivacy } from '../../../../shared/models/videos'
9import { Notifier } from '../../notifier'
8 10
9async function processAnnounceActivity (activity: ActivityAnnounce, actorAnnouncer: ActorModel) { 11async function processAnnounceActivity (activity: ActivityAnnounce, actorAnnouncer: ActorModel) {
10 return retryTransactionWrapper(processVideoShare, actorAnnouncer, activity) 12 return retryTransactionWrapper(processVideoShare, actorAnnouncer, activity)
@@ -21,9 +23,9 @@ export {
21async function processVideoShare (actorAnnouncer: ActorModel, activity: ActivityAnnounce) { 23async function processVideoShare (actorAnnouncer: ActorModel, activity: ActivityAnnounce) {
22 const objectUri = typeof activity.object === 'string' ? activity.object : activity.object.id 24 const objectUri = typeof activity.object === 'string' ? activity.object : activity.object.id
23 25
24 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: objectUri }) 26 const { video, created: videoCreated } = await getOrCreateVideoAndAccountAndChannel({ videoObject: objectUri })
25 27
26 return sequelizeTypescript.transaction(async t => { 28 await sequelizeTypescript.transaction(async t => {
27 // Add share entry 29 // Add share entry
28 30
29 const share = { 31 const share = {
@@ -49,4 +51,6 @@ async function processVideoShare (actorAnnouncer: ActorModel, activity: Activity
49 51
50 return undefined 52 return undefined
51 }) 53 })
54
55 if (videoCreated) Notifier.Instance.notifyOnNewVideo(video)
52} 56}
diff --git a/server/lib/activitypub/process/process-create.ts b/server/lib/activitypub/process/process-create.ts
index cd7ea01aa..5f4d793a5 100644
--- a/server/lib/activitypub/process/process-create.ts
+++ b/server/lib/activitypub/process/process-create.ts
@@ -1,36 +1,44 @@
1import { ActivityCreate, CacheFileObject, VideoAbuseState, VideoTorrentObject } from '../../../../shared' 1import { ActivityCreate, CacheFileObject, VideoTorrentObject } from '../../../../shared'
2import { DislikeObject, VideoAbuseObject, ViewObject } from '../../../../shared/models/activitypub/objects'
3import { VideoCommentObject } from '../../../../shared/models/activitypub/objects/video-comment-object' 2import { VideoCommentObject } from '../../../../shared/models/activitypub/objects/video-comment-object'
4import { retryTransactionWrapper } from '../../../helpers/database-utils' 3import { retryTransactionWrapper } from '../../../helpers/database-utils'
5import { logger } from '../../../helpers/logger' 4import { logger } from '../../../helpers/logger'
6import { sequelizeTypescript } from '../../../initializers' 5import { sequelizeTypescript } from '../../../initializers'
7import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
8import { ActorModel } from '../../../models/activitypub/actor' 6import { ActorModel } from '../../../models/activitypub/actor'
9import { VideoAbuseModel } from '../../../models/video/video-abuse'
10import { addVideoComment, resolveThread } from '../video-comments' 7import { addVideoComment, resolveThread } from '../video-comments'
11import { getOrCreateVideoAndAccountAndChannel } from '../videos' 8import { getOrCreateVideoAndAccountAndChannel } from '../videos'
12import { forwardVideoRelatedActivity } from '../send/utils' 9import { forwardVideoRelatedActivity } from '../send/utils'
13import { Redis } from '../../redis'
14import { createOrUpdateCacheFile } from '../cache-file' 10import { createOrUpdateCacheFile } from '../cache-file'
15import { getVideoDislikeActivityPubUrl } from '../url' 11import { Notifier } from '../../notifier'
16import { VideoModel } from '../../../models/video/video' 12import { processViewActivity } from './process-view'
13import { processDislikeActivity } from './process-dislike'
14import { processFlagActivity } from './process-flag'
17 15
18async function processCreateActivity (activity: ActivityCreate, byActor: ActorModel) { 16async function processCreateActivity (activity: ActivityCreate, byActor: ActorModel) {
19 const activityObject = activity.object 17 const activityObject = activity.object
20 const activityType = activityObject.type 18 const activityType = activityObject.type
21 19
22 if (activityType === 'View') { 20 if (activityType === 'View') {
23 return processCreateView(byActor, activity) 21 return processViewActivity(activity, byActor)
24 } else if (activityType === 'Dislike') { 22 }
25 return retryTransactionWrapper(processCreateDislike, byActor, activity) 23
26 } else if (activityType === 'Video') { 24 if (activityType === 'Dislike') {
25 return retryTransactionWrapper(processDislikeActivity, activity, byActor)
26 }
27
28 if (activityType === 'Flag') {
29 return retryTransactionWrapper(processFlagActivity, activity, byActor)
30 }
31
32 if (activityType === 'Video') {
27 return processCreateVideo(activity) 33 return processCreateVideo(activity)
28 } else if (activityType === 'Flag') { 34 }
29 return retryTransactionWrapper(processCreateVideoAbuse, byActor, activityObject as VideoAbuseObject) 35
30 } else if (activityType === 'Note') { 36 if (activityType === 'Note') {
31 return retryTransactionWrapper(processCreateVideoComment, byActor, activity) 37 return retryTransactionWrapper(processCreateVideoComment, activity, byActor)
32 } else if (activityType === 'CacheFile') { 38 }
33 return retryTransactionWrapper(processCacheFile, byActor, activity) 39
40 if (activityType === 'CacheFile') {
41 return retryTransactionWrapper(processCacheFile, activity, byActor)
34 } 42 }
35 43
36 logger.warn('Unknown activity object type %s when creating activity.', activityType, { activity: activity.id }) 44 logger.warn('Unknown activity object type %s when creating activity.', activityType, { activity: activity.id })
@@ -48,61 +56,14 @@ export {
48async function processCreateVideo (activity: ActivityCreate) { 56async function processCreateVideo (activity: ActivityCreate) {
49 const videoToCreateData = activity.object as VideoTorrentObject 57 const videoToCreateData = activity.object as VideoTorrentObject
50 58
51 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoToCreateData }) 59 const { video, created } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoToCreateData })
52 60
53 return video 61 if (created) Notifier.Instance.notifyOnNewVideo(video)
54}
55
56async function processCreateDislike (byActor: ActorModel, activity: ActivityCreate) {
57 const dislike = activity.object as DislikeObject
58 const byAccount = byActor.Account
59
60 if (!byAccount) throw new Error('Cannot create dislike with the non account actor ' + byActor.url)
61
62 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislike.object })
63 62
64 return sequelizeTypescript.transaction(async t => { 63 return video
65 const rate = {
66 type: 'dislike' as 'dislike',
67 videoId: video.id,
68 accountId: byAccount.id
69 }
70
71 const [ , created ] = await AccountVideoRateModel.findOrCreate({
72 where: rate,
73 defaults: Object.assign({}, rate, { url: getVideoDislikeActivityPubUrl(byActor, video) }),
74 transaction: t
75 })
76 if (created === true) await video.increment('dislikes', { transaction: t })
77
78 if (video.isOwned() && created === true) {
79 // Don't resend the activity to the sender
80 const exceptions = [ byActor ]
81
82 await forwardVideoRelatedActivity(activity, t, exceptions, video)
83 }
84 })
85}
86
87async function processCreateView (byActor: ActorModel, activity: ActivityCreate) {
88 const view = activity.object as ViewObject
89
90 const options = {
91 videoObject: view.object,
92 fetchType: 'only-video' as 'only-video'
93 }
94 const { video } = await getOrCreateVideoAndAccountAndChannel(options)
95
96 await Redis.Instance.addVideoView(video.id)
97
98 if (video.isOwned()) {
99 // Don't resend the activity to the sender
100 const exceptions = [ byActor ]
101 await forwardVideoRelatedActivity(activity, undefined, exceptions, video)
102 }
103} 64}
104 65
105async function processCacheFile (byActor: ActorModel, activity: ActivityCreate) { 66async function processCacheFile (activity: ActivityCreate, byActor: ActorModel) {
106 const cacheFile = activity.object as CacheFileObject 67 const cacheFile = activity.object as CacheFileObject
107 68
108 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: cacheFile.object }) 69 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: cacheFile.object })
@@ -118,29 +79,7 @@ async function processCacheFile (byActor: ActorModel, activity: ActivityCreate)
118 } 79 }
119} 80}
120 81
121async function processCreateVideoAbuse (byActor: ActorModel, videoAbuseToCreateData: VideoAbuseObject) { 82async function processCreateVideoComment (activity: ActivityCreate, byActor: ActorModel) {
122 logger.debug('Reporting remote abuse for video %s.', videoAbuseToCreateData.object)
123
124 const account = byActor.Account
125 if (!account) throw new Error('Cannot create dislike with the non account actor ' + byActor.url)
126
127 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoAbuseToCreateData.object })
128
129 return sequelizeTypescript.transaction(async t => {
130 const videoAbuseData = {
131 reporterAccountId: account.id,
132 reason: videoAbuseToCreateData.content,
133 videoId: video.id,
134 state: VideoAbuseState.PENDING
135 }
136
137 await VideoAbuseModel.create(videoAbuseData, { transaction: t })
138
139 logger.info('Remote abuse for video uuid %s created', videoAbuseToCreateData.object)
140 })
141}
142
143async function processCreateVideoComment (byActor: ActorModel, activity: ActivityCreate) {
144 const commentObject = activity.object as VideoCommentObject 83 const commentObject = activity.object as VideoCommentObject
145 const byAccount = byActor.Account 84 const byAccount = byActor.Account
146 85
@@ -148,7 +87,7 @@ async function processCreateVideoComment (byActor: ActorModel, activity: Activit
148 87
149 const { video } = await resolveThread(commentObject.inReplyTo) 88 const { video } = await resolveThread(commentObject.inReplyTo)
150 89
151 const { created } = await addVideoComment(video, commentObject.id) 90 const { comment, created } = await addVideoComment(video, commentObject.id)
152 91
153 if (video.isOwned() && created === true) { 92 if (video.isOwned() && created === true) {
154 // Don't resend the activity to the sender 93 // Don't resend the activity to the sender
@@ -156,4 +95,6 @@ async function processCreateVideoComment (byActor: ActorModel, activity: Activit
156 95
157 await forwardVideoRelatedActivity(activity, undefined, exceptions, video) 96 await forwardVideoRelatedActivity(activity, undefined, exceptions, video)
158 } 97 }
98
99 if (created === true) Notifier.Instance.notifyOnNewComment(comment)
159} 100}
diff --git a/server/lib/activitypub/process/process-dislike.ts b/server/lib/activitypub/process/process-dislike.ts
new file mode 100644
index 000000000..bfd69e07a
--- /dev/null
+++ b/server/lib/activitypub/process/process-dislike.ts
@@ -0,0 +1,52 @@
1import { ActivityCreate, ActivityDislike } from '../../../../shared'
2import { DislikeObject } from '../../../../shared/models/activitypub/objects'
3import { retryTransactionWrapper } from '../../../helpers/database-utils'
4import { sequelizeTypescript } from '../../../initializers'
5import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
6import { ActorModel } from '../../../models/activitypub/actor'
7import { getOrCreateVideoAndAccountAndChannel } from '../videos'
8import { forwardVideoRelatedActivity } from '../send/utils'
9import { getVideoDislikeActivityPubUrl } from '../url'
10
11async function processDislikeActivity (activity: ActivityCreate | ActivityDislike, byActor: ActorModel) {
12 return retryTransactionWrapper(processDislike, activity, byActor)
13}
14
15// ---------------------------------------------------------------------------
16
17export {
18 processDislikeActivity
19}
20
21// ---------------------------------------------------------------------------
22
23async function processDislike (activity: ActivityCreate | ActivityDislike, byActor: ActorModel) {
24 const dislikeObject = activity.type === 'Dislike' ? activity.object : (activity.object as DislikeObject).object
25 const byAccount = byActor.Account
26
27 if (!byAccount) throw new Error('Cannot create dislike with the non account actor ' + byActor.url)
28
29 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislikeObject })
30
31 return sequelizeTypescript.transaction(async t => {
32 const rate = {
33 type: 'dislike' as 'dislike',
34 videoId: video.id,
35 accountId: byAccount.id
36 }
37
38 const [ , created ] = await AccountVideoRateModel.findOrCreate({
39 where: rate,
40 defaults: Object.assign({}, rate, { url: getVideoDislikeActivityPubUrl(byActor, video) }),
41 transaction: t
42 })
43 if (created === true) await video.increment('dislikes', { transaction: t })
44
45 if (video.isOwned() && created === true) {
46 // Don't resend the activity to the sender
47 const exceptions = [ byActor ]
48
49 await forwardVideoRelatedActivity(activity, t, exceptions, video)
50 }
51 })
52}
diff --git a/server/lib/activitypub/process/process-flag.ts b/server/lib/activitypub/process/process-flag.ts
new file mode 100644
index 000000000..79ce6fb41
--- /dev/null
+++ b/server/lib/activitypub/process/process-flag.ts
@@ -0,0 +1,49 @@
1import { ActivityCreate, ActivityFlag, VideoAbuseState } from '../../../../shared'
2import { VideoAbuseObject } from '../../../../shared/models/activitypub/objects'
3import { retryTransactionWrapper } from '../../../helpers/database-utils'
4import { logger } from '../../../helpers/logger'
5import { sequelizeTypescript } from '../../../initializers'
6import { ActorModel } from '../../../models/activitypub/actor'
7import { VideoAbuseModel } from '../../../models/video/video-abuse'
8import { getOrCreateVideoAndAccountAndChannel } from '../videos'
9import { Notifier } from '../../notifier'
10import { getAPId } from '../../../helpers/activitypub'
11
12async function processFlagActivity (activity: ActivityCreate | ActivityFlag, byActor: ActorModel) {
13 return retryTransactionWrapper(processCreateVideoAbuse, activity, byActor)
14}
15
16// ---------------------------------------------------------------------------
17
18export {
19 processFlagActivity
20}
21
22// ---------------------------------------------------------------------------
23
24async function processCreateVideoAbuse (activity: ActivityCreate | ActivityFlag, byActor: ActorModel) {
25 const flag = activity.type === 'Flag' ? activity : (activity.object as VideoAbuseObject)
26
27 logger.debug('Reporting remote abuse for video %s.', getAPId(flag.object))
28
29 const account = byActor.Account
30 if (!account) throw new Error('Cannot create dislike with the non account actor ' + byActor.url)
31
32 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: flag.object })
33
34 return sequelizeTypescript.transaction(async t => {
35 const videoAbuseData = {
36 reporterAccountId: account.id,
37 reason: flag.content,
38 videoId: video.id,
39 state: VideoAbuseState.PENDING
40 }
41
42 const videoAbuseInstance = await VideoAbuseModel.create(videoAbuseData, { transaction: t })
43 videoAbuseInstance.Video = video
44
45 Notifier.Instance.notifyOnNewVideoAbuse(videoAbuseInstance)
46
47 logger.info('Remote abuse for video uuid %s created', flag.object)
48 })
49}
diff --git a/server/lib/activitypub/process/process-follow.ts b/server/lib/activitypub/process/process-follow.ts
index 24c9085f7..0cd537187 100644
--- a/server/lib/activitypub/process/process-follow.ts
+++ b/server/lib/activitypub/process/process-follow.ts
@@ -5,9 +5,11 @@ import { sequelizeTypescript } from '../../../initializers'
5import { ActorModel } from '../../../models/activitypub/actor' 5import { ActorModel } from '../../../models/activitypub/actor'
6import { ActorFollowModel } from '../../../models/activitypub/actor-follow' 6import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
7import { sendAccept } from '../send' 7import { sendAccept } from '../send'
8import { Notifier } from '../../notifier'
9import { getAPId } from '../../../helpers/activitypub'
8 10
9async function processFollowActivity (activity: ActivityFollow, byActor: ActorModel) { 11async function processFollowActivity (activity: ActivityFollow, byActor: ActorModel) {
10 const activityObject = activity.object 12 const activityObject = getAPId(activity.object)
11 13
12 return retryTransactionWrapper(processFollow, byActor, activityObject) 14 return retryTransactionWrapper(processFollow, byActor, activityObject)
13} 15}
@@ -21,13 +23,13 @@ export {
21// --------------------------------------------------------------------------- 23// ---------------------------------------------------------------------------
22 24
23async function processFollow (actor: ActorModel, targetActorURL: string) { 25async function processFollow (actor: ActorModel, targetActorURL: string) {
24 await sequelizeTypescript.transaction(async t => { 26 const { actorFollow, created } = await sequelizeTypescript.transaction(async t => {
25 const targetActor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(targetActorURL, t) 27 const targetActor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(targetActorURL, t)
26 28
27 if (!targetActor) throw new Error('Unknown actor') 29 if (!targetActor) throw new Error('Unknown actor')
28 if (targetActor.isOwned() === false) throw new Error('This is not a local actor.') 30 if (targetActor.isOwned() === false) throw new Error('This is not a local actor.')
29 31
30 const [ actorFollow ] = await ActorFollowModel.findOrCreate({ 32 const [ actorFollow, created ] = await ActorFollowModel.findOrCreate({
31 where: { 33 where: {
32 actorId: actor.id, 34 actorId: actor.id,
33 targetActorId: targetActor.id 35 targetActorId: targetActor.id
@@ -52,8 +54,12 @@ async function processFollow (actor: ActorModel, targetActorURL: string) {
52 actorFollow.ActorFollowing = targetActor 54 actorFollow.ActorFollowing = targetActor
53 55
54 // Target sends to actor he accepted the follow request 56 // Target sends to actor he accepted the follow request
55 return sendAccept(actorFollow) 57 await sendAccept(actorFollow)
58
59 return { actorFollow, created }
56 }) 60 })
57 61
62 if (created) Notifier.Instance.notifyOfNewFollow(actorFollow)
63
58 logger.info('Actor %s is followed by actor %s.', targetActorURL, actor.url) 64 logger.info('Actor %s is followed by actor %s.', targetActorURL, actor.url)
59} 65}
diff --git a/server/lib/activitypub/process/process-like.ts b/server/lib/activitypub/process/process-like.ts
index e8e97eece..2a04167d7 100644
--- a/server/lib/activitypub/process/process-like.ts
+++ b/server/lib/activitypub/process/process-like.ts
@@ -6,6 +6,7 @@ import { ActorModel } from '../../../models/activitypub/actor'
6import { forwardVideoRelatedActivity } from '../send/utils' 6import { forwardVideoRelatedActivity } from '../send/utils'
7import { getOrCreateVideoAndAccountAndChannel } from '../videos' 7import { getOrCreateVideoAndAccountAndChannel } from '../videos'
8import { getVideoLikeActivityPubUrl } from '../url' 8import { getVideoLikeActivityPubUrl } from '../url'
9import { getAPId } from '../../../helpers/activitypub'
9 10
10async function processLikeActivity (activity: ActivityLike, byActor: ActorModel) { 11async function processLikeActivity (activity: ActivityLike, byActor: ActorModel) {
11 return retryTransactionWrapper(processLikeVideo, byActor, activity) 12 return retryTransactionWrapper(processLikeVideo, byActor, activity)
@@ -20,7 +21,7 @@ export {
20// --------------------------------------------------------------------------- 21// ---------------------------------------------------------------------------
21 22
22async function processLikeVideo (byActor: ActorModel, activity: ActivityLike) { 23async function processLikeVideo (byActor: ActorModel, activity: ActivityLike) {
23 const videoUrl = activity.object 24 const videoUrl = getAPId(activity.object)
24 25
25 const byAccount = byActor.Account 26 const byAccount = byActor.Account
26 if (!byAccount) throw new Error('Cannot create like with the non account actor ' + byActor.url) 27 if (!byAccount) throw new Error('Cannot create like with the non account actor ' + byActor.url)
diff --git a/server/lib/activitypub/process/process-undo.ts b/server/lib/activitypub/process/process-undo.ts
index 438a013b6..ed0177a67 100644
--- a/server/lib/activitypub/process/process-undo.ts
+++ b/server/lib/activitypub/process/process-undo.ts
@@ -26,6 +26,10 @@ async function processUndoActivity (activity: ActivityUndo, byActor: ActorModel)
26 } 26 }
27 } 27 }
28 28
29 if (activityToUndo.type === 'Dislike') {
30 return retryTransactionWrapper(processUndoDislike, byActor, activity)
31 }
32
29 if (activityToUndo.type === 'Follow') { 33 if (activityToUndo.type === 'Follow') {
30 return retryTransactionWrapper(processUndoFollow, byActor, activityToUndo) 34 return retryTransactionWrapper(processUndoFollow, byActor, activityToUndo)
31 } 35 }
@@ -72,7 +76,9 @@ async function processUndoLike (byActor: ActorModel, activity: ActivityUndo) {
72} 76}
73 77
74async function processUndoDislike (byActor: ActorModel, activity: ActivityUndo) { 78async function processUndoDislike (byActor: ActorModel, activity: ActivityUndo) {
75 const dislike = activity.object.object as DislikeObject 79 const dislike = activity.object.type === 'Dislike'
80 ? activity.object
81 : activity.object.object as DislikeObject
76 82
77 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislike.object }) 83 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislike.object })
78 84
diff --git a/server/lib/activitypub/process/process-update.ts b/server/lib/activitypub/process/process-update.ts
index 03831a00e..c6b42d846 100644
--- a/server/lib/activitypub/process/process-update.ts
+++ b/server/lib/activitypub/process/process-update.ts
@@ -51,7 +51,7 @@ async function processUpdateVideo (actor: ActorModel, activity: ActivityUpdate)
51 return undefined 51 return undefined
52 } 52 }
53 53
54 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoObject.id }) 54 const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoObject.id, allowRefresh: false })
55 const channelActor = await getOrCreateVideoChannelFromVideoObject(videoObject) 55 const channelActor = await getOrCreateVideoChannelFromVideoObject(videoObject)
56 56
57 const updateOptions = { 57 const updateOptions = {
diff --git a/server/lib/activitypub/process/process-view.ts b/server/lib/activitypub/process/process-view.ts
new file mode 100644
index 000000000..8f66d3630
--- /dev/null
+++ b/server/lib/activitypub/process/process-view.ts
@@ -0,0 +1,35 @@
1import { ActorModel } from '../../../models/activitypub/actor'
2import { getOrCreateVideoAndAccountAndChannel } from '../videos'
3import { forwardVideoRelatedActivity } from '../send/utils'
4import { Redis } from '../../redis'
5import { ActivityCreate, ActivityView, ViewObject } from '../../../../shared/models/activitypub'
6
7async function processViewActivity (activity: ActivityView | ActivityCreate, byActor: ActorModel) {
8 return processCreateView(activity, byActor)
9}
10
11// ---------------------------------------------------------------------------
12
13export {
14 processViewActivity
15}
16
17// ---------------------------------------------------------------------------
18
19async function processCreateView (activity: ActivityView | ActivityCreate, byActor: ActorModel) {
20 const videoObject = activity.type === 'View' ? activity.object : (activity.object as ViewObject).object
21
22 const options = {
23 videoObject: videoObject,
24 fetchType: 'only-video' as 'only-video'
25 }
26 const { video } = await getOrCreateVideoAndAccountAndChannel(options)
27
28 await Redis.Instance.addVideoView(video.id)
29
30 if (video.isOwned()) {
31 // Don't resend the activity to the sender
32 const exceptions = [ byActor ]
33 await forwardVideoRelatedActivity(activity, undefined, exceptions, video)
34 }
35}
diff --git a/server/lib/activitypub/process/process.ts b/server/lib/activitypub/process/process.ts
index bcc5cac7a..9dd241402 100644
--- a/server/lib/activitypub/process/process.ts
+++ b/server/lib/activitypub/process/process.ts
@@ -1,5 +1,5 @@
1import { Activity, ActivityType } from '../../../../shared/models/activitypub' 1import { Activity, ActivityType } from '../../../../shared/models/activitypub'
2import { checkUrlsSameHost, getAPUrl } from '../../../helpers/activitypub' 2import { checkUrlsSameHost, getAPId } from '../../../helpers/activitypub'
3import { logger } from '../../../helpers/logger' 3import { logger } from '../../../helpers/logger'
4import { ActorModel } from '../../../models/activitypub/actor' 4import { ActorModel } from '../../../models/activitypub/actor'
5import { processAcceptActivity } from './process-accept' 5import { processAcceptActivity } from './process-accept'
@@ -12,6 +12,9 @@ import { processRejectActivity } from './process-reject'
12import { processUndoActivity } from './process-undo' 12import { processUndoActivity } from './process-undo'
13import { processUpdateActivity } from './process-update' 13import { processUpdateActivity } from './process-update'
14import { getOrCreateActorAndServerAndModel } from '../actor' 14import { getOrCreateActorAndServerAndModel } from '../actor'
15import { processDislikeActivity } from './process-dislike'
16import { processFlagActivity } from './process-flag'
17import { processViewActivity } from './process-view'
15 18
16const processActivity: { [ P in ActivityType ]: (activity: Activity, byActor: ActorModel, inboxActor?: ActorModel) => Promise<any> } = { 19const processActivity: { [ P in ActivityType ]: (activity: Activity, byActor: ActorModel, inboxActor?: ActorModel) => Promise<any> } = {
17 Create: processCreateActivity, 20 Create: processCreateActivity,
@@ -22,7 +25,10 @@ const processActivity: { [ P in ActivityType ]: (activity: Activity, byActor: Ac
22 Reject: processRejectActivity, 25 Reject: processRejectActivity,
23 Announce: processAnnounceActivity, 26 Announce: processAnnounceActivity,
24 Undo: processUndoActivity, 27 Undo: processUndoActivity,
25 Like: processLikeActivity 28 Like: processLikeActivity,
29 Dislike: processDislikeActivity,
30 Flag: processFlagActivity,
31 View: processViewActivity
26} 32}
27 33
28async function processActivities ( 34async function processActivities (
@@ -35,12 +41,12 @@ async function processActivities (
35 const actorsCache: { [ url: string ]: ActorModel } = {} 41 const actorsCache: { [ url: string ]: ActorModel } = {}
36 42
37 for (const activity of activities) { 43 for (const activity of activities) {
38 if (!options.signatureActor && [ 'Create', 'Announce', 'Like' ].indexOf(activity.type) === -1) { 44 if (!options.signatureActor && [ 'Create', 'Announce', 'Like' ].includes(activity.type) === false) {
39 logger.error('Cannot process activity %s (type: %s) without the actor signature.', activity.id, activity.type) 45 logger.error('Cannot process activity %s (type: %s) without the actor signature.', activity.id, activity.type)
40 continue 46 continue
41 } 47 }
42 48
43 const actorUrl = getAPUrl(activity.actor) 49 const actorUrl = getAPId(activity.actor)
44 50
45 // When we fetch remote data, we don't have signature 51 // When we fetch remote data, we don't have signature
46 if (options.signatureActor && actorUrl !== options.signatureActor.url) { 52 if (options.signatureActor && actorUrl !== options.signatureActor.url) {
diff --git a/server/lib/activitypub/share.ts b/server/lib/activitypub/share.ts
index 5dcba778c..1767df0ae 100644
--- a/server/lib/activitypub/share.ts
+++ b/server/lib/activitypub/share.ts
@@ -11,7 +11,7 @@ import { doRequest } from '../../helpers/requests'
11import { getOrCreateActorAndServerAndModel } from './actor' 11import { getOrCreateActorAndServerAndModel } from './actor'
12import { logger } from '../../helpers/logger' 12import { logger } from '../../helpers/logger'
13import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers' 13import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers'
14import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub' 14import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
15 15
16async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction) { 16async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction) {
17 if (video.privacy === VideoPrivacy.PRIVATE) return undefined 17 if (video.privacy === VideoPrivacy.PRIVATE) return undefined
@@ -41,7 +41,7 @@ async function addVideoShares (shareUrls: string[], instance: VideoModel) {
41 }) 41 })
42 if (!body || !body.actor) throw new Error('Body or body actor is invalid') 42 if (!body || !body.actor) throw new Error('Body or body actor is invalid')
43 43
44 const actorUrl = getAPUrl(body.actor) 44 const actorUrl = getAPId(body.actor)
45 if (checkUrlsSameHost(shareUrl, actorUrl) !== true) { 45 if (checkUrlsSameHost(shareUrl, actorUrl) !== true) {
46 throw new Error(`Actor url ${actorUrl} has not the same host than the share url ${shareUrl}`) 46 throw new Error(`Actor url ${actorUrl} has not the same host than the share url ${shareUrl}`)
47 } 47 }
@@ -78,7 +78,7 @@ async function shareByServer (video: VideoModel, t: Transaction) {
78 const serverActor = await getServerActor() 78 const serverActor = await getServerActor()
79 79
80 const serverShareUrl = getVideoAnnounceActivityPubUrl(serverActor, video) 80 const serverShareUrl = getVideoAnnounceActivityPubUrl(serverActor, video)
81 return VideoShareModel.findOrCreate({ 81 const [ serverShare ] = await VideoShareModel.findOrCreate({
82 defaults: { 82 defaults: {
83 actorId: serverActor.id, 83 actorId: serverActor.id,
84 videoId: video.id, 84 videoId: video.id,
@@ -88,16 +88,14 @@ async function shareByServer (video: VideoModel, t: Transaction) {
88 url: serverShareUrl 88 url: serverShareUrl
89 }, 89 },
90 transaction: t 90 transaction: t
91 }).then(([ serverShare, created ]) => {
92 if (created) return sendVideoAnnounce(serverActor, serverShare, video, t)
93
94 return undefined
95 }) 91 })
92
93 return sendVideoAnnounce(serverActor, serverShare, video, t)
96} 94}
97 95
98async function shareByVideoChannel (video: VideoModel, t: Transaction) { 96async function shareByVideoChannel (video: VideoModel, t: Transaction) {
99 const videoChannelShareUrl = getVideoAnnounceActivityPubUrl(video.VideoChannel.Actor, video) 97 const videoChannelShareUrl = getVideoAnnounceActivityPubUrl(video.VideoChannel.Actor, video)
100 return VideoShareModel.findOrCreate({ 98 const [ videoChannelShare ] = await VideoShareModel.findOrCreate({
101 defaults: { 99 defaults: {
102 actorId: video.VideoChannel.actorId, 100 actorId: video.VideoChannel.actorId,
103 videoId: video.id, 101 videoId: video.id,
@@ -107,11 +105,9 @@ async function shareByVideoChannel (video: VideoModel, t: Transaction) {
107 url: videoChannelShareUrl 105 url: videoChannelShareUrl
108 }, 106 },
109 transaction: t 107 transaction: t
110 }).then(([ videoChannelShare, created ]) => {
111 if (created) return sendVideoAnnounce(video.VideoChannel.Actor, videoChannelShare, video, t)
112
113 return undefined
114 }) 108 })
109
110 return sendVideoAnnounce(video.VideoChannel.Actor, videoChannelShare, video, t)
115} 111}
116 112
117async function undoShareByVideoChannel (video: VideoModel, oldVideoChannel: VideoChannelModel, t: Transaction) { 113async function undoShareByVideoChannel (video: VideoModel, oldVideoChannel: VideoChannelModel, t: Transaction) {
diff --git a/server/lib/activitypub/video-comments.ts b/server/lib/activitypub/video-comments.ts
index 5868e7297..e87301fe7 100644
--- a/server/lib/activitypub/video-comments.ts
+++ b/server/lib/activitypub/video-comments.ts
@@ -70,7 +70,7 @@ async function addVideoComment (videoInstance: VideoModel, commentUrl: string) {
70 throw new Error(`Comment url ${commentUrl} host is different from the AP object id ${body.id}`) 70 throw new Error(`Comment url ${commentUrl} host is different from the AP object id ${body.id}`)
71 } 71 }
72 72
73 const actor = await getOrCreateActorAndServerAndModel(actorUrl) 73 const actor = await getOrCreateActorAndServerAndModel(actorUrl, 'all')
74 const entry = await videoCommentActivityObjectToDBAttributes(videoInstance, actor, body) 74 const entry = await videoCommentActivityObjectToDBAttributes(videoInstance, actor, body)
75 if (!entry) return { created: false } 75 if (!entry) return { created: false }
76 76
@@ -80,6 +80,8 @@ async function addVideoComment (videoInstance: VideoModel, commentUrl: string) {
80 }, 80 },
81 defaults: entry 81 defaults: entry
82 }) 82 })
83 comment.Account = actor.Account
84 comment.Video = videoInstance
83 85
84 return { comment, created } 86 return { comment, created }
85} 87}
diff --git a/server/lib/activitypub/video-rates.ts b/server/lib/activitypub/video-rates.ts
index 2cce67f0c..45a2b22ea 100644
--- a/server/lib/activitypub/video-rates.ts
+++ b/server/lib/activitypub/video-rates.ts
@@ -9,7 +9,7 @@ import { AccountVideoRateModel } from '../../models/account/account-video-rate'
9import { logger } from '../../helpers/logger' 9import { logger } from '../../helpers/logger'
10import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers' 10import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers'
11import { doRequest } from '../../helpers/requests' 11import { doRequest } from '../../helpers/requests'
12import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub' 12import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
13import { ActorModel } from '../../models/activitypub/actor' 13import { ActorModel } from '../../models/activitypub/actor'
14import { getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from './url' 14import { getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from './url'
15 15
@@ -26,7 +26,7 @@ async function createRates (ratesUrl: string[], video: VideoModel, rate: VideoRa
26 }) 26 })
27 if (!body || !body.actor) throw new Error('Body or body actor is invalid') 27 if (!body || !body.actor) throw new Error('Body or body actor is invalid')
28 28
29 const actorUrl = getAPUrl(body.actor) 29 const actorUrl = getAPId(body.actor)
30 if (checkUrlsSameHost(actorUrl, rateUrl) !== true) { 30 if (checkUrlsSameHost(actorUrl, rateUrl) !== true) {
31 throw new Error(`Rate url ${rateUrl} has not the same host than actor url ${actorUrl}`) 31 throw new Error(`Rate url ${rateUrl} has not the same host than actor url ${actorUrl}`)
32 } 32 }
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts
index 998f90330..e1e523499 100644
--- a/server/lib/activitypub/videos.ts
+++ b/server/lib/activitypub/videos.ts
@@ -1,7 +1,6 @@
1import * as Bluebird from 'bluebird' 1import * as Bluebird from 'bluebird'
2import * as sequelize from 'sequelize' 2import * as sequelize from 'sequelize'
3import * as magnetUtil from 'magnet-uri' 3import * as magnetUtil from 'magnet-uri'
4import { join } from 'path'
5import * as request from 'request' 4import * as request from 'request'
6import { ActivityIconObject, ActivityUrlObject, ActivityVideoUrlObject, VideoState } from '../../../shared/index' 5import { ActivityIconObject, ActivityUrlObject, ActivityVideoUrlObject, VideoState } from '../../../shared/index'
7import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' 6import { VideoTorrentObject } from '../../../shared/models/activitypub/objects'
@@ -11,7 +10,7 @@ import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos
11import { resetSequelizeInstance, retryTransactionWrapper } from '../../helpers/database-utils' 10import { resetSequelizeInstance, retryTransactionWrapper } from '../../helpers/database-utils'
12import { logger } from '../../helpers/logger' 11import { logger } from '../../helpers/logger'
13import { doRequest, downloadImage } from '../../helpers/requests' 12import { doRequest, downloadImage } from '../../helpers/requests'
14import { ACTIVITY_PUB, CONFIG, REMOTE_SCHEME, sequelizeTypescript, THUMBNAILS_SIZE, VIDEO_MIMETYPE_EXT } from '../../initializers' 13import { ACTIVITY_PUB, CONFIG, MIMETYPES, REMOTE_SCHEME, sequelizeTypescript, THUMBNAILS_SIZE } from '../../initializers'
15import { ActorModel } from '../../models/activitypub/actor' 14import { ActorModel } from '../../models/activitypub/actor'
16import { TagModel } from '../../models/video/tag' 15import { TagModel } from '../../models/video/tag'
17import { VideoModel } from '../../models/video/video' 16import { VideoModel } from '../../models/video/video'
@@ -29,7 +28,8 @@ import { createRates } from './video-rates'
29import { addVideoShares, shareVideoByServerAndChannel } from './share' 28import { addVideoShares, shareVideoByServerAndChannel } from './share'
30import { AccountModel } from '../../models/account/account' 29import { AccountModel } from '../../models/account/account'
31import { fetchVideoByUrl, VideoFetchByUrlType } from '../../helpers/video' 30import { fetchVideoByUrl, VideoFetchByUrlType } from '../../helpers/video'
32import { checkUrlsSameHost, getAPUrl } from '../../helpers/activitypub' 31import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
32import { Notifier } from '../notifier'
33 33
34async function federateVideoIfNeeded (video: VideoModel, isNewVideo: boolean, transaction?: sequelize.Transaction) { 34async function federateVideoIfNeeded (video: VideoModel, isNewVideo: boolean, transaction?: sequelize.Transaction) {
35 // If the video is not private and published, we federate it 35 // If the video is not private and published, we federate it
@@ -95,9 +95,8 @@ function fetchRemoteVideoStaticFile (video: VideoModel, path: string, reject: Fu
95 95
96function generateThumbnailFromUrl (video: VideoModel, icon: ActivityIconObject) { 96function generateThumbnailFromUrl (video: VideoModel, icon: ActivityIconObject) {
97 const thumbnailName = video.getThumbnailName() 97 const thumbnailName = video.getThumbnailName()
98 const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName)
99 98
100 return downloadImage(icon.url, thumbnailPath, THUMBNAILS_SIZE) 99 return downloadImage(icon.url, CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName, THUMBNAILS_SIZE)
101} 100}
102 101
103function getOrCreateVideoChannelFromVideoObject (videoObject: VideoTorrentObject) { 102function getOrCreateVideoChannelFromVideoObject (videoObject: VideoTorrentObject) {
@@ -156,29 +155,34 @@ async function syncVideoExternalAttributes (video: VideoModel, fetchedVideo: Vid
156} 155}
157 156
158async function getOrCreateVideoAndAccountAndChannel (options: { 157async function getOrCreateVideoAndAccountAndChannel (options: {
159 videoObject: VideoTorrentObject | string, 158 videoObject: { id: string } | string,
160 syncParam?: SyncParam, 159 syncParam?: SyncParam,
161 fetchType?: VideoFetchByUrlType 160 fetchType?: VideoFetchByUrlType,
161 allowRefresh?: boolean // true by default
162}) { 162}) {
163 // Default params 163 // Default params
164 const syncParam = options.syncParam || { likes: true, dislikes: true, shares: true, comments: true, thumbnail: true, refreshVideo: false } 164 const syncParam = options.syncParam || { likes: true, dislikes: true, shares: true, comments: true, thumbnail: true, refreshVideo: false }
165 const fetchType = options.fetchType || 'all' 165 const fetchType = options.fetchType || 'all'
166 const allowRefresh = options.allowRefresh !== false
166 167
167 // Get video url 168 // Get video url
168 const videoUrl = getAPUrl(options.videoObject) 169 const videoUrl = getAPId(options.videoObject)
169 170
170 let videoFromDatabase = await fetchVideoByUrl(videoUrl, fetchType) 171 let videoFromDatabase = await fetchVideoByUrl(videoUrl, fetchType)
171 if (videoFromDatabase) { 172 if (videoFromDatabase) {
172 const refreshOptions = {
173 video: videoFromDatabase,
174 fetchedType: fetchType,
175 syncParam
176 }
177 173
178 if (syncParam.refreshVideo === true) videoFromDatabase = await refreshVideoIfNeeded(refreshOptions) 174 if (allowRefresh === true) {
179 else await JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', videoUrl: videoFromDatabase.url } }) 175 const refreshOptions = {
176 video: videoFromDatabase,
177 fetchedType: fetchType,
178 syncParam
179 }
180
181 if (syncParam.refreshVideo === true) videoFromDatabase = await refreshVideoIfNeeded(refreshOptions)
182 else await JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', url: videoFromDatabase.url } })
183 }
180 184
181 return { video: videoFromDatabase } 185 return { video: videoFromDatabase, created: false }
182 } 186 }
183 187
184 const { videoObject: fetchedVideo } = await fetchRemoteVideo(videoUrl) 188 const { videoObject: fetchedVideo } = await fetchRemoteVideo(videoUrl)
@@ -189,7 +193,7 @@ async function getOrCreateVideoAndAccountAndChannel (options: {
189 193
190 await syncVideoExternalAttributes(video, fetchedVideo, syncParam) 194 await syncVideoExternalAttributes(video, fetchedVideo, syncParam)
191 195
192 return { video } 196 return { video, created: true }
193} 197}
194 198
195async function updateVideoFromAP (options: { 199async function updateVideoFromAP (options: {
@@ -200,13 +204,14 @@ async function updateVideoFromAP (options: {
200 overrideTo?: string[] 204 overrideTo?: string[]
201}) { 205}) {
202 logger.debug('Updating remote video "%s".', options.videoObject.uuid) 206 logger.debug('Updating remote video "%s".', options.videoObject.uuid)
207
203 let videoFieldsSave: any 208 let videoFieldsSave: any
209 const wasPrivateVideo = options.video.privacy === VideoPrivacy.PRIVATE
210 const wasUnlistedVideo = options.video.privacy === VideoPrivacy.UNLISTED
204 211
205 try { 212 try {
206 await sequelizeTypescript.transaction(async t => { 213 await sequelizeTypescript.transaction(async t => {
207 const sequelizeOptions = { 214 const sequelizeOptions = { transaction: t }
208 transaction: t
209 }
210 215
211 videoFieldsSave = options.video.toJSON() 216 videoFieldsSave = options.video.toJSON()
212 217
@@ -276,6 +281,11 @@ async function updateVideoFromAP (options: {
276 } 281 }
277 }) 282 })
278 283
284 // Notify our users?
285 if (wasPrivateVideo || wasUnlistedVideo) {
286 Notifier.Instance.notifyOnNewVideo(options.video)
287 }
288
279 logger.info('Remote video with uuid %s updated', options.videoObject.uuid) 289 logger.info('Remote video with uuid %s updated', options.videoObject.uuid)
280 } catch (err) { 290 } catch (err) {
281 if (options.video !== undefined && videoFieldsSave !== undefined) { 291 if (options.video !== undefined && videoFieldsSave !== undefined) {
@@ -358,7 +368,7 @@ export {
358// --------------------------------------------------------------------------- 368// ---------------------------------------------------------------------------
359 369
360function isActivityVideoUrlObject (url: ActivityUrlObject): url is ActivityVideoUrlObject { 370function isActivityVideoUrlObject (url: ActivityUrlObject): url is ActivityVideoUrlObject {
361 const mimeTypes = Object.keys(VIDEO_MIMETYPE_EXT) 371 const mimeTypes = Object.keys(MIMETYPES.VIDEO.MIMETYPE_EXT)
362 372
363 const urlMediaType = url.mediaType || url.mimeType 373 const urlMediaType = url.mediaType || url.mimeType
364 return mimeTypes.indexOf(urlMediaType) !== -1 && urlMediaType.startsWith('video/') 374 return mimeTypes.indexOf(urlMediaType) !== -1 && urlMediaType.startsWith('video/')
@@ -486,7 +496,7 @@ function videoFileActivityUrlToDBAttributes (video: VideoModel, videoObject: Vid
486 496
487 const mediaType = fileUrl.mediaType || fileUrl.mimeType 497 const mediaType = fileUrl.mediaType || fileUrl.mimeType
488 const attribute = { 498 const attribute = {
489 extname: VIDEO_MIMETYPE_EXT[ mediaType ], 499 extname: MIMETYPES.VIDEO.MIMETYPE_EXT[ mediaType ],
490 infoHash: parsed.infoHash, 500 infoHash: parsed.infoHash,
491 resolution: fileUrl.height, 501 resolution: fileUrl.height,
492 size: fileUrl.size, 502 size: fileUrl.size,
diff --git a/server/lib/cache/actor-follow-score-cache.ts b/server/lib/cache/actor-follow-score-cache.ts
new file mode 100644
index 000000000..d070bde09
--- /dev/null
+++ b/server/lib/cache/actor-follow-score-cache.ts
@@ -0,0 +1,46 @@
1import { ACTOR_FOLLOW_SCORE } from '../../initializers'
2import { logger } from '../../helpers/logger'
3
4// Cache follows scores, instead of writing them too often in database
5// Keep data in memory, we don't really need Redis here as we don't really care to loose some scores
6class ActorFollowScoreCache {
7
8 private static instance: ActorFollowScoreCache
9 private pendingFollowsScore: { [ url: string ]: number } = {}
10
11 private constructor () {}
12
13 static get Instance () {
14 return this.instance || (this.instance = new this())
15 }
16
17 updateActorFollowsScore (goodInboxes: string[], badInboxes: string[]) {
18 if (goodInboxes.length === 0 && badInboxes.length === 0) return
19
20 logger.info('Updating %d good actor follows and %d bad actor follows scores in cache.', goodInboxes.length, badInboxes.length)
21
22 for (const goodInbox of goodInboxes) {
23 if (this.pendingFollowsScore[goodInbox] === undefined) this.pendingFollowsScore[goodInbox] = 0
24
25 this.pendingFollowsScore[goodInbox] += ACTOR_FOLLOW_SCORE.BONUS
26 }
27
28 for (const badInbox of badInboxes) {
29 if (this.pendingFollowsScore[badInbox] === undefined) this.pendingFollowsScore[badInbox] = 0
30
31 this.pendingFollowsScore[badInbox] += ACTOR_FOLLOW_SCORE.PENALTY
32 }
33 }
34
35 getPendingFollowsScoreCopy () {
36 return this.pendingFollowsScore
37 }
38
39 clearPendingFollowsScore () {
40 this.pendingFollowsScore = {}
41 }
42}
43
44export {
45 ActorFollowScoreCache
46}
diff --git a/server/lib/cache/index.ts b/server/lib/cache/index.ts
index 54eb983fa..e921d04a7 100644
--- a/server/lib/cache/index.ts
+++ b/server/lib/cache/index.ts
@@ -1,2 +1,3 @@
1export * from './actor-follow-score-cache'
1export * from './videos-preview-cache' 2export * from './videos-preview-cache'
2export * from './videos-caption-cache' 3export * from './videos-caption-cache'
diff --git a/server/lib/client-html.ts b/server/lib/client-html.ts
index fc013e0c3..b2c376e20 100644
--- a/server/lib/client-html.ts
+++ b/server/lib/client-html.ts
@@ -1,7 +1,7 @@
1import * as express from 'express' 1import * as express from 'express'
2import * as Bluebird from 'bluebird' 2import * as Bluebird from 'bluebird'
3import { buildFileLocale, getDefaultLocale, is18nLocale, POSSIBLE_LOCALES } from '../../shared/models/i18n/i18n' 3import { buildFileLocale, getDefaultLocale, is18nLocale, POSSIBLE_LOCALES } from '../../shared/models/i18n/i18n'
4import { CONFIG, CUSTOM_HTML_TAG_COMMENTS, EMBED_SIZE, STATIC_PATHS } from '../initializers' 4import { CONFIG, CUSTOM_HTML_TAG_COMMENTS, EMBED_SIZE } from '../initializers'
5import { join } from 'path' 5import { join } from 'path'
6import { escapeHTML } from '../helpers/core-utils' 6import { escapeHTML } from '../helpers/core-utils'
7import { VideoModel } from '../models/video/video' 7import { VideoModel } from '../models/video/video'
@@ -18,21 +18,13 @@ export class ClientHtml {
18 ClientHtml.htmlCache = {} 18 ClientHtml.htmlCache = {}
19 } 19 }
20 20
21 static async getIndexHTML (req: express.Request, res: express.Response, paramLang?: string) { 21 static async getDefaultHTMLPage (req: express.Request, res: express.Response, paramLang?: string) {
22 const path = ClientHtml.getIndexPath(req, res, paramLang) 22 const html = await ClientHtml.getIndexHTML(req, res, paramLang)
23 if (ClientHtml.htmlCache[path]) return ClientHtml.htmlCache[path]
24
25 const buffer = await readFile(path)
26 23
27 let html = buffer.toString() 24 let customHtml = ClientHtml.addTitleTag(html)
28 25 customHtml = ClientHtml.addDescriptionTag(customHtml)
29 html = ClientHtml.addTitleTag(html)
30 html = ClientHtml.addDescriptionTag(html)
31 html = ClientHtml.addCustomCSS(html)
32 26
33 ClientHtml.htmlCache[path] = html 27 return customHtml
34
35 return html
36 } 28 }
37 29
38 static async getWatchHTMLPage (videoId: string, req: express.Request, res: express.Response) { 30 static async getWatchHTMLPage (videoId: string, req: express.Request, res: express.Response) {
@@ -55,7 +47,26 @@ export class ClientHtml {
55 return ClientHtml.getIndexHTML(req, res) 47 return ClientHtml.getIndexHTML(req, res)
56 } 48 }
57 49
58 return ClientHtml.addOpenGraphAndOEmbedTags(html, video) 50 let customHtml = ClientHtml.addTitleTag(html, escapeHTML(video.name))
51 customHtml = ClientHtml.addDescriptionTag(customHtml, escapeHTML(video.description))
52 customHtml = ClientHtml.addOpenGraphAndOEmbedTags(customHtml, video)
53
54 return customHtml
55 }
56
57 private static async getIndexHTML (req: express.Request, res: express.Response, paramLang?: string) {
58 const path = ClientHtml.getIndexPath(req, res, paramLang)
59 if (ClientHtml.htmlCache[path]) return ClientHtml.htmlCache[path]
60
61 const buffer = await readFile(path)
62
63 let html = buffer.toString()
64
65 html = ClientHtml.addCustomCSS(html)
66
67 ClientHtml.htmlCache[path] = html
68
69 return html
59 } 70 }
60 71
61 private static getIndexPath (req: express.Request, res: express.Response, paramLang?: string) { 72 private static getIndexPath (req: express.Request, res: express.Response, paramLang?: string) {
@@ -81,14 +92,18 @@ export class ClientHtml {
81 return join(__dirname, '../../../client/dist/' + buildFileLocale(lang) + '/index.html') 92 return join(__dirname, '../../../client/dist/' + buildFileLocale(lang) + '/index.html')
82 } 93 }
83 94
84 private static addTitleTag (htmlStringPage: string) { 95 private static addTitleTag (htmlStringPage: string, title?: string) {
85 const titleTag = '<title>' + CONFIG.INSTANCE.NAME + '</title>' 96 let text = title || CONFIG.INSTANCE.NAME
97 if (title) text += ` - ${CONFIG.INSTANCE.NAME}`
98
99 const titleTag = `<title>${text}</title>`
86 100
87 return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.TITLE, titleTag) 101 return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.TITLE, titleTag)
88 } 102 }
89 103
90 private static addDescriptionTag (htmlStringPage: string) { 104 private static addDescriptionTag (htmlStringPage: string, description?: string) {
91 const descriptionTag = `<meta name="description" content="${CONFIG.INSTANCE.SHORT_DESCRIPTION}" />` 105 const content = description || CONFIG.INSTANCE.SHORT_DESCRIPTION
106 const descriptionTag = `<meta name="description" content="${content}" />`
92 107
93 return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.DESCRIPTION, descriptionTag) 108 return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.DESCRIPTION, descriptionTag)
94 } 109 }
@@ -100,8 +115,8 @@ export class ClientHtml {
100 } 115 }
101 116
102 private static addOpenGraphAndOEmbedTags (htmlStringPage: string, video: VideoModel) { 117 private static addOpenGraphAndOEmbedTags (htmlStringPage: string, video: VideoModel) {
103 const previewUrl = CONFIG.WEBSERVER.URL + STATIC_PATHS.PREVIEWS + video.getPreviewName() 118 const previewUrl = CONFIG.WEBSERVER.URL + video.getPreviewStaticPath()
104 const videoUrl = CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid 119 const videoUrl = CONFIG.WEBSERVER.URL + video.getWatchStaticPath()
105 120
106 const videoNameEscaped = escapeHTML(video.name) 121 const videoNameEscaped = escapeHTML(video.name)
107 const videoDescriptionEscaped = escapeHTML(video.description) 122 const videoDescriptionEscaped = escapeHTML(video.description)
@@ -172,8 +187,8 @@ export class ClientHtml {
172 // Schema.org 187 // Schema.org
173 tagsString += `<script type="application/ld+json">${JSON.stringify(schemaTags)}</script>` 188 tagsString += `<script type="application/ld+json">${JSON.stringify(schemaTags)}</script>`
174 189
175 // SEO 190 // SEO, use origin video url so Google does not index remote videos
176 tagsString += `<link rel="canonical" href="${videoUrl}" />` 191 tagsString += `<link rel="canonical" href="${video.url}" />`
177 192
178 return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.OPENGRAPH_AND_OEMBED, tagsString) 193 return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.OPENGRAPH_AND_OEMBED, tagsString)
179 } 194 }
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts
index 9327792fb..f384a254e 100644
--- a/server/lib/emailer.ts
+++ b/server/lib/emailer.ts
@@ -1,5 +1,4 @@
1import { createTransport, Transporter } from 'nodemailer' 1import { createTransport, Transporter } from 'nodemailer'
2import { UserRight } from '../../shared/models/users'
3import { isTestInstance } from '../helpers/core-utils' 2import { isTestInstance } from '../helpers/core-utils'
4import { bunyanLogger, logger } from '../helpers/logger' 3import { bunyanLogger, logger } from '../helpers/logger'
5import { CONFIG } from '../initializers' 4import { CONFIG } from '../initializers'
@@ -8,6 +7,11 @@ import { VideoModel } from '../models/video/video'
8import { JobQueue } from './job-queue' 7import { JobQueue } from './job-queue'
9import { EmailPayload } from './job-queue/handlers/email' 8import { EmailPayload } from './job-queue/handlers/email'
10import { readFileSync } from 'fs-extra' 9import { readFileSync } from 'fs-extra'
10import { VideoCommentModel } from '../models/video/video-comment'
11import { VideoAbuseModel } from '../models/video/video-abuse'
12import { VideoBlacklistModel } from '../models/video/video-blacklist'
13import { VideoImportModel } from '../models/video/video-import'
14import { ActorFollowModel } from '../models/activitypub/actor-follow'
11 15
12class Emailer { 16class Emailer {
13 17
@@ -22,7 +26,7 @@ class Emailer {
22 if (this.initialized === true) return 26 if (this.initialized === true) return
23 this.initialized = true 27 this.initialized = true
24 28
25 if (CONFIG.SMTP.HOSTNAME && CONFIG.SMTP.PORT) { 29 if (Emailer.isEnabled()) {
26 logger.info('Using %s:%s as SMTP server.', CONFIG.SMTP.HOSTNAME, CONFIG.SMTP.PORT) 30 logger.info('Using %s:%s as SMTP server.', CONFIG.SMTP.HOSTNAME, CONFIG.SMTP.PORT)
27 31
28 let tls 32 let tls
@@ -57,6 +61,10 @@ class Emailer {
57 } 61 }
58 } 62 }
59 63
64 static isEnabled () {
65 return !!CONFIG.SMTP.HOSTNAME && !!CONFIG.SMTP.PORT
66 }
67
60 async checkConnectionOrDie () { 68 async checkConnectionOrDie () {
61 if (!this.transporter) return 69 if (!this.transporter) return
62 70
@@ -72,50 +80,158 @@ class Emailer {
72 } 80 }
73 } 81 }
74 82
75 addForgetPasswordEmailJob (to: string, resetPasswordUrl: string) { 83 addNewVideoFromSubscriberNotification (to: string[], video: VideoModel) {
84 const channelName = video.VideoChannel.getDisplayName()
85 const videoUrl = CONFIG.WEBSERVER.URL + video.getWatchStaticPath()
86
76 const text = `Hi dear user,\n\n` + 87 const text = `Hi dear user,\n\n` +
77 `It seems you forgot your password on ${CONFIG.WEBSERVER.HOST}! ` + 88 `Your subscription ${channelName} just published a new video: ${video.name}` +
78 `Please follow this link to reset it: ${resetPasswordUrl}\n\n` + 89 `\n\n` +
79 `If you are not the person who initiated this request, please ignore this email.\n\n` + 90 `You can view it on ${videoUrl} ` +
91 `\n\n` +
80 `Cheers,\n` + 92 `Cheers,\n` +
81 `PeerTube.` 93 `PeerTube.`
82 94
83 const emailPayload: EmailPayload = { 95 const emailPayload: EmailPayload = {
84 to: [ to ], 96 to,
85 subject: 'Reset your PeerTube password', 97 subject: channelName + ' just published a new video',
86 text 98 text
87 } 99 }
88 100
89 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) 101 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
90 } 102 }
91 103
92 addVerifyEmailJob (to: string, verifyEmailUrl: string) { 104 addNewFollowNotification (to: string[], actorFollow: ActorFollowModel, followType: 'account' | 'channel') {
93 const text = `Welcome to PeerTube,\n\n` + 105 const followerName = actorFollow.ActorFollower.Account.getDisplayName()
94 `To start using PeerTube on ${CONFIG.WEBSERVER.HOST} you must verify your email! ` + 106 const followingName = (actorFollow.ActorFollowing.VideoChannel || actorFollow.ActorFollowing.Account).getDisplayName()
95 `Please follow this link to verify this email belongs to you: ${verifyEmailUrl}\n\n` + 107
96 `If you are not the person who initiated this request, please ignore this email.\n\n` + 108 const text = `Hi dear user,\n\n` +
109 `Your ${followType} ${followingName} has a new subscriber: ${followerName}` +
110 `\n\n` +
97 `Cheers,\n` + 111 `Cheers,\n` +
98 `PeerTube.` 112 `PeerTube.`
99 113
100 const emailPayload: EmailPayload = { 114 const emailPayload: EmailPayload = {
101 to: [ to ], 115 to,
102 subject: 'Verify your PeerTube email', 116 subject: 'New follower on your channel ' + followingName,
117 text
118 }
119
120 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
121 }
122
123 myVideoPublishedNotification (to: string[], video: VideoModel) {
124 const videoUrl = CONFIG.WEBSERVER.URL + video.getWatchStaticPath()
125
126 const text = `Hi dear user,\n\n` +
127 `Your video ${video.name} has been published.` +
128 `\n\n` +
129 `You can view it on ${videoUrl} ` +
130 `\n\n` +
131 `Cheers,\n` +
132 `PeerTube.`
133
134 const emailPayload: EmailPayload = {
135 to,
136 subject: `Your video ${video.name} is published`,
137 text
138 }
139
140 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
141 }
142
143 myVideoImportSuccessNotification (to: string[], videoImport: VideoImportModel) {
144 const videoUrl = CONFIG.WEBSERVER.URL + videoImport.Video.getWatchStaticPath()
145
146 const text = `Hi dear user,\n\n` +
147 `Your video import ${videoImport.getTargetIdentifier()} is finished.` +
148 `\n\n` +
149 `You can view the imported video on ${videoUrl} ` +
150 `\n\n` +
151 `Cheers,\n` +
152 `PeerTube.`
153
154 const emailPayload: EmailPayload = {
155 to,
156 subject: `Your video import ${videoImport.getTargetIdentifier()} is finished`,
103 text 157 text
104 } 158 }
105 159
106 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) 160 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
107 } 161 }
108 162
109 async addVideoAbuseReportJob (videoId: number) { 163 myVideoImportErrorNotification (to: string[], videoImport: VideoImportModel) {
110 const video = await VideoModel.load(videoId) 164 const importUrl = CONFIG.WEBSERVER.URL + '/my-account/video-imports'
111 if (!video) throw new Error('Unknown Video id during Abuse report.') 165
166 const text = `Hi dear user,\n\n` +
167 `Your video import ${videoImport.getTargetIdentifier()} encountered an error.` +
168 `\n\n` +
169 `See your videos import dashboard for more information: ${importUrl}` +
170 `\n\n` +
171 `Cheers,\n` +
172 `PeerTube.`
173
174 const emailPayload: EmailPayload = {
175 to,
176 subject: `Your video import ${videoImport.getTargetIdentifier()} encountered an error`,
177 text
178 }
179
180 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
181 }
182
183 addNewCommentOnMyVideoNotification (to: string[], comment: VideoCommentModel) {
184 const accountName = comment.Account.getDisplayName()
185 const video = comment.Video
186 const commentUrl = CONFIG.WEBSERVER.URL + comment.getCommentStaticPath()
187
188 const text = `Hi dear user,\n\n` +
189 `A new comment has been posted by ${accountName} on your video ${video.name}` +
190 `\n\n` +
191 `You can view it on ${commentUrl} ` +
192 `\n\n` +
193 `Cheers,\n` +
194 `PeerTube.`
195
196 const emailPayload: EmailPayload = {
197 to,
198 subject: 'New comment on your video ' + video.name,
199 text
200 }
201
202 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
203 }
204
205 addNewCommentMentionNotification (to: string[], comment: VideoCommentModel) {
206 const accountName = comment.Account.getDisplayName()
207 const video = comment.Video
208 const commentUrl = CONFIG.WEBSERVER.URL + comment.getCommentStaticPath()
209
210 const text = `Hi dear user,\n\n` +
211 `${accountName} mentioned you on video ${video.name}` +
212 `\n\n` +
213 `You can view the comment on ${commentUrl} ` +
214 `\n\n` +
215 `Cheers,\n` +
216 `PeerTube.`
217
218 const emailPayload: EmailPayload = {
219 to,
220 subject: 'Mention on video ' + video.name,
221 text
222 }
223
224 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
225 }
226
227 addVideoAbuseModeratorsNotification (to: string[], videoAbuse: VideoAbuseModel) {
228 const videoUrl = CONFIG.WEBSERVER.URL + videoAbuse.Video.getWatchStaticPath()
112 229
113 const text = `Hi,\n\n` + 230 const text = `Hi,\n\n` +
114 `Your instance received an abuse for the following video ${video.url}\n\n` + 231 `${CONFIG.WEBSERVER.HOST} received an abuse for the following video ${videoUrl}\n\n` +
115 `Cheers,\n` + 232 `Cheers,\n` +
116 `PeerTube.` 233 `PeerTube.`
117 234
118 const to = await UserModel.listEmailsWithRight(UserRight.MANAGE_VIDEO_ABUSES)
119 const emailPayload: EmailPayload = { 235 const emailPayload: EmailPayload = {
120 to, 236 to,
121 subject: '[PeerTube] Received a video abuse', 237 subject: '[PeerTube] Received a video abuse',
@@ -125,16 +241,27 @@ class Emailer {
125 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) 241 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
126 } 242 }
127 243
128 async addVideoBlacklistReportJob (videoId: number, reason?: string) { 244 addNewUserRegistrationNotification (to: string[], user: UserModel) {
129 const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoId) 245 const text = `Hi,\n\n` +
130 if (!video) throw new Error('Unknown Video id during Blacklist report.') 246 `User ${user.username} just registered on ${CONFIG.WEBSERVER.HOST} PeerTube instance.\n\n` +
131 // It's not our user 247 `Cheers,\n` +
132 if (video.remote === true) return 248 `PeerTube.`
133 249
134 const user = await UserModel.loadById(video.VideoChannel.Account.userId) 250 const emailPayload: EmailPayload = {
251 to,
252 subject: '[PeerTube] New user registration on ' + CONFIG.WEBSERVER.HOST,
253 text
254 }
135 255
136 const reasonString = reason ? ` for the following reason: ${reason}` : '' 256 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
137 const blockedString = `Your video ${video.name} on ${CONFIG.WEBSERVER.HOST} has been blacklisted${reasonString}.` 257 }
258
259 addVideoBlacklistNotification (to: string[], videoBlacklist: VideoBlacklistModel) {
260 const videoName = videoBlacklist.Video.name
261 const videoUrl = CONFIG.WEBSERVER.URL + videoBlacklist.Video.getWatchStaticPath()
262
263 const reasonString = videoBlacklist.reason ? ` for the following reason: ${videoBlacklist.reason}` : ''
264 const blockedString = `Your video ${videoName} (${videoUrl} on ${CONFIG.WEBSERVER.HOST} has been blacklisted${reasonString}.`
138 265
139 const text = 'Hi,\n\n' + 266 const text = 'Hi,\n\n' +
140 blockedString + 267 blockedString +
@@ -142,33 +269,26 @@ class Emailer {
142 'Cheers,\n' + 269 'Cheers,\n' +
143 `PeerTube.` 270 `PeerTube.`
144 271
145 const to = user.email
146 const emailPayload: EmailPayload = { 272 const emailPayload: EmailPayload = {
147 to: [ to ], 273 to,
148 subject: `[PeerTube] Video ${video.name} blacklisted`, 274 subject: `[PeerTube] Video ${videoName} blacklisted`,
149 text 275 text
150 } 276 }
151 277
152 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) 278 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
153 } 279 }
154 280
155 async addVideoUnblacklistReportJob (videoId: number) { 281 addVideoUnblacklistNotification (to: string[], video: VideoModel) {
156 const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoId) 282 const videoUrl = CONFIG.WEBSERVER.URL + video.getWatchStaticPath()
157 if (!video) throw new Error('Unknown Video id during Blacklist report.')
158 // It's not our user
159 if (video.remote === true) return
160
161 const user = await UserModel.loadById(video.VideoChannel.Account.userId)
162 283
163 const text = 'Hi,\n\n' + 284 const text = 'Hi,\n\n' +
164 `Your video ${video.name} on ${CONFIG.WEBSERVER.HOST} has been unblacklisted.` + 285 `Your video ${video.name} (${videoUrl}) on ${CONFIG.WEBSERVER.HOST} has been unblacklisted.` +
165 '\n\n' + 286 '\n\n' +
166 'Cheers,\n' + 287 'Cheers,\n' +
167 `PeerTube.` 288 `PeerTube.`
168 289
169 const to = user.email
170 const emailPayload: EmailPayload = { 290 const emailPayload: EmailPayload = {
171 to: [ to ], 291 to,
172 subject: `[PeerTube] Video ${video.name} unblacklisted`, 292 subject: `[PeerTube] Video ${video.name} unblacklisted`,
173 text 293 text
174 } 294 }
@@ -176,6 +296,40 @@ class Emailer {
176 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) 296 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
177 } 297 }
178 298
299 addForgetPasswordEmailJob (to: string, resetPasswordUrl: string) {
300 const text = `Hi dear user,\n\n` +
301 `It seems you forgot your password on ${CONFIG.WEBSERVER.HOST}! ` +
302 `Please follow this link to reset it: ${resetPasswordUrl}\n\n` +
303 `If you are not the person who initiated this request, please ignore this email.\n\n` +
304 `Cheers,\n` +
305 `PeerTube.`
306
307 const emailPayload: EmailPayload = {
308 to: [ to ],
309 subject: 'Reset your PeerTube password',
310 text
311 }
312
313 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
314 }
315
316 addVerifyEmailJob (to: string, verifyEmailUrl: string) {
317 const text = `Welcome to PeerTube,\n\n` +
318 `To start using PeerTube on ${CONFIG.WEBSERVER.HOST} you must verify your email! ` +
319 `Please follow this link to verify this email belongs to you: ${verifyEmailUrl}\n\n` +
320 `If you are not the person who initiated this request, please ignore this email.\n\n` +
321 `Cheers,\n` +
322 `PeerTube.`
323
324 const emailPayload: EmailPayload = {
325 to: [ to ],
326 subject: 'Verify your PeerTube email',
327 text
328 }
329
330 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
331 }
332
179 addUserBlockJob (user: UserModel, blocked: boolean, reason?: string) { 333 addUserBlockJob (user: UserModel, blocked: boolean, reason?: string) {
180 const reasonString = reason ? ` for the following reason: ${reason}` : '' 334 const reasonString = reason ? ` for the following reason: ${reason}` : ''
181 const blockedWord = blocked ? 'blocked' : 'unblocked' 335 const blockedWord = blocked ? 'blocked' : 'unblocked'
@@ -197,13 +351,32 @@ class Emailer {
197 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload }) 351 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
198 } 352 }
199 353
200 sendMail (to: string[], subject: string, text: string) { 354 addContactFormJob (fromEmail: string, fromName: string, body: string) {
201 if (!this.transporter) { 355 const text = 'Hello dear admin,\n\n' +
356 fromName + ' sent you a message' +
357 '\n\n---------------------------------------\n\n' +
358 body +
359 '\n\n---------------------------------------\n\n' +
360 'Cheers,\n' +
361 'PeerTube.'
362
363 const emailPayload: EmailPayload = {
364 from: fromEmail,
365 to: [ CONFIG.ADMIN.EMAIL ],
366 subject: '[PeerTube] Contact form submitted',
367 text
368 }
369
370 return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
371 }
372
373 sendMail (to: string[], subject: string, text: string, from?: string) {
374 if (!Emailer.isEnabled()) {
202 throw new Error('Cannot send mail because SMTP is not configured.') 375 throw new Error('Cannot send mail because SMTP is not configured.')
203 } 376 }
204 377
205 return this.transporter.sendMail({ 378 return this.transporter.sendMail({
206 from: CONFIG.SMTP.FROM_ADDRESS, 379 from: from || CONFIG.SMTP.FROM_ADDRESS,
207 to: to.join(','), 380 to: to.join(','),
208 subject, 381 subject,
209 text 382 text
diff --git a/server/lib/job-queue/handlers/activitypub-follow.ts b/server/lib/job-queue/handlers/activitypub-follow.ts
index 36d0f237b..b4d381062 100644
--- a/server/lib/job-queue/handlers/activitypub-follow.ts
+++ b/server/lib/job-queue/handlers/activitypub-follow.ts
@@ -8,6 +8,7 @@ import { getOrCreateActorAndServerAndModel } from '../../activitypub/actor'
8import { retryTransactionWrapper } from '../../../helpers/database-utils' 8import { retryTransactionWrapper } from '../../../helpers/database-utils'
9import { ActorFollowModel } from '../../../models/activitypub/actor-follow' 9import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
10import { ActorModel } from '../../../models/activitypub/actor' 10import { ActorModel } from '../../../models/activitypub/actor'
11import { Notifier } from '../../notifier'
11 12
12export type ActivitypubFollowPayload = { 13export type ActivitypubFollowPayload = {
13 followerActorId: number 14 followerActorId: number
@@ -42,7 +43,7 @@ export {
42 43
43// --------------------------------------------------------------------------- 44// ---------------------------------------------------------------------------
44 45
45function follow (fromActor: ActorModel, targetActor: ActorModel) { 46async function follow (fromActor: ActorModel, targetActor: ActorModel) {
46 if (fromActor.id === targetActor.id) { 47 if (fromActor.id === targetActor.id) {
47 throw new Error('Follower is the same than target actor.') 48 throw new Error('Follower is the same than target actor.')
48 } 49 }
@@ -50,7 +51,7 @@ function follow (fromActor: ActorModel, targetActor: ActorModel) {
50 // Same server, direct accept 51 // Same server, direct accept
51 const state = !fromActor.serverId && !targetActor.serverId ? 'accepted' : 'pending' 52 const state = !fromActor.serverId && !targetActor.serverId ? 'accepted' : 'pending'
52 53
53 return sequelizeTypescript.transaction(async t => { 54 const actorFollow = await sequelizeTypescript.transaction(async t => {
54 const [ actorFollow ] = await ActorFollowModel.findOrCreate({ 55 const [ actorFollow ] = await ActorFollowModel.findOrCreate({
55 where: { 56 where: {
56 actorId: fromActor.id, 57 actorId: fromActor.id,
@@ -68,5 +69,9 @@ function follow (fromActor: ActorModel, targetActor: ActorModel) {
68 69
69 // Send a notification to remote server if our follow is not already accepted 70 // Send a notification to remote server if our follow is not already accepted
70 if (actorFollow.state !== 'accepted') await sendFollow(actorFollow) 71 if (actorFollow.state !== 'accepted') await sendFollow(actorFollow)
72
73 return actorFollow
71 }) 74 })
75
76 if (actorFollow.state === 'accepted') Notifier.Instance.notifyOfNewFollow(actorFollow)
72} 77}
diff --git a/server/lib/job-queue/handlers/activitypub-http-broadcast.ts b/server/lib/job-queue/handlers/activitypub-http-broadcast.ts
index abbd89b3b..9493945ff 100644
--- a/server/lib/job-queue/handlers/activitypub-http-broadcast.ts
+++ b/server/lib/job-queue/handlers/activitypub-http-broadcast.ts
@@ -5,6 +5,7 @@ import { doRequest } from '../../../helpers/requests'
5import { ActorFollowModel } from '../../../models/activitypub/actor-follow' 5import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
6import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils' 6import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils'
7import { BROADCAST_CONCURRENCY, JOB_REQUEST_TIMEOUT } from '../../../initializers' 7import { BROADCAST_CONCURRENCY, JOB_REQUEST_TIMEOUT } from '../../../initializers'
8import { ActorFollowScoreCache } from '../../cache'
8 9
9export type ActivitypubHttpBroadcastPayload = { 10export type ActivitypubHttpBroadcastPayload = {
10 uris: string[] 11 uris: string[]
@@ -38,7 +39,7 @@ async function processActivityPubHttpBroadcast (job: Bull.Job) {
38 .catch(() => badUrls.push(uri)) 39 .catch(() => badUrls.push(uri))
39 }, { concurrency: BROADCAST_CONCURRENCY }) 40 }, { concurrency: BROADCAST_CONCURRENCY })
40 41
41 return ActorFollowModel.updateActorFollowsScore(goodUrls, badUrls, undefined) 42 return ActorFollowScoreCache.Instance.updateActorFollowsScore(goodUrls, badUrls)
42} 43}
43 44
44// --------------------------------------------------------------------------- 45// ---------------------------------------------------------------------------
diff --git a/server/lib/job-queue/handlers/activitypub-http-unicast.ts b/server/lib/job-queue/handlers/activitypub-http-unicast.ts
index d36479032..3973dcdc8 100644
--- a/server/lib/job-queue/handlers/activitypub-http-unicast.ts
+++ b/server/lib/job-queue/handlers/activitypub-http-unicast.ts
@@ -1,9 +1,9 @@
1import * as Bull from 'bull' 1import * as Bull from 'bull'
2import { logger } from '../../../helpers/logger' 2import { logger } from '../../../helpers/logger'
3import { doRequest } from '../../../helpers/requests' 3import { doRequest } from '../../../helpers/requests'
4import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
5import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils' 4import { buildGlobalHeaders, buildSignedRequestOptions, computeBody } from './utils/activitypub-http-utils'
6import { JOB_REQUEST_TIMEOUT } from '../../../initializers' 5import { JOB_REQUEST_TIMEOUT } from '../../../initializers'
6import { ActorFollowScoreCache } from '../../cache'
7 7
8export type ActivitypubHttpUnicastPayload = { 8export type ActivitypubHttpUnicastPayload = {
9 uri: string 9 uri: string
@@ -31,9 +31,9 @@ async function processActivityPubHttpUnicast (job: Bull.Job) {
31 31
32 try { 32 try {
33 await doRequest(options) 33 await doRequest(options)
34 ActorFollowModel.updateActorFollowsScore([ uri ], [], undefined) 34 ActorFollowScoreCache.Instance.updateActorFollowsScore([ uri ], [])
35 } catch (err) { 35 } catch (err) {
36 ActorFollowModel.updateActorFollowsScore([], [ uri ], undefined) 36 ActorFollowScoreCache.Instance.updateActorFollowsScore([], [ uri ])
37 37
38 throw err 38 throw err
39 } 39 }
diff --git a/server/lib/job-queue/handlers/activitypub-refresher.ts b/server/lib/job-queue/handlers/activitypub-refresher.ts
index 7752b3b40..454b975fe 100644
--- a/server/lib/job-queue/handlers/activitypub-refresher.ts
+++ b/server/lib/job-queue/handlers/activitypub-refresher.ts
@@ -1,29 +1,33 @@
1import * as Bull from 'bull' 1import * as Bull from 'bull'
2import { logger } from '../../../helpers/logger' 2import { logger } from '../../../helpers/logger'
3import { fetchVideoByUrl } from '../../../helpers/video' 3import { fetchVideoByUrl } from '../../../helpers/video'
4import { refreshVideoIfNeeded } from '../../activitypub' 4import { refreshVideoIfNeeded, refreshActorIfNeeded } from '../../activitypub'
5import { ActorModel } from '../../../models/activitypub/actor'
5 6
6export type RefreshPayload = { 7export type RefreshPayload = {
7 videoUrl: string 8 type: 'video' | 'actor'
8 type: 'video' 9 url: string
9} 10}
10 11
11async function refreshAPObject (job: Bull.Job) { 12async function refreshAPObject (job: Bull.Job) {
12 const payload = job.data as RefreshPayload 13 const payload = job.data as RefreshPayload
13 logger.info('Processing AP refresher in job %d.', job.id)
14 14
15 if (payload.type === 'video') return refreshAPVideo(payload.videoUrl) 15 logger.info('Processing AP refresher in job %d for %s.', job.id, payload.url)
16
17 if (payload.type === 'video') return refreshVideo(payload.url)
18 if (payload.type === 'actor') return refreshActor(payload.url)
16} 19}
17 20
18// --------------------------------------------------------------------------- 21// ---------------------------------------------------------------------------
19 22
20export { 23export {
24 refreshActor,
21 refreshAPObject 25 refreshAPObject
22} 26}
23 27
24// --------------------------------------------------------------------------- 28// ---------------------------------------------------------------------------
25 29
26async function refreshAPVideo (videoUrl: string) { 30async function refreshVideo (videoUrl: string) {
27 const fetchType = 'all' as 'all' 31 const fetchType = 'all' as 'all'
28 const syncParam = { likes: true, dislikes: true, shares: true, comments: true, thumbnail: true } 32 const syncParam = { likes: true, dislikes: true, shares: true, comments: true, thumbnail: true }
29 33
@@ -38,3 +42,13 @@ async function refreshAPVideo (videoUrl: string) {
38 await refreshVideoIfNeeded(refreshOptions) 42 await refreshVideoIfNeeded(refreshOptions)
39 } 43 }
40} 44}
45
46async function refreshActor (actorUrl: string) {
47 const fetchType = 'all' as 'all'
48 const actor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(actorUrl)
49
50 if (actor) {
51 await refreshActorIfNeeded(actor, fetchType)
52 }
53
54}
diff --git a/server/lib/job-queue/handlers/email.ts b/server/lib/job-queue/handlers/email.ts
index 73d98ae54..220d0af32 100644
--- a/server/lib/job-queue/handlers/email.ts
+++ b/server/lib/job-queue/handlers/email.ts
@@ -6,13 +6,14 @@ export type EmailPayload = {
6 to: string[] 6 to: string[]
7 subject: string 7 subject: string
8 text: string 8 text: string
9 from?: string
9} 10}
10 11
11async function processEmail (job: Bull.Job) { 12async function processEmail (job: Bull.Job) {
12 const payload = job.data as EmailPayload 13 const payload = job.data as EmailPayload
13 logger.info('Processing email in job %d.', job.id) 14 logger.info('Processing email in job %d.', job.id)
14 15
15 return Emailer.Instance.sendMail(payload.to, payload.subject, payload.text) 16 return Emailer.Instance.sendMail(payload.to, payload.subject, payload.text, payload.from)
16} 17}
17 18
18// --------------------------------------------------------------------------- 19// ---------------------------------------------------------------------------
diff --git a/server/lib/job-queue/handlers/video-file.ts b/server/lib/job-queue/handlers/video-file.ts
index adc0a2a15..593e43cc5 100644
--- a/server/lib/job-queue/handlers/video-file.ts
+++ b/server/lib/job-queue/handlers/video-file.ts
@@ -8,7 +8,8 @@ import { retryTransactionWrapper } from '../../../helpers/database-utils'
8import { sequelizeTypescript } from '../../../initializers' 8import { sequelizeTypescript } from '../../../initializers'
9import * as Bluebird from 'bluebird' 9import * as Bluebird from 'bluebird'
10import { computeResolutionsToTranscode } from '../../../helpers/ffmpeg-utils' 10import { computeResolutionsToTranscode } from '../../../helpers/ffmpeg-utils'
11import { importVideoFile, transcodeOriginalVideofile, optimizeVideofile } from '../../video-transcoding' 11import { importVideoFile, optimizeVideofile, transcodeOriginalVideofile } from '../../video-transcoding'
12import { Notifier } from '../../notifier'
12 13
13export type VideoFilePayload = { 14export type VideoFilePayload = {
14 videoUUID: string 15 videoUUID: string
@@ -67,17 +68,17 @@ async function processVideoFile (job: Bull.Job) {
67async function onVideoFileTranscoderOrImportSuccess (video: VideoModel) { 68async function onVideoFileTranscoderOrImportSuccess (video: VideoModel) {
68 if (video === undefined) return undefined 69 if (video === undefined) return undefined
69 70
70 return sequelizeTypescript.transaction(async t => { 71 const { videoDatabase, videoPublished } = await sequelizeTypescript.transaction(async t => {
71 // Maybe the video changed in database, refresh it 72 // Maybe the video changed in database, refresh it
72 let videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t) 73 let videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
73 // Video does not exist anymore 74 // Video does not exist anymore
74 if (!videoDatabase) return undefined 75 if (!videoDatabase) return undefined
75 76
76 let isNewVideo = false 77 let videoPublished = false
77 78
78 // We transcoded the video file in another format, now we can publish it 79 // We transcoded the video file in another format, now we can publish it
79 if (videoDatabase.state !== VideoState.PUBLISHED) { 80 if (videoDatabase.state !== VideoState.PUBLISHED) {
80 isNewVideo = true 81 videoPublished = true
81 82
82 videoDatabase.state = VideoState.PUBLISHED 83 videoDatabase.state = VideoState.PUBLISHED
83 videoDatabase.publishedAt = new Date() 84 videoDatabase.publishedAt = new Date()
@@ -85,21 +86,26 @@ async function onVideoFileTranscoderOrImportSuccess (video: VideoModel) {
85 } 86 }
86 87
87 // If the video was not published, we consider it is a new one for other instances 88 // If the video was not published, we consider it is a new one for other instances
88 await federateVideoIfNeeded(videoDatabase, isNewVideo, t) 89 await federateVideoIfNeeded(videoDatabase, videoPublished, t)
89 90
90 return undefined 91 return { videoDatabase, videoPublished }
91 }) 92 })
93
94 if (videoPublished) {
95 Notifier.Instance.notifyOnNewVideo(videoDatabase)
96 Notifier.Instance.notifyOnPendingVideoPublished(videoDatabase)
97 }
92} 98}
93 99
94async function onVideoFileOptimizerSuccess (video: VideoModel, isNewVideo: boolean) { 100async function onVideoFileOptimizerSuccess (videoArg: VideoModel, isNewVideo: boolean) {
95 if (video === undefined) return undefined 101 if (videoArg === undefined) return undefined
96 102
97 // Outside the transaction (IO on disk) 103 // Outside the transaction (IO on disk)
98 const { videoFileResolution } = await video.getOriginalFileResolution() 104 const { videoFileResolution } = await videoArg.getOriginalFileResolution()
99 105
100 return sequelizeTypescript.transaction(async t => { 106 const { videoDatabase, videoPublished } = await sequelizeTypescript.transaction(async t => {
101 // Maybe the video changed in database, refresh it 107 // Maybe the video changed in database, refresh it
102 const videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t) 108 let videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoArg.uuid, t)
103 // Video does not exist anymore 109 // Video does not exist anymore
104 if (!videoDatabase) return undefined 110 if (!videoDatabase) return undefined
105 111
@@ -110,8 +116,10 @@ async function onVideoFileOptimizerSuccess (video: VideoModel, isNewVideo: boole
110 { resolutions: resolutionsEnabled } 116 { resolutions: resolutionsEnabled }
111 ) 117 )
112 118
119 let videoPublished = false
120
113 if (resolutionsEnabled.length !== 0) { 121 if (resolutionsEnabled.length !== 0) {
114 const tasks: Bluebird<any>[] = [] 122 const tasks: Bluebird<Bull.Job<any>>[] = []
115 123
116 for (const resolution of resolutionsEnabled) { 124 for (const resolution of resolutionsEnabled) {
117 const dataInput = { 125 const dataInput = {
@@ -127,15 +135,22 @@ async function onVideoFileOptimizerSuccess (video: VideoModel, isNewVideo: boole
127 135
128 logger.info('Transcoding jobs created for uuid %s.', videoDatabase.uuid, { resolutionsEnabled }) 136 logger.info('Transcoding jobs created for uuid %s.', videoDatabase.uuid, { resolutionsEnabled })
129 } else { 137 } else {
138 videoPublished = true
139
130 // No transcoding to do, it's now published 140 // No transcoding to do, it's now published
131 video.state = VideoState.PUBLISHED 141 videoDatabase.state = VideoState.PUBLISHED
132 video = await video.save({ transaction: t }) 142 videoDatabase = await videoDatabase.save({ transaction: t })
133 143
134 logger.info('No transcoding jobs created for video %s (no resolutions).', video.uuid) 144 logger.info('No transcoding jobs created for video %s (no resolutions).', videoDatabase.uuid, { privacy: videoDatabase.privacy })
135 } 145 }
136 146
137 return federateVideoIfNeeded(video, isNewVideo, t) 147 await federateVideoIfNeeded(videoDatabase, isNewVideo, t)
148
149 return { videoDatabase, videoPublished }
138 }) 150 })
151
152 if (isNewVideo) Notifier.Instance.notifyOnNewVideo(videoDatabase)
153 if (videoPublished) Notifier.Instance.notifyOnPendingVideoPublished(videoDatabase)
139} 154}
140 155
141// --------------------------------------------------------------------------- 156// ---------------------------------------------------------------------------
diff --git a/server/lib/job-queue/handlers/video-import.ts b/server/lib/job-queue/handlers/video-import.ts
index 4de901c0c..12004dcd7 100644
--- a/server/lib/job-queue/handlers/video-import.ts
+++ b/server/lib/job-queue/handlers/video-import.ts
@@ -7,14 +7,15 @@ import { getDurationFromVideoFile, getVideoFileFPS, getVideoFileResolution } fro
7import { extname, join } from 'path' 7import { extname, join } from 'path'
8import { VideoFileModel } from '../../../models/video/video-file' 8import { VideoFileModel } from '../../../models/video/video-file'
9import { CONFIG, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE, VIDEO_IMPORT_TIMEOUT } from '../../../initializers' 9import { CONFIG, PREVIEWS_SIZE, sequelizeTypescript, THUMBNAILS_SIZE, VIDEO_IMPORT_TIMEOUT } from '../../../initializers'
10import { doRequestAndSaveToFile, downloadImage } from '../../../helpers/requests' 10import { downloadImage } from '../../../helpers/requests'
11import { VideoState } from '../../../../shared' 11import { VideoState } from '../../../../shared'
12import { JobQueue } from '../index' 12import { JobQueue } from '../index'
13import { federateVideoIfNeeded } from '../../activitypub' 13import { federateVideoIfNeeded } from '../../activitypub'
14import { VideoModel } from '../../../models/video/video' 14import { VideoModel } from '../../../models/video/video'
15import { downloadWebTorrentVideo } from '../../../helpers/webtorrent' 15import { downloadWebTorrentVideo } from '../../../helpers/webtorrent'
16import { getSecureTorrentName } from '../../../helpers/utils' 16import { getSecureTorrentName } from '../../../helpers/utils'
17import { remove, rename, stat } from 'fs-extra' 17import { remove, move, stat } from 'fs-extra'
18import { Notifier } from '../../notifier'
18 19
19type VideoImportYoutubeDLPayload = { 20type VideoImportYoutubeDLPayload = {
20 type: 'youtube-dl' 21 type: 'youtube-dl'
@@ -109,6 +110,7 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide
109 let tempVideoPath: string 110 let tempVideoPath: string
110 let videoDestFile: string 111 let videoDestFile: string
111 let videoFile: VideoFileModel 112 let videoFile: VideoFileModel
113
112 try { 114 try {
113 // Download video from youtubeDL 115 // Download video from youtubeDL
114 tempVideoPath = await downloader() 116 tempVideoPath = await downloader()
@@ -138,14 +140,13 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide
138 140
139 // Move file 141 // Move file
140 videoDestFile = join(CONFIG.STORAGE.VIDEOS_DIR, videoImport.Video.getVideoFilename(videoFile)) 142 videoDestFile = join(CONFIG.STORAGE.VIDEOS_DIR, videoImport.Video.getVideoFilename(videoFile))
141 await rename(tempVideoPath, videoDestFile) 143 await move(tempVideoPath, videoDestFile)
142 tempVideoPath = null // This path is not used anymore 144 tempVideoPath = null // This path is not used anymore
143 145
144 // Process thumbnail 146 // Process thumbnail
145 if (options.downloadThumbnail) { 147 if (options.downloadThumbnail) {
146 if (options.thumbnailUrl) { 148 if (options.thumbnailUrl) {
147 const destThumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, videoImport.Video.getThumbnailName()) 149 await downloadImage(options.thumbnailUrl, CONFIG.STORAGE.THUMBNAILS_DIR, videoImport.Video.getThumbnailName(), THUMBNAILS_SIZE)
148 await downloadImage(options.thumbnailUrl, destThumbnailPath, THUMBNAILS_SIZE)
149 } else { 150 } else {
150 await videoImport.Video.createThumbnail(videoFile) 151 await videoImport.Video.createThumbnail(videoFile)
151 } 152 }
@@ -156,8 +157,7 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide
156 // Process preview 157 // Process preview
157 if (options.downloadPreview) { 158 if (options.downloadPreview) {
158 if (options.thumbnailUrl) { 159 if (options.thumbnailUrl) {
159 const destPreviewPath = join(CONFIG.STORAGE.PREVIEWS_DIR, videoImport.Video.getPreviewName()) 160 await downloadImage(options.thumbnailUrl, CONFIG.STORAGE.PREVIEWS_DIR, videoImport.Video.getPreviewName(), PREVIEWS_SIZE)
160 await downloadImage(options.thumbnailUrl, destPreviewPath, PREVIEWS_SIZE)
161 } else { 161 } else {
162 await videoImport.Video.createPreview(videoFile) 162 await videoImport.Video.createPreview(videoFile)
163 } 163 }
@@ -180,7 +180,7 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide
180 // Update video DB object 180 // Update video DB object
181 video.duration = duration 181 video.duration = duration
182 video.state = CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED 182 video.state = CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED
183 const videoUpdated = await video.save({ transaction: t }) 183 await video.save({ transaction: t })
184 184
185 // Now we can federate the video (reload from database, we need more attributes) 185 // Now we can federate the video (reload from database, we need more attributes)
186 const videoForFederation = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t) 186 const videoForFederation = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
@@ -192,10 +192,13 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide
192 192
193 logger.info('Video %s imported.', video.uuid) 193 logger.info('Video %s imported.', video.uuid)
194 194
195 videoImportUpdated.Video = videoUpdated 195 videoImportUpdated.Video = videoForFederation
196 return videoImportUpdated 196 return videoImportUpdated
197 }) 197 })
198 198
199 Notifier.Instance.notifyOnNewVideo(videoImportUpdated.Video)
200 Notifier.Instance.notifyOnFinishedVideoImport(videoImportUpdated, true)
201
199 // Create transcoding jobs? 202 // Create transcoding jobs?
200 if (videoImportUpdated.Video.state === VideoState.TO_TRANSCODE) { 203 if (videoImportUpdated.Video.state === VideoState.TO_TRANSCODE) {
201 // Put uuid because we don't have id auto incremented for now 204 // Put uuid because we don't have id auto incremented for now
@@ -218,6 +221,8 @@ async function processFile (downloader: () => Promise<string>, videoImport: Vide
218 videoImport.state = VideoImportState.FAILED 221 videoImport.state = VideoImportState.FAILED
219 await videoImport.save() 222 await videoImport.save()
220 223
224 Notifier.Instance.notifyOnFinishedVideoImport(videoImport, false)
225
221 throw err 226 throw err
222 } 227 }
223} 228}
diff --git a/server/lib/job-queue/handlers/video-views.ts b/server/lib/job-queue/handlers/video-views.ts
index 038ef43e2..fa1fd13b3 100644
--- a/server/lib/job-queue/handlers/video-views.ts
+++ b/server/lib/job-queue/handlers/video-views.ts
@@ -23,9 +23,7 @@ async function processVideosViews () {
23 for (const videoId of videoIds) { 23 for (const videoId of videoIds) {
24 try { 24 try {
25 const views = await Redis.Instance.getVideoViews(videoId, hour) 25 const views = await Redis.Instance.getVideoViews(videoId, hour)
26 if (isNaN(views)) { 26 if (views) {
27 logger.error('Cannot process videos views of video %d in hour %d: views number is NaN (%s).', videoId, hour, views)
28 } else {
29 logger.debug('Adding %d views to video %d in hour %d.', views, videoId, hour) 27 logger.debug('Adding %d views to video %d in hour %d.', views, videoId, hour)
30 28
31 try { 29 try {
diff --git a/server/lib/job-queue/job-queue.ts b/server/lib/job-queue/job-queue.ts
index 5862e178f..ba9cbe0d9 100644
--- a/server/lib/job-queue/job-queue.ts
+++ b/server/lib/job-queue/job-queue.ts
@@ -88,7 +88,6 @@ class JobQueue {
88 88
89 queue.on('error', err => { 89 queue.on('error', err => {
90 logger.error('Error in job queue %s.', handlerName, { err }) 90 logger.error('Error in job queue %s.', handlerName, { err })
91 process.exit(-1)
92 }) 91 })
93 92
94 this.queues[handlerName] = queue 93 this.queues[handlerName] = queue
@@ -166,10 +165,10 @@ class JobQueue {
166 return total 165 return total
167 } 166 }
168 167
169 removeOldJobs () { 168 async removeOldJobs () {
170 for (const key of Object.keys(this.queues)) { 169 for (const key of Object.keys(this.queues)) {
171 const queue = this.queues[key] 170 const queue = this.queues[key]
172 queue.clean(JOB_COMPLETED_LIFETIME, 'completed') 171 await queue.clean(JOB_COMPLETED_LIFETIME, 'completed')
173 } 172 }
174 } 173 }
175 174
diff --git a/server/lib/notifier.ts b/server/lib/notifier.ts
new file mode 100644
index 000000000..d1b331346
--- /dev/null
+++ b/server/lib/notifier.ts
@@ -0,0 +1,455 @@
1import { UserNotificationSettingValue, UserNotificationType, UserRight } from '../../shared/models/users'
2import { logger } from '../helpers/logger'
3import { VideoModel } from '../models/video/video'
4import { Emailer } from './emailer'
5import { UserNotificationModel } from '../models/account/user-notification'
6import { VideoCommentModel } from '../models/video/video-comment'
7import { UserModel } from '../models/account/user'
8import { PeerTubeSocket } from './peertube-socket'
9import { CONFIG } from '../initializers/constants'
10import { VideoPrivacy, VideoState } from '../../shared/models/videos'
11import { VideoAbuseModel } from '../models/video/video-abuse'
12import { VideoBlacklistModel } from '../models/video/video-blacklist'
13import * as Bluebird from 'bluebird'
14import { VideoImportModel } from '../models/video/video-import'
15import { AccountBlocklistModel } from '../models/account/account-blocklist'
16import { ActorFollowModel } from '../models/activitypub/actor-follow'
17import { AccountModel } from '../models/account/account'
18
19class Notifier {
20
21 private static instance: Notifier
22
23 private constructor () {}
24
25 notifyOnNewVideo (video: VideoModel): void {
26 // Only notify on public and published videos
27 if (video.privacy !== VideoPrivacy.PUBLIC || video.state !== VideoState.PUBLISHED) return
28
29 this.notifySubscribersOfNewVideo(video)
30 .catch(err => logger.error('Cannot notify subscribers of new video %s.', video.url, { err }))
31 }
32
33 notifyOnPendingVideoPublished (video: VideoModel): void {
34 // Only notify on public videos that has been published while the user waited transcoding/scheduled update
35 if (video.waitTranscoding === false && !video.ScheduleVideoUpdate) return
36
37 this.notifyOwnedVideoHasBeenPublished(video)
38 .catch(err => logger.error('Cannot notify owner that its video %s has been published.', video.url, { err }))
39 }
40
41 notifyOnNewComment (comment: VideoCommentModel): void {
42 this.notifyVideoOwnerOfNewComment(comment)
43 .catch(err => logger.error('Cannot notify video owner of new comment %s.', comment.url, { err }))
44
45 this.notifyOfCommentMention(comment)
46 .catch(err => logger.error('Cannot notify mentions of comment %s.', comment.url, { err }))
47 }
48
49 notifyOnNewVideoAbuse (videoAbuse: VideoAbuseModel): void {
50 this.notifyModeratorsOfNewVideoAbuse(videoAbuse)
51 .catch(err => logger.error('Cannot notify of new video abuse of video %s.', videoAbuse.Video.url, { err }))
52 }
53
54 notifyOnVideoBlacklist (videoBlacklist: VideoBlacklistModel): void {
55 this.notifyVideoOwnerOfBlacklist(videoBlacklist)
56 .catch(err => logger.error('Cannot notify video owner of new video blacklist of %s.', videoBlacklist.Video.url, { err }))
57 }
58
59 notifyOnVideoUnblacklist (video: VideoModel): void {
60 this.notifyVideoOwnerOfUnblacklist(video)
61 .catch(err => logger.error('Cannot notify video owner of new video blacklist of %s.', video.url, { err }))
62 }
63
64 notifyOnFinishedVideoImport (videoImport: VideoImportModel, success: boolean): void {
65 this.notifyOwnerVideoImportIsFinished(videoImport, success)
66 .catch(err => logger.error('Cannot notify owner that its video import %s is finished.', videoImport.getTargetIdentifier(), { err }))
67 }
68
69 notifyOnNewUserRegistration (user: UserModel): void {
70 this.notifyModeratorsOfNewUserRegistration(user)
71 .catch(err => logger.error('Cannot notify moderators of new user registration (%s).', user.username, { err }))
72 }
73
74 notifyOfNewFollow (actorFollow: ActorFollowModel): void {
75 this.notifyUserOfNewActorFollow(actorFollow)
76 .catch(err => {
77 logger.error(
78 'Cannot notify owner of channel %s of a new follow by %s.',
79 actorFollow.ActorFollowing.VideoChannel.getDisplayName(),
80 actorFollow.ActorFollower.Account.getDisplayName(),
81 err
82 )
83 })
84 }
85
86 private async notifySubscribersOfNewVideo (video: VideoModel) {
87 // List all followers that are users
88 const users = await UserModel.listUserSubscribersOf(video.VideoChannel.actorId)
89
90 logger.info('Notifying %d users of new video %s.', users.length, video.url)
91
92 function settingGetter (user: UserModel) {
93 return user.NotificationSetting.newVideoFromSubscription
94 }
95
96 async function notificationCreator (user: UserModel) {
97 const notification = await UserNotificationModel.create({
98 type: UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION,
99 userId: user.id,
100 videoId: video.id
101 })
102 notification.Video = video
103
104 return notification
105 }
106
107 function emailSender (emails: string[]) {
108 return Emailer.Instance.addNewVideoFromSubscriberNotification(emails, video)
109 }
110
111 return this.notify({ users, settingGetter, notificationCreator, emailSender })
112 }
113
114 private async notifyVideoOwnerOfNewComment (comment: VideoCommentModel) {
115 if (comment.Video.isOwned() === false) return
116
117 const user = await UserModel.loadByVideoId(comment.videoId)
118
119 // Not our user or user comments its own video
120 if (!user || comment.Account.userId === user.id) return
121
122 const accountMuted = await AccountBlocklistModel.isAccountMutedBy(user.Account.id, comment.accountId)
123 if (accountMuted) return
124
125 logger.info('Notifying user %s of new comment %s.', user.username, comment.url)
126
127 function settingGetter (user: UserModel) {
128 return user.NotificationSetting.newCommentOnMyVideo
129 }
130
131 async function notificationCreator (user: UserModel) {
132 const notification = await UserNotificationModel.create({
133 type: UserNotificationType.NEW_COMMENT_ON_MY_VIDEO,
134 userId: user.id,
135 commentId: comment.id
136 })
137 notification.Comment = comment
138
139 return notification
140 }
141
142 function emailSender (emails: string[]) {
143 return Emailer.Instance.addNewCommentOnMyVideoNotification(emails, comment)
144 }
145
146 return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender })
147 }
148
149 private async notifyOfCommentMention (comment: VideoCommentModel) {
150 const usernames = comment.extractMentions()
151 let users = await UserModel.listByUsernames(usernames)
152
153 if (comment.Video.isOwned()) {
154 const userException = await UserModel.loadByVideoId(comment.videoId)
155 users = users.filter(u => u.id !== userException.id)
156 }
157
158 // Don't notify if I mentioned myself
159 users = users.filter(u => u.Account.id !== comment.accountId)
160
161 if (users.length === 0) return
162
163 const accountMutedHash = await AccountBlocklistModel.isAccountMutedByMulti(users.map(u => u.Account.id), comment.accountId)
164
165 logger.info('Notifying %d users of new comment %s.', users.length, comment.url)
166
167 function settingGetter (user: UserModel) {
168 if (accountMutedHash[user.Account.id] === true) return UserNotificationSettingValue.NONE
169
170 return user.NotificationSetting.commentMention
171 }
172
173 async function notificationCreator (user: UserModel) {
174 const notification = await UserNotificationModel.create({
175 type: UserNotificationType.COMMENT_MENTION,
176 userId: user.id,
177 commentId: comment.id
178 })
179 notification.Comment = comment
180
181 return notification
182 }
183
184 function emailSender (emails: string[]) {
185 return Emailer.Instance.addNewCommentMentionNotification(emails, comment)
186 }
187
188 return this.notify({ users, settingGetter, notificationCreator, emailSender })
189 }
190
191 private async notifyUserOfNewActorFollow (actorFollow: ActorFollowModel) {
192 if (actorFollow.ActorFollowing.isOwned() === false) return
193
194 // Account follows one of our account?
195 let followType: 'account' | 'channel' = 'channel'
196 let user = await UserModel.loadByChannelActorId(actorFollow.ActorFollowing.id)
197
198 // Account follows one of our channel?
199 if (!user) {
200 user = await UserModel.loadByAccountActorId(actorFollow.ActorFollowing.id)
201 followType = 'account'
202 }
203
204 if (!user) return
205
206 if (!actorFollow.ActorFollower.Account || !actorFollow.ActorFollower.Account.name) {
207 actorFollow.ActorFollower.Account = await actorFollow.ActorFollower.$get('Account') as AccountModel
208 }
209 const followerAccount = actorFollow.ActorFollower.Account
210
211 const accountMuted = await AccountBlocklistModel.isAccountMutedBy(user.Account.id, followerAccount.id)
212 if (accountMuted) return
213
214 logger.info('Notifying user %s of new follower: %s.', user.username, followerAccount.getDisplayName())
215
216 function settingGetter (user: UserModel) {
217 return user.NotificationSetting.newFollow
218 }
219
220 async function notificationCreator (user: UserModel) {
221 const notification = await UserNotificationModel.create({
222 type: UserNotificationType.NEW_FOLLOW,
223 userId: user.id,
224 actorFollowId: actorFollow.id
225 })
226 notification.ActorFollow = actorFollow
227
228 return notification
229 }
230
231 function emailSender (emails: string[]) {
232 return Emailer.Instance.addNewFollowNotification(emails, actorFollow, followType)
233 }
234
235 return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender })
236 }
237
238 private async notifyModeratorsOfNewVideoAbuse (videoAbuse: VideoAbuseModel) {
239 const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_ABUSES)
240 if (moderators.length === 0) return
241
242 logger.info('Notifying %s user/moderators of new video abuse %s.', moderators.length, videoAbuse.Video.url)
243
244 function settingGetter (user: UserModel) {
245 return user.NotificationSetting.videoAbuseAsModerator
246 }
247
248 async function notificationCreator (user: UserModel) {
249 const notification = await UserNotificationModel.create({
250 type: UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS,
251 userId: user.id,
252 videoAbuseId: videoAbuse.id
253 })
254 notification.VideoAbuse = videoAbuse
255
256 return notification
257 }
258
259 function emailSender (emails: string[]) {
260 return Emailer.Instance.addVideoAbuseModeratorsNotification(emails, videoAbuse)
261 }
262
263 return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender })
264 }
265
266 private async notifyVideoOwnerOfBlacklist (videoBlacklist: VideoBlacklistModel) {
267 const user = await UserModel.loadByVideoId(videoBlacklist.videoId)
268 if (!user) return
269
270 logger.info('Notifying user %s that its video %s has been blacklisted.', user.username, videoBlacklist.Video.url)
271
272 function settingGetter (user: UserModel) {
273 return user.NotificationSetting.blacklistOnMyVideo
274 }
275
276 async function notificationCreator (user: UserModel) {
277 const notification = await UserNotificationModel.create({
278 type: UserNotificationType.BLACKLIST_ON_MY_VIDEO,
279 userId: user.id,
280 videoBlacklistId: videoBlacklist.id
281 })
282 notification.VideoBlacklist = videoBlacklist
283
284 return notification
285 }
286
287 function emailSender (emails: string[]) {
288 return Emailer.Instance.addVideoBlacklistNotification(emails, videoBlacklist)
289 }
290
291 return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender })
292 }
293
294 private async notifyVideoOwnerOfUnblacklist (video: VideoModel) {
295 const user = await UserModel.loadByVideoId(video.id)
296 if (!user) return
297
298 logger.info('Notifying user %s that its video %s has been unblacklisted.', user.username, video.url)
299
300 function settingGetter (user: UserModel) {
301 return user.NotificationSetting.blacklistOnMyVideo
302 }
303
304 async function notificationCreator (user: UserModel) {
305 const notification = await UserNotificationModel.create({
306 type: UserNotificationType.UNBLACKLIST_ON_MY_VIDEO,
307 userId: user.id,
308 videoId: video.id
309 })
310 notification.Video = video
311
312 return notification
313 }
314
315 function emailSender (emails: string[]) {
316 return Emailer.Instance.addVideoUnblacklistNotification(emails, video)
317 }
318
319 return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender })
320 }
321
322 private async notifyOwnedVideoHasBeenPublished (video: VideoModel) {
323 const user = await UserModel.loadByVideoId(video.id)
324 if (!user) return
325
326 logger.info('Notifying user %s of the publication of its video %s.', user.username, video.url)
327
328 function settingGetter (user: UserModel) {
329 return user.NotificationSetting.myVideoPublished
330 }
331
332 async function notificationCreator (user: UserModel) {
333 const notification = await UserNotificationModel.create({
334 type: UserNotificationType.MY_VIDEO_PUBLISHED,
335 userId: user.id,
336 videoId: video.id
337 })
338 notification.Video = video
339
340 return notification
341 }
342
343 function emailSender (emails: string[]) {
344 return Emailer.Instance.myVideoPublishedNotification(emails, video)
345 }
346
347 return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender })
348 }
349
350 private async notifyOwnerVideoImportIsFinished (videoImport: VideoImportModel, success: boolean) {
351 const user = await UserModel.loadByVideoImportId(videoImport.id)
352 if (!user) return
353
354 logger.info('Notifying user %s its video import %s is finished.', user.username, videoImport.getTargetIdentifier())
355
356 function settingGetter (user: UserModel) {
357 return user.NotificationSetting.myVideoImportFinished
358 }
359
360 async function notificationCreator (user: UserModel) {
361 const notification = await UserNotificationModel.create({
362 type: success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR,
363 userId: user.id,
364 videoImportId: videoImport.id
365 })
366 notification.VideoImport = videoImport
367
368 return notification
369 }
370
371 function emailSender (emails: string[]) {
372 return success
373 ? Emailer.Instance.myVideoImportSuccessNotification(emails, videoImport)
374 : Emailer.Instance.myVideoImportErrorNotification(emails, videoImport)
375 }
376
377 return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender })
378 }
379
380 private async notifyModeratorsOfNewUserRegistration (registeredUser: UserModel) {
381 const moderators = await UserModel.listWithRight(UserRight.MANAGE_USERS)
382 if (moderators.length === 0) return
383
384 logger.info(
385 'Notifying %s moderators of new user registration of %s.',
386 moderators.length, registeredUser.Account.Actor.preferredUsername
387 )
388
389 function settingGetter (user: UserModel) {
390 return user.NotificationSetting.newUserRegistration
391 }
392
393 async function notificationCreator (user: UserModel) {
394 const notification = await UserNotificationModel.create({
395 type: UserNotificationType.NEW_USER_REGISTRATION,
396 userId: user.id,
397 accountId: registeredUser.Account.id
398 })
399 notification.Account = registeredUser.Account
400
401 return notification
402 }
403
404 function emailSender (emails: string[]) {
405 return Emailer.Instance.addNewUserRegistrationNotification(emails, registeredUser)
406 }
407
408 return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender })
409 }
410
411 private async notify (options: {
412 users: UserModel[],
413 notificationCreator: (user: UserModel) => Promise<UserNotificationModel>,
414 emailSender: (emails: string[]) => Promise<any> | Bluebird<any>,
415 settingGetter: (user: UserModel) => UserNotificationSettingValue
416 }) {
417 const emails: string[] = []
418
419 for (const user of options.users) {
420 if (this.isWebNotificationEnabled(options.settingGetter(user))) {
421 const notification = await options.notificationCreator(user)
422
423 PeerTubeSocket.Instance.sendNotification(user.id, notification)
424 }
425
426 if (this.isEmailEnabled(user, options.settingGetter(user))) {
427 emails.push(user.email)
428 }
429 }
430
431 if (emails.length !== 0) {
432 await options.emailSender(emails)
433 }
434 }
435
436 private isEmailEnabled (user: UserModel, value: UserNotificationSettingValue) {
437 if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION === true && user.emailVerified !== true) return false
438
439 return value & UserNotificationSettingValue.EMAIL
440 }
441
442 private isWebNotificationEnabled (value: UserNotificationSettingValue) {
443 return value & UserNotificationSettingValue.WEB
444 }
445
446 static get Instance () {
447 return this.instance || (this.instance = new this())
448 }
449}
450
451// ---------------------------------------------------------------------------
452
453export {
454 Notifier
455}
diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts
index 5cbe60b82..2cd2ae97c 100644
--- a/server/lib/oauth-model.ts
+++ b/server/lib/oauth-model.ts
@@ -1,3 +1,4 @@
1import * as Bluebird from 'bluebird'
1import { AccessDeniedError } from 'oauth2-server' 2import { AccessDeniedError } from 'oauth2-server'
2import { logger } from '../helpers/logger' 3import { logger } from '../helpers/logger'
3import { UserModel } from '../models/account/user' 4import { UserModel } from '../models/account/user'
@@ -37,7 +38,7 @@ function clearCacheByToken (token: string) {
37function getAccessToken (bearerToken: string) { 38function getAccessToken (bearerToken: string) {
38 logger.debug('Getting access token (bearerToken: ' + bearerToken + ').') 39 logger.debug('Getting access token (bearerToken: ' + bearerToken + ').')
39 40
40 if (accessTokenCache[bearerToken] !== undefined) return accessTokenCache[bearerToken] 41 if (accessTokenCache[bearerToken] !== undefined) return Bluebird.resolve(accessTokenCache[bearerToken])
41 42
42 return OAuthTokenModel.getByTokenAndPopulateUser(bearerToken) 43 return OAuthTokenModel.getByTokenAndPopulateUser(bearerToken)
43 .then(tokenModel => { 44 .then(tokenModel => {
diff --git a/server/lib/peertube-socket.ts b/server/lib/peertube-socket.ts
new file mode 100644
index 000000000..eb84ecd4b
--- /dev/null
+++ b/server/lib/peertube-socket.ts
@@ -0,0 +1,52 @@
1import * as SocketIO from 'socket.io'
2import { authenticateSocket } from '../middlewares'
3import { UserNotificationModel } from '../models/account/user-notification'
4import { logger } from '../helpers/logger'
5import { Server } from 'http'
6
7class PeerTubeSocket {
8
9 private static instance: PeerTubeSocket
10
11 private userNotificationSockets: { [ userId: number ]: SocketIO.Socket } = {}
12
13 private constructor () {}
14
15 init (server: Server) {
16 const io = SocketIO(server)
17
18 io.of('/user-notifications')
19 .use(authenticateSocket)
20 .on('connection', socket => {
21 const userId = socket.handshake.query.user.id
22
23 logger.debug('User %d connected on the notification system.', userId)
24
25 this.userNotificationSockets[userId] = socket
26
27 socket.on('disconnect', () => {
28 logger.debug('User %d disconnected from SocketIO notifications.', userId)
29
30 delete this.userNotificationSockets[userId]
31 })
32 })
33 }
34
35 sendNotification (userId: number, notification: UserNotificationModel) {
36 const socket = this.userNotificationSockets[userId]
37
38 if (!socket) return
39
40 socket.emit('new-notification', notification.toFormattedJSON())
41 }
42
43 static get Instance () {
44 return this.instance || (this.instance = new this())
45 }
46}
47
48// ---------------------------------------------------------------------------
49
50export {
51 PeerTubeSocket
52}
diff --git a/server/lib/redis.ts b/server/lib/redis.ts
index abd75d512..3628c0583 100644
--- a/server/lib/redis.ts
+++ b/server/lib/redis.ts
@@ -2,7 +2,13 @@ import * as express from 'express'
2import { createClient, RedisClient } from 'redis' 2import { createClient, RedisClient } from 'redis'
3import { logger } from '../helpers/logger' 3import { logger } from '../helpers/logger'
4import { generateRandomString } from '../helpers/utils' 4import { generateRandomString } from '../helpers/utils'
5import { CONFIG, USER_PASSWORD_RESET_LIFETIME, USER_EMAIL_VERIFY_LIFETIME, VIDEO_VIEW_LIFETIME } from '../initializers' 5import {
6 CONFIG,
7 CONTACT_FORM_LIFETIME,
8 USER_EMAIL_VERIFY_LIFETIME,
9 USER_PASSWORD_RESET_LIFETIME,
10 VIDEO_VIEW_LIFETIME
11} from '../initializers'
6 12
7type CachedRoute = { 13type CachedRoute = {
8 body: string, 14 body: string,
@@ -76,6 +82,16 @@ class Redis {
76 return this.getValue(this.generateVerifyEmailKey(userId)) 82 return this.getValue(this.generateVerifyEmailKey(userId))
77 } 83 }
78 84
85 /************* Contact form per IP *************/
86
87 async setContactFormIp (ip: string) {
88 return this.setValue(this.generateContactFormKey(ip), '1', CONTACT_FORM_LIFETIME)
89 }
90
91 async isContactFormIpExists (ip: string) {
92 return this.exists(this.generateContactFormKey(ip))
93 }
94
79 /************* Views per IP *************/ 95 /************* Views per IP *************/
80 96
81 setIPVideoView (ip: string, videoUUID: string) { 97 setIPVideoView (ip: string, videoUUID: string) {
@@ -121,7 +137,14 @@ class Redis {
121 const key = this.generateVideoViewKey(videoId, hour) 137 const key = this.generateVideoViewKey(videoId, hour)
122 138
123 const valueString = await this.getValue(key) 139 const valueString = await this.getValue(key)
124 return parseInt(valueString, 10) 140 const valueInt = parseInt(valueString, 10)
141
142 if (isNaN(valueInt)) {
143 logger.error('Cannot get videos views of video %d in hour %d: views number is NaN (%s).', videoId, hour, valueString)
144 return undefined
145 }
146
147 return valueInt
125 } 148 }
126 149
127 async getVideosIdViewed (hour: number) { 150 async getVideosIdViewed (hour: number) {
@@ -168,7 +191,11 @@ class Redis {
168 } 191 }
169 192
170 private generateViewKey (ip: string, videoUUID: string) { 193 private generateViewKey (ip: string, videoUUID: string) {
171 return videoUUID + '-' + ip 194 return `views-${videoUUID}-${ip}`
195 }
196
197 private generateContactFormKey (ip: string) {
198 return 'contact-form-' + ip
172 } 199 }
173 200
174 /************* Redis helpers *************/ 201 /************* Redis helpers *************/
diff --git a/server/lib/schedulers/abstract-scheduler.ts b/server/lib/schedulers/abstract-scheduler.ts
index b9d0a4d17..86ea7aa38 100644
--- a/server/lib/schedulers/abstract-scheduler.ts
+++ b/server/lib/schedulers/abstract-scheduler.ts
@@ -1,8 +1,11 @@
1import { logger } from '../../helpers/logger'
2
1export abstract class AbstractScheduler { 3export abstract class AbstractScheduler {
2 4
3 protected abstract schedulerIntervalMs: number 5 protected abstract schedulerIntervalMs: number
4 6
5 private interval: NodeJS.Timer 7 private interval: NodeJS.Timer
8 private isRunning = false
6 9
7 enable () { 10 enable () {
8 if (!this.schedulerIntervalMs) throw new Error('Interval is not correctly set.') 11 if (!this.schedulerIntervalMs) throw new Error('Interval is not correctly set.')
@@ -14,5 +17,18 @@ export abstract class AbstractScheduler {
14 clearInterval(this.interval) 17 clearInterval(this.interval)
15 } 18 }
16 19
17 abstract execute () 20 async execute () {
21 if (this.isRunning === true) return
22 this.isRunning = true
23
24 try {
25 await this.internalExecute()
26 } catch (err) {
27 logger.error('Cannot execute %s scheduler.', this.constructor.name, { err })
28 } finally {
29 this.isRunning = false
30 }
31 }
32
33 protected abstract internalExecute (): Promise<any>
18} 34}
diff --git a/server/lib/schedulers/bad-actor-follow-scheduler.ts b/server/lib/schedulers/actor-follow-scheduler.ts
index 617149aaf..3967be7f8 100644
--- a/server/lib/schedulers/bad-actor-follow-scheduler.ts
+++ b/server/lib/schedulers/actor-follow-scheduler.ts
@@ -3,18 +3,35 @@ import { logger } from '../../helpers/logger'
3import { ActorFollowModel } from '../../models/activitypub/actor-follow' 3import { ActorFollowModel } from '../../models/activitypub/actor-follow'
4import { AbstractScheduler } from './abstract-scheduler' 4import { AbstractScheduler } from './abstract-scheduler'
5import { SCHEDULER_INTERVALS_MS } from '../../initializers' 5import { SCHEDULER_INTERVALS_MS } from '../../initializers'
6import { ActorFollowScoreCache } from '../cache'
6 7
7export class BadActorFollowScheduler extends AbstractScheduler { 8export class ActorFollowScheduler extends AbstractScheduler {
8 9
9 private static instance: AbstractScheduler 10 private static instance: AbstractScheduler
10 11
11 protected schedulerIntervalMs = SCHEDULER_INTERVALS_MS.badActorFollow 12 protected schedulerIntervalMs = SCHEDULER_INTERVALS_MS.actorFollowScores
12 13
13 private constructor () { 14 private constructor () {
14 super() 15 super()
15 } 16 }
16 17
17 async execute () { 18 protected async internalExecute () {
19 await this.processPendingScores()
20
21 await this.removeBadActorFollows()
22 }
23
24 private async processPendingScores () {
25 const pendingScores = ActorFollowScoreCache.Instance.getPendingFollowsScoreCopy()
26
27 ActorFollowScoreCache.Instance.clearPendingFollowsScore()
28
29 for (const inbox of Object.keys(pendingScores)) {
30 await ActorFollowModel.updateFollowScore(inbox, pendingScores[inbox])
31 }
32 }
33
34 private async removeBadActorFollows () {
18 if (!isTestInstance()) logger.info('Removing bad actor follows (scheduler).') 35 if (!isTestInstance()) logger.info('Removing bad actor follows (scheduler).')
19 36
20 try { 37 try {
diff --git a/server/lib/schedulers/remove-old-jobs-scheduler.ts b/server/lib/schedulers/remove-old-jobs-scheduler.ts
index a29a6b800..4a4341ba9 100644
--- a/server/lib/schedulers/remove-old-jobs-scheduler.ts
+++ b/server/lib/schedulers/remove-old-jobs-scheduler.ts
@@ -14,10 +14,10 @@ export class RemoveOldJobsScheduler extends AbstractScheduler {
14 super() 14 super()
15 } 15 }
16 16
17 async execute () { 17 protected internalExecute () {
18 if (!isTestInstance()) logger.info('Removing old jobs (scheduler).') 18 if (!isTestInstance()) logger.info('Removing old jobs in scheduler.')
19 19
20 JobQueue.Instance.removeOldJobs() 20 return JobQueue.Instance.removeOldJobs()
21 } 21 }
22 22
23 static get Instance () { 23 static get Instance () {
diff --git a/server/lib/schedulers/update-videos-scheduler.ts b/server/lib/schedulers/update-videos-scheduler.ts
index fd2edfd17..2618a5857 100644
--- a/server/lib/schedulers/update-videos-scheduler.ts
+++ b/server/lib/schedulers/update-videos-scheduler.ts
@@ -5,6 +5,8 @@ import { retryTransactionWrapper } from '../../helpers/database-utils'
5import { federateVideoIfNeeded } from '../activitypub' 5import { federateVideoIfNeeded } from '../activitypub'
6import { SCHEDULER_INTERVALS_MS, sequelizeTypescript } from '../../initializers' 6import { SCHEDULER_INTERVALS_MS, sequelizeTypescript } from '../../initializers'
7import { VideoPrivacy } from '../../../shared/models/videos' 7import { VideoPrivacy } from '../../../shared/models/videos'
8import { Notifier } from '../notifier'
9import { VideoModel } from '../../models/video/video'
8 10
9export class UpdateVideosScheduler extends AbstractScheduler { 11export class UpdateVideosScheduler extends AbstractScheduler {
10 12
@@ -12,30 +14,20 @@ export class UpdateVideosScheduler extends AbstractScheduler {
12 14
13 protected schedulerIntervalMs = SCHEDULER_INTERVALS_MS.updateVideos 15 protected schedulerIntervalMs = SCHEDULER_INTERVALS_MS.updateVideos
14 16
15 private isRunning = false
16
17 private constructor () { 17 private constructor () {
18 super() 18 super()
19 } 19 }
20 20
21 async execute () { 21 protected async internalExecute () {
22 if (this.isRunning === true) return 22 return retryTransactionWrapper(this.updateVideos.bind(this))
23 this.isRunning = true
24
25 try {
26 await retryTransactionWrapper(this.updateVideos.bind(this))
27 } catch (err) {
28 logger.error('Cannot execute update videos scheduler.', { err })
29 } finally {
30 this.isRunning = false
31 }
32 } 23 }
33 24
34 private async updateVideos () { 25 private async updateVideos () {
35 if (!await ScheduleVideoUpdateModel.areVideosToUpdate()) return undefined 26 if (!await ScheduleVideoUpdateModel.areVideosToUpdate()) return undefined
36 27
37 return sequelizeTypescript.transaction(async t => { 28 const publishedVideos = await sequelizeTypescript.transaction(async t => {
38 const schedules = await ScheduleVideoUpdateModel.listVideosToUpdate(t) 29 const schedules = await ScheduleVideoUpdateModel.listVideosToUpdate(t)
30 const publishedVideos: VideoModel[] = []
39 31
40 for (const schedule of schedules) { 32 for (const schedule of schedules) {
41 const video = schedule.Video 33 const video = schedule.Video
@@ -50,11 +42,23 @@ export class UpdateVideosScheduler extends AbstractScheduler {
50 42
51 await video.save({ transaction: t }) 43 await video.save({ transaction: t })
52 await federateVideoIfNeeded(video, isNewVideo, t) 44 await federateVideoIfNeeded(video, isNewVideo, t)
45
46 if (oldPrivacy === VideoPrivacy.UNLISTED || oldPrivacy === VideoPrivacy.PRIVATE) {
47 video.ScheduleVideoUpdate = schedule
48 publishedVideos.push(video)
49 }
53 } 50 }
54 51
55 await schedule.destroy({ transaction: t }) 52 await schedule.destroy({ transaction: t })
56 } 53 }
54
55 return publishedVideos
57 }) 56 })
57
58 for (const v of publishedVideos) {
59 Notifier.Instance.notifyOnNewVideo(v)
60 Notifier.Instance.notifyOnPendingVideoPublished(v)
61 }
58 } 62 }
59 63
60 static get Instance () { 64 static get Instance () {
diff --git a/server/lib/schedulers/videos-redundancy-scheduler.ts b/server/lib/schedulers/videos-redundancy-scheduler.ts
index 8b7f33539..f643ee226 100644
--- a/server/lib/schedulers/videos-redundancy-scheduler.ts
+++ b/server/lib/schedulers/videos-redundancy-scheduler.ts
@@ -6,7 +6,7 @@ import { VideoRedundancyModel } from '../../models/redundancy/video-redundancy'
6import { VideoFileModel } from '../../models/video/video-file' 6import { VideoFileModel } from '../../models/video/video-file'
7import { downloadWebTorrentVideo } from '../../helpers/webtorrent' 7import { downloadWebTorrentVideo } from '../../helpers/webtorrent'
8import { join } from 'path' 8import { join } from 'path'
9import { rename } from 'fs-extra' 9import { move } from 'fs-extra'
10import { getServerActor } from '../../helpers/utils' 10import { getServerActor } from '../../helpers/utils'
11import { sendCreateCacheFile, sendUpdateCacheFile } from '../activitypub/send' 11import { sendCreateCacheFile, sendUpdateCacheFile } from '../activitypub/send'
12import { getVideoCacheFileActivityPubUrl } from '../activitypub/url' 12import { getVideoCacheFileActivityPubUrl } from '../activitypub/url'
@@ -16,7 +16,6 @@ import { getOrCreateVideoAndAccountAndChannel } from '../activitypub'
16export class VideosRedundancyScheduler extends AbstractScheduler { 16export class VideosRedundancyScheduler extends AbstractScheduler {
17 17
18 private static instance: AbstractScheduler 18 private static instance: AbstractScheduler
19 private executing = false
20 19
21 protected schedulerIntervalMs = CONFIG.REDUNDANCY.VIDEOS.CHECK_INTERVAL 20 protected schedulerIntervalMs = CONFIG.REDUNDANCY.VIDEOS.CHECK_INTERVAL
22 21
@@ -24,11 +23,7 @@ export class VideosRedundancyScheduler extends AbstractScheduler {
24 super() 23 super()
25 } 24 }
26 25
27 async execute () { 26 protected async internalExecute () {
28 if (this.executing) return
29
30 this.executing = true
31
32 for (const obj of CONFIG.REDUNDANCY.VIDEOS.STRATEGIES) { 27 for (const obj of CONFIG.REDUNDANCY.VIDEOS.STRATEGIES) {
33 logger.info('Running redundancy scheduler for strategy %s.', obj.strategy) 28 logger.info('Running redundancy scheduler for strategy %s.', obj.strategy)
34 29
@@ -57,8 +52,6 @@ export class VideosRedundancyScheduler extends AbstractScheduler {
57 await this.extendsLocalExpiration() 52 await this.extendsLocalExpiration()
58 53
59 await this.purgeRemoteExpired() 54 await this.purgeRemoteExpired()
60
61 this.executing = false
62 } 55 }
63 56
64 static get Instance () { 57 static get Instance () {
@@ -145,13 +138,13 @@ export class VideosRedundancyScheduler extends AbstractScheduler {
145 138
146 const tmpPath = await downloadWebTorrentVideo({ magnetUri }, VIDEO_IMPORT_TIMEOUT) 139 const tmpPath = await downloadWebTorrentVideo({ magnetUri }, VIDEO_IMPORT_TIMEOUT)
147 140
148 const destPath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename(file)) 141 const destPath = join(CONFIG.STORAGE.REDUNDANCY_DIR, video.getVideoFilename(file))
149 await rename(tmpPath, destPath) 142 await move(tmpPath, destPath)
150 143
151 const createdModel = await VideoRedundancyModel.create({ 144 const createdModel = await VideoRedundancyModel.create({
152 expiresOn: this.buildNewExpiration(redundancy.minLifetime), 145 expiresOn: this.buildNewExpiration(redundancy.minLifetime),
153 url: getVideoCacheFileActivityPubUrl(file), 146 url: getVideoCacheFileActivityPubUrl(file),
154 fileUrl: video.getVideoFileUrl(file, CONFIG.WEBSERVER.URL), 147 fileUrl: video.getVideoRedundancyUrl(file, CONFIG.WEBSERVER.URL),
155 strategy: redundancy.strategy, 148 strategy: redundancy.strategy,
156 videoFileId: file.id, 149 videoFileId: file.id,
157 actorId: serverActor.id 150 actorId: serverActor.id
diff --git a/server/lib/schedulers/youtube-dl-update-scheduler.ts b/server/lib/schedulers/youtube-dl-update-scheduler.ts
index 461cd045e..aa027116d 100644
--- a/server/lib/schedulers/youtube-dl-update-scheduler.ts
+++ b/server/lib/schedulers/youtube-dl-update-scheduler.ts
@@ -12,7 +12,7 @@ export class YoutubeDlUpdateScheduler extends AbstractScheduler {
12 super() 12 super()
13 } 13 }
14 14
15 execute () { 15 protected internalExecute () {
16 return updateYoutubeDLBinary() 16 return updateYoutubeDLBinary()
17 } 17 }
18 18
diff --git a/server/lib/user.ts b/server/lib/user.ts
index 29d6d087d..a39ef6c3d 100644
--- a/server/lib/user.ts
+++ b/server/lib/user.ts
@@ -9,6 +9,8 @@ import { createVideoChannel } from './video-channel'
9import { VideoChannelModel } from '../models/video/video-channel' 9import { VideoChannelModel } from '../models/video/video-channel'
10import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model' 10import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model'
11import { ActorModel } from '../models/activitypub/actor' 11import { ActorModel } from '../models/activitypub/actor'
12import { UserNotificationSettingModel } from '../models/account/user-notification-setting'
13import { UserNotificationSetting, UserNotificationSettingValue } from '../../shared/models/users'
12 14
13async function createUserAccountAndChannel (userToCreate: UserModel, validateUser = true) { 15async function createUserAccountAndChannel (userToCreate: UserModel, validateUser = true) {
14 const { user, account, videoChannel } = await sequelizeTypescript.transaction(async t => { 16 const { user, account, videoChannel } = await sequelizeTypescript.transaction(async t => {
@@ -18,6 +20,8 @@ async function createUserAccountAndChannel (userToCreate: UserModel, validateUse
18 } 20 }
19 21
20 const userCreated = await userToCreate.save(userOptions) 22 const userCreated = await userToCreate.save(userOptions)
23 userCreated.NotificationSetting = await createDefaultUserNotificationSettings(userCreated, t)
24
21 const accountCreated = await createLocalAccountWithoutKeys(userCreated.username, userCreated.id, null, t) 25 const accountCreated = await createLocalAccountWithoutKeys(userCreated.username, userCreated.id, null, t)
22 userCreated.Account = accountCreated 26 userCreated.Account = accountCreated
23 27
@@ -88,3 +92,22 @@ export {
88 createUserAccountAndChannel, 92 createUserAccountAndChannel,
89 createLocalAccountWithoutKeys 93 createLocalAccountWithoutKeys
90} 94}
95
96// ---------------------------------------------------------------------------
97
98function createDefaultUserNotificationSettings (user: UserModel, t: Sequelize.Transaction | undefined) {
99 const values: UserNotificationSetting & { userId: number } = {
100 userId: user.id,
101 newVideoFromSubscription: UserNotificationSettingValue.WEB,
102 newCommentOnMyVideo: UserNotificationSettingValue.WEB,
103 myVideoImportFinished: UserNotificationSettingValue.WEB,
104 myVideoPublished: UserNotificationSettingValue.WEB,
105 videoAbuseAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
106 blacklistOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
107 newUserRegistration: UserNotificationSettingValue.WEB,
108 commentMention: UserNotificationSettingValue.WEB,
109 newFollow: UserNotificationSettingValue.WEB
110 }
111
112 return UserNotificationSettingModel.create(values, { transaction: t })
113}
diff --git a/server/lib/video-transcoding.ts b/server/lib/video-transcoding.ts
index a78de61e5..4460f46e4 100644
--- a/server/lib/video-transcoding.ts
+++ b/server/lib/video-transcoding.ts
@@ -1,7 +1,7 @@
1import { CONFIG } from '../initializers' 1import { CONFIG } from '../initializers'
2import { extname, join } from 'path' 2import { extname, join } from 'path'
3import { getVideoFileFPS, getVideoFileResolution, transcode } from '../helpers/ffmpeg-utils' 3import { getVideoFileFPS, getVideoFileResolution, transcode } from '../helpers/ffmpeg-utils'
4import { copy, remove, rename, stat } from 'fs-extra' 4import { copy, remove, move, stat } from 'fs-extra'
5import { logger } from '../helpers/logger' 5import { logger } from '../helpers/logger'
6import { VideoResolution } from '../../shared/models/videos' 6import { VideoResolution } from '../../shared/models/videos'
7import { VideoFileModel } from '../models/video/video-file' 7import { VideoFileModel } from '../models/video/video-file'
@@ -30,7 +30,7 @@ async function optimizeVideofile (video: VideoModel, inputVideoFileArg?: VideoFi
30 inputVideoFile.set('extname', newExtname) 30 inputVideoFile.set('extname', newExtname)
31 31
32 const videoOutputPath = video.getVideoFilePath(inputVideoFile) 32 const videoOutputPath = video.getVideoFilePath(inputVideoFile)
33 await rename(videoTranscodedPath, videoOutputPath) 33 await move(videoTranscodedPath, videoOutputPath)
34 const stats = await stat(videoOutputPath) 34 const stats = await stat(videoOutputPath)
35 const fps = await getVideoFileFPS(videoOutputPath) 35 const fps = await getVideoFileFPS(videoOutputPath)
36 36
diff --git a/server/middlewares/csp.ts b/server/middlewares/csp.ts
new file mode 100644
index 000000000..8b919af0d
--- /dev/null
+++ b/server/middlewares/csp.ts
@@ -0,0 +1,44 @@
1import * as helmet from 'helmet'
2import { CONFIG } from '../initializers/constants'
3
4const baseDirectives = Object.assign({},
5 {
6 defaultSrc: ["'none'"], // by default, not specifying default-src = '*'
7 connectSrc: ['*', 'data:'],
8 mediaSrc: ["'self'", 'https:', 'blob:'],
9 fontSrc: ["'self'", 'data:'],
10 imgSrc: ["'self'", 'data:'],
11 scriptSrc: ["'self' 'unsafe-inline' 'unsafe-eval'"],
12 styleSrc: ["'self' 'unsafe-inline'"],
13 objectSrc: ["'none'"], // only define to allow plugins, else let defaultSrc 'none' block it
14 formAction: ["'self'"],
15 frameAncestors: ["'none'"],
16 baseUri: ["'self'"],
17 manifestSrc: ["'self'"],
18 frameSrc: ["'self'"], // instead of deprecated child-src / self because of test-embed
19 workerSrc: ["'self'"] // instead of deprecated child-src
20 },
21 CONFIG.SERVICES['CSP-LOGGER'] ? { reportUri: CONFIG.SERVICES['CSP-LOGGER'] } : {},
22 CONFIG.WEBSERVER.SCHEME === 'https' ? { upgradeInsecureRequests: true } : {}
23)
24
25const baseCSP = helmet.contentSecurityPolicy({
26 directives: baseDirectives,
27 browserSniff: false,
28 reportOnly: true
29})
30
31const embedCSP = helmet.contentSecurityPolicy({
32 directives: Object.assign(baseDirectives, {
33 frameAncestors: ['*']
34 }),
35 browserSniff: false, // assumes a modern browser, but allows CDN in front
36 reportOnly: true
37})
38
39// ---------------------------------------------------------------------------
40
41export {
42 baseCSP,
43 embedCSP
44}
diff --git a/server/middlewares/dnt.ts b/server/middlewares/dnt.ts
index cabad39c6..607def855 100644
--- a/server/middlewares/dnt.ts
+++ b/server/middlewares/dnt.ts
@@ -10,4 +10,4 @@ const advertiseDoNotTrack = (_, res, next) => {
10 10
11export { 11export {
12 advertiseDoNotTrack 12 advertiseDoNotTrack
13 } 13}
diff --git a/server/middlewares/index.ts b/server/middlewares/index.ts
index 0cef26953..b758a8586 100644
--- a/server/middlewares/index.ts
+++ b/server/middlewares/index.ts
@@ -6,3 +6,5 @@ export * from './pagination'
6export * from './servers' 6export * from './servers'
7export * from './sort' 7export * from './sort'
8export * from './user-right' 8export * from './user-right'
9export * from './dnt'
10export * from './csp'
diff --git a/server/middlewares/oauth.ts b/server/middlewares/oauth.ts
index 8c1df2c3e..1d193d467 100644
--- a/server/middlewares/oauth.ts
+++ b/server/middlewares/oauth.ts
@@ -3,6 +3,8 @@ import * as OAuthServer from 'express-oauth-server'
3import 'express-validator' 3import 'express-validator'
4import { OAUTH_LIFETIME } from '../initializers' 4import { OAUTH_LIFETIME } from '../initializers'
5import { logger } from '../helpers/logger' 5import { logger } from '../helpers/logger'
6import { Socket } from 'socket.io'
7import { getAccessToken } from '../lib/oauth-model'
6 8
7const oAuthServer = new OAuthServer({ 9const oAuthServer = new OAuthServer({
8 useErrorHandler: true, 10 useErrorHandler: true,
@@ -28,6 +30,25 @@ function authenticate (req: express.Request, res: express.Response, next: expres
28 }) 30 })
29} 31}
30 32
33function authenticateSocket (socket: Socket, next: (err?: any) => void) {
34 const accessToken = socket.handshake.query.accessToken
35
36 logger.debug('Checking socket access token %s.', accessToken)
37
38 getAccessToken(accessToken)
39 .then(tokenDB => {
40 const now = new Date()
41
42 if (!tokenDB || tokenDB.accessTokenExpiresAt < now || tokenDB.refreshTokenExpiresAt < now) {
43 return next(new Error('Invalid access token.'))
44 }
45
46 socket.handshake.query.user = tokenDB.User
47
48 return next()
49 })
50}
51
31function authenticatePromiseIfNeeded (req: express.Request, res: express.Response) { 52function authenticatePromiseIfNeeded (req: express.Request, res: express.Response) {
32 return new Promise(resolve => { 53 return new Promise(resolve => {
33 // Already authenticated? (or tried to) 54 // Already authenticated? (or tried to)
@@ -68,6 +89,7 @@ function token (req: express.Request, res: express.Response, next: express.NextF
68 89
69export { 90export {
70 authenticate, 91 authenticate,
92 authenticateSocket,
71 authenticatePromiseIfNeeded, 93 authenticatePromiseIfNeeded,
72 optionalAuthenticate, 94 optionalAuthenticate,
73 token 95 token
diff --git a/server/middlewares/validators/config.ts b/server/middlewares/validators/config.ts
index f3f257d57..90108fa82 100644
--- a/server/middlewares/validators/config.ts
+++ b/server/middlewares/validators/config.ts
@@ -1,29 +1,44 @@
1import * as express from 'express' 1import * as express from 'express'
2import { body } from 'express-validator/check' 2import { body } from 'express-validator/check'
3import { isUserNSFWPolicyValid, isUserVideoQuotaValid } from '../../helpers/custom-validators/users' 3import { isUserNSFWPolicyValid, isUserVideoQuotaValid, isUserVideoQuotaDailyValid } from '../../helpers/custom-validators/users'
4import { logger } from '../../helpers/logger' 4import { logger } from '../../helpers/logger'
5import { areValidationErrors } from './utils' 5import { areValidationErrors } from './utils'
6 6
7const customConfigUpdateValidator = [ 7const customConfigUpdateValidator = [
8 body('instance.name').exists().withMessage('Should have a valid instance name'), 8 body('instance.name').exists().withMessage('Should have a valid instance name'),
9 body('instance.shortDescription').exists().withMessage('Should have a valid instance short description'),
9 body('instance.description').exists().withMessage('Should have a valid instance description'), 10 body('instance.description').exists().withMessage('Should have a valid instance description'),
10 body('instance.terms').exists().withMessage('Should have a valid instance terms'), 11 body('instance.terms').exists().withMessage('Should have a valid instance terms'),
11 body('instance.defaultClientRoute').exists().withMessage('Should have a valid instance default client route'), 12 body('instance.defaultClientRoute').exists().withMessage('Should have a valid instance default client route'),
12 body('instance.defaultNSFWPolicy').custom(isUserNSFWPolicyValid).withMessage('Should have a valid NSFW policy'), 13 body('instance.defaultNSFWPolicy').custom(isUserNSFWPolicyValid).withMessage('Should have a valid NSFW policy'),
13 body('instance.customizations.css').exists().withMessage('Should have a valid instance CSS customization'), 14 body('instance.customizations.css').exists().withMessage('Should have a valid instance CSS customization'),
14 body('instance.customizations.javascript').exists().withMessage('Should have a valid instance JavaScript customization'), 15 body('instance.customizations.javascript').exists().withMessage('Should have a valid instance JavaScript customization'),
15 body('cache.previews.size').isInt().withMessage('Should have a valid previews size'), 16
17 body('services.twitter.username').exists().withMessage('Should have a valid twitter username'),
18 body('services.twitter.whitelisted').isBoolean().withMessage('Should have a valid twitter whitelisted boolean'),
19
20 body('cache.previews.size').isInt().withMessage('Should have a valid previews cache size'),
21 body('cache.captions.size').isInt().withMessage('Should have a valid captions cache size'),
22
16 body('signup.enabled').isBoolean().withMessage('Should have a valid signup enabled boolean'), 23 body('signup.enabled').isBoolean().withMessage('Should have a valid signup enabled boolean'),
17 body('signup.limit').isInt().withMessage('Should have a valid signup limit'), 24 body('signup.limit').isInt().withMessage('Should have a valid signup limit'),
25 body('signup.requiresEmailVerification').isBoolean().withMessage('Should have a valid requiresEmailVerification boolean'),
26
18 body('admin.email').isEmail().withMessage('Should have a valid administrator email'), 27 body('admin.email').isEmail().withMessage('Should have a valid administrator email'),
28 body('contactForm.enabled').isBoolean().withMessage('Should have a valid contact form enabled boolean'),
29
19 body('user.videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid video quota'), 30 body('user.videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid video quota'),
31 body('user.videoQuotaDaily').custom(isUserVideoQuotaDailyValid).withMessage('Should have a valid daily video quota'),
32
20 body('transcoding.enabled').isBoolean().withMessage('Should have a valid transcoding enabled boolean'), 33 body('transcoding.enabled').isBoolean().withMessage('Should have a valid transcoding enabled boolean'),
34 body('transcoding.allowAdditionalExtensions').isBoolean().withMessage('Should have a valid additional extensions boolean'),
21 body('transcoding.threads').isInt().withMessage('Should have a valid transcoding threads number'), 35 body('transcoding.threads').isInt().withMessage('Should have a valid transcoding threads number'),
22 body('transcoding.resolutions.240p').isBoolean().withMessage('Should have a valid transcoding 240p resolution enabled boolean'), 36 body('transcoding.resolutions.240p').isBoolean().withMessage('Should have a valid transcoding 240p resolution enabled boolean'),
23 body('transcoding.resolutions.360p').isBoolean().withMessage('Should have a valid transcoding 360p resolution enabled boolean'), 37 body('transcoding.resolutions.360p').isBoolean().withMessage('Should have a valid transcoding 360p resolution enabled boolean'),
24 body('transcoding.resolutions.480p').isBoolean().withMessage('Should have a valid transcoding 480p resolution enabled boolean'), 38 body('transcoding.resolutions.480p').isBoolean().withMessage('Should have a valid transcoding 480p resolution enabled boolean'),
25 body('transcoding.resolutions.720p').isBoolean().withMessage('Should have a valid transcoding 720p resolution enabled boolean'), 39 body('transcoding.resolutions.720p').isBoolean().withMessage('Should have a valid transcoding 720p resolution enabled boolean'),
26 body('transcoding.resolutions.1080p').isBoolean().withMessage('Should have a valid transcoding 1080p resolution enabled boolean'), 40 body('transcoding.resolutions.1080p').isBoolean().withMessage('Should have a valid transcoding 1080p resolution enabled boolean'),
41
27 body('import.videos.http.enabled').isBoolean().withMessage('Should have a valid import video http enabled boolean'), 42 body('import.videos.http.enabled').isBoolean().withMessage('Should have a valid import video http enabled boolean'),
28 body('import.videos.torrent.enabled').isBoolean().withMessage('Should have a valid import video torrent enabled boolean'), 43 body('import.videos.torrent.enabled').isBoolean().withMessage('Should have a valid import video torrent enabled boolean'),
29 44
diff --git a/server/middlewares/validators/index.ts b/server/middlewares/validators/index.ts
index 46c7f0f3a..65dd00335 100644
--- a/server/middlewares/validators/index.ts
+++ b/server/middlewares/validators/index.ts
@@ -12,3 +12,4 @@ export * from './videos'
12export * from './webfinger' 12export * from './webfinger'
13export * from './search' 13export * from './search'
14export * from './server' 14export * from './server'
15export * from './user-history'
diff --git a/server/middlewares/validators/server.ts b/server/middlewares/validators/server.ts
index a491dfeb3..d85afc2ff 100644
--- a/server/middlewares/validators/server.ts
+++ b/server/middlewares/validators/server.ts
@@ -1,9 +1,13 @@
1import * as express from 'express' 1import * as express from 'express'
2import { logger } from '../../helpers/logger' 2import { logger } from '../../helpers/logger'
3import { areValidationErrors } from './utils' 3import { areValidationErrors } from './utils'
4import { isHostValid } from '../../helpers/custom-validators/servers' 4import { isHostValid, isValidContactBody } from '../../helpers/custom-validators/servers'
5import { ServerModel } from '../../models/server/server' 5import { ServerModel } from '../../models/server/server'
6import { body } from 'express-validator/check' 6import { body } from 'express-validator/check'
7import { isUserDisplayNameValid } from '../../helpers/custom-validators/users'
8import { Emailer } from '../../lib/emailer'
9import { Redis } from '../../lib/redis'
10import { CONFIG } from '../../initializers/constants'
7 11
8const serverGetValidator = [ 12const serverGetValidator = [
9 body('host').custom(isHostValid).withMessage('Should have a valid host'), 13 body('host').custom(isHostValid).withMessage('Should have a valid host'),
@@ -26,8 +30,49 @@ const serverGetValidator = [
26 } 30 }
27] 31]
28 32
33const contactAdministratorValidator = [
34 body('fromName')
35 .custom(isUserDisplayNameValid).withMessage('Should have a valid name'),
36 body('fromEmail')
37 .isEmail().withMessage('Should have a valid email'),
38 body('body')
39 .custom(isValidContactBody).withMessage('Should have a valid body'),
40
41 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
42 logger.debug('Checking contactAdministratorValidator parameters', { parameters: req.body })
43
44 if (areValidationErrors(req, res)) return
45
46 if (CONFIG.CONTACT_FORM.ENABLED === false) {
47 return res
48 .status(409)
49 .send({ error: 'Contact form is not enabled on this instance.' })
50 .end()
51 }
52
53 if (Emailer.isEnabled() === false) {
54 return res
55 .status(409)
56 .send({ error: 'Emailer is not enabled on this instance.' })
57 .end()
58 }
59
60 if (await Redis.Instance.isContactFormIpExists(req.ip)) {
61 logger.info('Refusing a contact form by %s: already sent one recently.', req.ip)
62
63 return res
64 .status(403)
65 .send({ error: 'You already sent a contact form recently.' })
66 .end()
67 }
68
69 return next()
70 }
71]
72
29// --------------------------------------------------------------------------- 73// ---------------------------------------------------------------------------
30 74
31export { 75export {
32 serverGetValidator 76 serverGetValidator,
77 contactAdministratorValidator
33} 78}
diff --git a/server/middlewares/validators/sort.ts b/server/middlewares/validators/sort.ts
index 4c0577d8f..5ceda845f 100644
--- a/server/middlewares/validators/sort.ts
+++ b/server/middlewares/validators/sort.ts
@@ -18,6 +18,7 @@ const SORTABLE_FOLLOWING_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.FOLLOW
18const SORTABLE_USER_SUBSCRIPTIONS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USER_SUBSCRIPTIONS) 18const SORTABLE_USER_SUBSCRIPTIONS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USER_SUBSCRIPTIONS)
19const SORTABLE_ACCOUNTS_BLOCKLIST_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.ACCOUNTS_BLOCKLIST) 19const SORTABLE_ACCOUNTS_BLOCKLIST_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.ACCOUNTS_BLOCKLIST)
20const SORTABLE_SERVERS_BLOCKLIST_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.SERVERS_BLOCKLIST) 20const SORTABLE_SERVERS_BLOCKLIST_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.SERVERS_BLOCKLIST)
21const SORTABLE_USER_NOTIFICATIONS_COLUMNS = createSortableColumns(SORTABLE_COLUMNS.USER_NOTIFICATIONS)
21 22
22const usersSortValidator = checkSort(SORTABLE_USERS_COLUMNS) 23const usersSortValidator = checkSort(SORTABLE_USERS_COLUMNS)
23const accountsSortValidator = checkSort(SORTABLE_ACCOUNTS_COLUMNS) 24const accountsSortValidator = checkSort(SORTABLE_ACCOUNTS_COLUMNS)
@@ -35,6 +36,7 @@ const followingSortValidator = checkSort(SORTABLE_FOLLOWING_COLUMNS)
35const userSubscriptionsSortValidator = checkSort(SORTABLE_USER_SUBSCRIPTIONS_COLUMNS) 36const userSubscriptionsSortValidator = checkSort(SORTABLE_USER_SUBSCRIPTIONS_COLUMNS)
36const accountsBlocklistSortValidator = checkSort(SORTABLE_ACCOUNTS_BLOCKLIST_COLUMNS) 37const accountsBlocklistSortValidator = checkSort(SORTABLE_ACCOUNTS_BLOCKLIST_COLUMNS)
37const serversBlocklistSortValidator = checkSort(SORTABLE_SERVERS_BLOCKLIST_COLUMNS) 38const serversBlocklistSortValidator = checkSort(SORTABLE_SERVERS_BLOCKLIST_COLUMNS)
39const userNotificationsSortValidator = checkSort(SORTABLE_USER_NOTIFICATIONS_COLUMNS)
38 40
39// --------------------------------------------------------------------------- 41// ---------------------------------------------------------------------------
40 42
@@ -54,5 +56,6 @@ export {
54 userSubscriptionsSortValidator, 56 userSubscriptionsSortValidator,
55 videoChannelsSearchSortValidator, 57 videoChannelsSearchSortValidator,
56 accountsBlocklistSortValidator, 58 accountsBlocklistSortValidator,
57 serversBlocklistSortValidator 59 serversBlocklistSortValidator,
60 userNotificationsSortValidator
58} 61}
diff --git a/server/middlewares/validators/user-history.ts b/server/middlewares/validators/user-history.ts
new file mode 100644
index 000000000..418313d09
--- /dev/null
+++ b/server/middlewares/validators/user-history.ts
@@ -0,0 +1,26 @@
1import * as express from 'express'
2import 'express-validator'
3import { body } from 'express-validator/check'
4import { logger } from '../../helpers/logger'
5import { areValidationErrors } from './utils'
6import { isDateValid } from '../../helpers/custom-validators/misc'
7
8const userHistoryRemoveValidator = [
9 body('beforeDate')
10 .optional()
11 .custom(isDateValid).withMessage('Should have a valid before date'),
12
13 (req: express.Request, res: express.Response, next: express.NextFunction) => {
14 logger.debug('Checking userHistoryRemoveValidator parameters', { parameters: req.body })
15
16 if (areValidationErrors(req, res)) return
17
18 return next()
19 }
20]
21
22// ---------------------------------------------------------------------------
23
24export {
25 userHistoryRemoveValidator
26}
diff --git a/server/middlewares/validators/user-notifications.ts b/server/middlewares/validators/user-notifications.ts
new file mode 100644
index 000000000..46486e081
--- /dev/null
+++ b/server/middlewares/validators/user-notifications.ts
@@ -0,0 +1,63 @@
1import * as express from 'express'
2import 'express-validator'
3import { body, query } from 'express-validator/check'
4import { logger } from '../../helpers/logger'
5import { areValidationErrors } from './utils'
6import { isUserNotificationSettingValid } from '../../helpers/custom-validators/user-notifications'
7import { isNotEmptyIntArray } from '../../helpers/custom-validators/misc'
8
9const listUserNotificationsValidator = [
10 query('unread')
11 .optional()
12 .toBoolean()
13 .isBoolean().withMessage('Should have a valid unread boolean'),
14
15 (req: express.Request, res: express.Response, next: express.NextFunction) => {
16 logger.debug('Checking listUserNotificationsValidator parameters', { parameters: req.query })
17
18 if (areValidationErrors(req, res)) return
19
20 return next()
21 }
22]
23
24const updateNotificationSettingsValidator = [
25 body('newVideoFromSubscription')
26 .custom(isUserNotificationSettingValid).withMessage('Should have a valid new video from subscription notification setting'),
27 body('newCommentOnMyVideo')
28 .custom(isUserNotificationSettingValid).withMessage('Should have a valid new comment on my video notification setting'),
29 body('videoAbuseAsModerator')
30 .custom(isUserNotificationSettingValid).withMessage('Should have a valid new video abuse as moderator notification setting'),
31 body('blacklistOnMyVideo')
32 .custom(isUserNotificationSettingValid).withMessage('Should have a valid new blacklist on my video notification setting'),
33
34 (req: express.Request, res: express.Response, next: express.NextFunction) => {
35 logger.debug('Checking updateNotificationSettingsValidator parameters', { parameters: req.body })
36
37 if (areValidationErrors(req, res)) return
38
39 return next()
40 }
41]
42
43const markAsReadUserNotificationsValidator = [
44 body('ids')
45 .optional()
46 .custom(isNotEmptyIntArray).withMessage('Should have a valid notification ids to mark as read'),
47
48 (req: express.Request, res: express.Response, next: express.NextFunction) => {
49 logger.debug('Checking markAsReadUserNotificationsValidator parameters', { parameters: req.body })
50
51 if (areValidationErrors(req, res)) return
52
53 return next()
54 }
55]
56
57// ---------------------------------------------------------------------------
58
59export {
60 listUserNotificationsValidator,
61 updateNotificationSettingsValidator,
62 markAsReadUserNotificationsValidator
63}
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts
index ccaf2eeb6..1bb0bfb1b 100644
--- a/server/middlewares/validators/users.ts
+++ b/server/middlewares/validators/users.ts
@@ -5,15 +5,16 @@ import { body, param } from 'express-validator/check'
5import { omit } from 'lodash' 5import { omit } from 'lodash'
6import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' 6import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
7import { 7import {
8 isUserAutoPlayVideoValid, isUserBlockedReasonValid, 8 isUserAutoPlayVideoValid,
9 isUserBlockedReasonValid,
9 isUserDescriptionValid, 10 isUserDescriptionValid,
10 isUserDisplayNameValid, 11 isUserDisplayNameValid,
11 isUserNSFWPolicyValid, 12 isUserNSFWPolicyValid,
12 isUserPasswordValid, 13 isUserPasswordValid,
13 isUserRoleValid, 14 isUserRoleValid,
14 isUserUsernameValid, 15 isUserUsernameValid,
15 isUserVideoQuotaValid, 16 isUserVideoQuotaDailyValid,
16 isUserVideoQuotaDailyValid 17 isUserVideoQuotaValid, isUserVideosHistoryEnabledValid
17} from '../../helpers/custom-validators/users' 18} from '../../helpers/custom-validators/users'
18import { isVideoExist } from '../../helpers/custom-validators/videos' 19import { isVideoExist } from '../../helpers/custom-validators/videos'
19import { logger } from '../../helpers/logger' 20import { logger } from '../../helpers/logger'
@@ -22,7 +23,6 @@ import { Redis } from '../../lib/redis'
22import { UserModel } from '../../models/account/user' 23import { UserModel } from '../../models/account/user'
23import { areValidationErrors } from './utils' 24import { areValidationErrors } from './utils'
24import { ActorModel } from '../../models/activitypub/actor' 25import { ActorModel } from '../../models/activitypub/actor'
25import { comparePassword } from '../../helpers/peertube-crypto'
26 26
27const usersAddValidator = [ 27const usersAddValidator = [
28 body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'), 28 body('username').custom(isUserUsernameValid).withMessage('Should have a valid username (lowercase alphanumeric characters)'),
@@ -144,6 +144,9 @@ const usersUpdateMeValidator = [
144 body('email').optional().isEmail().withMessage('Should have a valid email attribute'), 144 body('email').optional().isEmail().withMessage('Should have a valid email attribute'),
145 body('nsfwPolicy').optional().custom(isUserNSFWPolicyValid).withMessage('Should have a valid display Not Safe For Work policy'), 145 body('nsfwPolicy').optional().custom(isUserNSFWPolicyValid).withMessage('Should have a valid display Not Safe For Work policy'),
146 body('autoPlayVideo').optional().custom(isUserAutoPlayVideoValid).withMessage('Should have a valid automatically plays video attribute'), 146 body('autoPlayVideo').optional().custom(isUserAutoPlayVideoValid).withMessage('Should have a valid automatically plays video attribute'),
147 body('videosHistoryEnabled')
148 .optional()
149 .custom(isUserVideosHistoryEnabledValid).withMessage('Should have a valid videos history enabled attribute'),
147 150
148 async (req: express.Request, res: express.Response, next: express.NextFunction) => { 151 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
149 logger.debug('Checking usersUpdateMe parameters', { parameters: omit(req.body, 'password') }) 152 logger.debug('Checking usersUpdateMe parameters', { parameters: omit(req.body, 'password') })
diff --git a/server/middlewares/validators/videos/video-blacklist.ts b/server/middlewares/validators/videos/video-blacklist.ts
index 13da7acff..2688f63ae 100644
--- a/server/middlewares/validators/videos/video-blacklist.ts
+++ b/server/middlewares/validators/videos/video-blacklist.ts
@@ -1,10 +1,11 @@
1import * as express from 'express' 1import * as express from 'express'
2import { body, param } from 'express-validator/check' 2import { body, param } from 'express-validator/check'
3import { isIdOrUUIDValid } from '../../../helpers/custom-validators/misc' 3import { isBooleanValid, isIdOrUUIDValid } from '../../../helpers/custom-validators/misc'
4import { isVideoExist } from '../../../helpers/custom-validators/videos' 4import { isVideoExist } from '../../../helpers/custom-validators/videos'
5import { logger } from '../../../helpers/logger' 5import { logger } from '../../../helpers/logger'
6import { areValidationErrors } from '../utils' 6import { areValidationErrors } from '../utils'
7import { isVideoBlacklistExist, isVideoBlacklistReasonValid } from '../../../helpers/custom-validators/video-blacklist' 7import { isVideoBlacklistExist, isVideoBlacklistReasonValid } from '../../../helpers/custom-validators/video-blacklist'
8import { VideoModel } from '../../../models/video/video'
8 9
9const videosBlacklistRemoveValidator = [ 10const videosBlacklistRemoveValidator = [
10 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), 11 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
@@ -22,6 +23,10 @@ const videosBlacklistRemoveValidator = [
22 23
23const videosBlacklistAddValidator = [ 24const videosBlacklistAddValidator = [
24 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), 25 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
26 body('unfederate')
27 .optional()
28 .toBoolean()
29 .custom(isBooleanValid).withMessage('Should have a valid unfederate boolean'),
25 body('reason') 30 body('reason')
26 .optional() 31 .optional()
27 .custom(isVideoBlacklistReasonValid).withMessage('Should have a valid reason'), 32 .custom(isVideoBlacklistReasonValid).withMessage('Should have a valid reason'),
@@ -32,6 +37,14 @@ const videosBlacklistAddValidator = [
32 if (areValidationErrors(req, res)) return 37 if (areValidationErrors(req, res)) return
33 if (!await isVideoExist(req.params.videoId, res)) return 38 if (!await isVideoExist(req.params.videoId, res)) return
34 39
40 const video: VideoModel = res.locals.video
41 if (req.body.unfederate === true && video.remote === true) {
42 return res
43 .status(409)
44 .send({ error: 'You cannot unfederate a remote video.' })
45 .end()
46 }
47
35 return next() 48 return next()
36 } 49 }
37] 50]
diff --git a/server/middlewares/validators/videos/video-watch.ts b/server/middlewares/validators/videos/video-watch.ts
index bca64662f..c38ad8a10 100644
--- a/server/middlewares/validators/videos/video-watch.ts
+++ b/server/middlewares/validators/videos/video-watch.ts
@@ -4,6 +4,7 @@ import { isIdOrUUIDValid } from '../../../helpers/custom-validators/misc'
4import { isVideoExist } from '../../../helpers/custom-validators/videos' 4import { isVideoExist } from '../../../helpers/custom-validators/videos'
5import { areValidationErrors } from '../utils' 5import { areValidationErrors } from '../utils'
6import { logger } from '../../../helpers/logger' 6import { logger } from '../../../helpers/logger'
7import { UserModel } from '../../../models/account/user'
7 8
8const videoWatchingValidator = [ 9const videoWatchingValidator = [
9 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'), 10 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
@@ -17,6 +18,12 @@ const videoWatchingValidator = [
17 if (areValidationErrors(req, res)) return 18 if (areValidationErrors(req, res)) return
18 if (!await isVideoExist(req.params.videoId, res, 'id')) return 19 if (!await isVideoExist(req.params.videoId, res, 'id')) return
19 20
21 const user = res.locals.oauth.token.User as UserModel
22 if (user.videosHistoryEnabled === false) {
23 logger.warn('Cannot set videos to watch by user %d: videos history is disabled.', user.id)
24 return res.status(409).end()
25 }
26
20 return next() 27 return next()
21 } 28 }
22] 29]
diff --git a/server/models/account/account-blocklist.ts b/server/models/account/account-blocklist.ts
index fa2819235..efd6ed59e 100644
--- a/server/models/account/account-blocklist.ts
+++ b/server/models/account/account-blocklist.ts
@@ -2,6 +2,7 @@ import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, Updated
2import { AccountModel } from './account' 2import { AccountModel } from './account'
3import { getSort } from '../utils' 3import { getSort } from '../utils'
4import { AccountBlock } from '../../../shared/models/blocklist' 4import { AccountBlock } from '../../../shared/models/blocklist'
5import { Op } from 'sequelize'
5 6
6enum ScopeNames { 7enum ScopeNames {
7 WITH_ACCOUNTS = 'WITH_ACCOUNTS' 8 WITH_ACCOUNTS = 'WITH_ACCOUNTS'
@@ -72,6 +73,36 @@ export class AccountBlocklistModel extends Model<AccountBlocklistModel> {
72 }) 73 })
73 BlockedAccount: AccountModel 74 BlockedAccount: AccountModel
74 75
76 static isAccountMutedBy (accountId: number, targetAccountId: number) {
77 return AccountBlocklistModel.isAccountMutedByMulti([ accountId ], targetAccountId)
78 .then(result => result[accountId])
79 }
80
81 static isAccountMutedByMulti (accountIds: number[], targetAccountId: number) {
82 const query = {
83 attributes: [ 'accountId', 'id' ],
84 where: {
85 accountId: {
86 [Op.any]: accountIds
87 },
88 targetAccountId
89 },
90 raw: true
91 }
92
93 return AccountBlocklistModel.unscoped()
94 .findAll(query)
95 .then(rows => {
96 const result: { [accountId: number]: boolean } = {}
97
98 for (const accountId of accountIds) {
99 result[accountId] = !!rows.find(r => r.accountId === accountId)
100 }
101
102 return result
103 })
104 }
105
75 static loadByAccountAndTarget (accountId: number, targetAccountId: number) { 106 static loadByAccountAndTarget (accountId: number, targetAccountId: number) {
76 const query = { 107 const query = {
77 where: { 108 where: {
diff --git a/server/models/account/account.ts b/server/models/account/account.ts
index 5a237d733..84ef0b30d 100644
--- a/server/models/account/account.ts
+++ b/server/models/account/account.ts
@@ -241,6 +241,27 @@ export class AccountModel extends Model<AccountModel> {
241 }) 241 })
242 } 242 }
243 243
244 static listLocalsForSitemap (sort: string) {
245 const query = {
246 attributes: [ ],
247 offset: 0,
248 order: getSort(sort),
249 include: [
250 {
251 attributes: [ 'preferredUsername', 'serverId' ],
252 model: ActorModel.unscoped(),
253 where: {
254 serverId: null
255 }
256 }
257 ]
258 }
259
260 return AccountModel
261 .unscoped()
262 .findAll(query)
263 }
264
244 toFormattedJSON (): Account { 265 toFormattedJSON (): Account {
245 const actor = this.Actor.toFormattedJSON() 266 const actor = this.Actor.toFormattedJSON()
246 const account = { 267 const account = {
@@ -267,6 +288,10 @@ export class AccountModel extends Model<AccountModel> {
267 return this.Actor.isOwned() 288 return this.Actor.isOwned()
268 } 289 }
269 290
291 isOutdated () {
292 return this.Actor.isOutdated()
293 }
294
270 getDisplayName () { 295 getDisplayName () {
271 return this.name 296 return this.name
272 } 297 }
diff --git a/server/models/account/user-notification-setting.ts b/server/models/account/user-notification-setting.ts
new file mode 100644
index 000000000..f1c3ac223
--- /dev/null
+++ b/server/models/account/user-notification-setting.ts
@@ -0,0 +1,150 @@
1import {
2 AfterDestroy,
3 AfterUpdate,
4 AllowNull,
5 BelongsTo,
6 Column,
7 CreatedAt,
8 Default,
9 ForeignKey,
10 Is,
11 Model,
12 Table,
13 UpdatedAt
14} from 'sequelize-typescript'
15import { throwIfNotValid } from '../utils'
16import { UserModel } from './user'
17import { isUserNotificationSettingValid } from '../../helpers/custom-validators/user-notifications'
18import { UserNotificationSetting, UserNotificationSettingValue } from '../../../shared/models/users/user-notification-setting.model'
19import { clearCacheByUserId } from '../../lib/oauth-model'
20
21@Table({
22 tableName: 'userNotificationSetting',
23 indexes: [
24 {
25 fields: [ 'userId' ],
26 unique: true
27 }
28 ]
29})
30export class UserNotificationSettingModel extends Model<UserNotificationSettingModel> {
31
32 @AllowNull(false)
33 @Default(null)
34 @Is(
35 'UserNotificationSettingNewVideoFromSubscription',
36 value => throwIfNotValid(value, isUserNotificationSettingValid, 'newVideoFromSubscription')
37 )
38 @Column
39 newVideoFromSubscription: UserNotificationSettingValue
40
41 @AllowNull(false)
42 @Default(null)
43 @Is(
44 'UserNotificationSettingNewCommentOnMyVideo',
45 value => throwIfNotValid(value, isUserNotificationSettingValid, 'newCommentOnMyVideo')
46 )
47 @Column
48 newCommentOnMyVideo: UserNotificationSettingValue
49
50 @AllowNull(false)
51 @Default(null)
52 @Is(
53 'UserNotificationSettingVideoAbuseAsModerator',
54 value => throwIfNotValid(value, isUserNotificationSettingValid, 'videoAbuseAsModerator')
55 )
56 @Column
57 videoAbuseAsModerator: UserNotificationSettingValue
58
59 @AllowNull(false)
60 @Default(null)
61 @Is(
62 'UserNotificationSettingBlacklistOnMyVideo',
63 value => throwIfNotValid(value, isUserNotificationSettingValid, 'blacklistOnMyVideo')
64 )
65 @Column
66 blacklistOnMyVideo: UserNotificationSettingValue
67
68 @AllowNull(false)
69 @Default(null)
70 @Is(
71 'UserNotificationSettingMyVideoPublished',
72 value => throwIfNotValid(value, isUserNotificationSettingValid, 'myVideoPublished')
73 )
74 @Column
75 myVideoPublished: UserNotificationSettingValue
76
77 @AllowNull(false)
78 @Default(null)
79 @Is(
80 'UserNotificationSettingMyVideoImportFinished',
81 value => throwIfNotValid(value, isUserNotificationSettingValid, 'myVideoImportFinished')
82 )
83 @Column
84 myVideoImportFinished: UserNotificationSettingValue
85
86 @AllowNull(false)
87 @Default(null)
88 @Is(
89 'UserNotificationSettingNewUserRegistration',
90 value => throwIfNotValid(value, isUserNotificationSettingValid, 'newUserRegistration')
91 )
92 @Column
93 newUserRegistration: UserNotificationSettingValue
94
95 @AllowNull(false)
96 @Default(null)
97 @Is(
98 'UserNotificationSettingNewFollow',
99 value => throwIfNotValid(value, isUserNotificationSettingValid, 'newFollow')
100 )
101 @Column
102 newFollow: UserNotificationSettingValue
103
104 @AllowNull(false)
105 @Default(null)
106 @Is(
107 'UserNotificationSettingCommentMention',
108 value => throwIfNotValid(value, isUserNotificationSettingValid, 'commentMention')
109 )
110 @Column
111 commentMention: UserNotificationSettingValue
112
113 @ForeignKey(() => UserModel)
114 @Column
115 userId: number
116
117 @BelongsTo(() => UserModel, {
118 foreignKey: {
119 allowNull: false
120 },
121 onDelete: 'cascade'
122 })
123 User: UserModel
124
125 @CreatedAt
126 createdAt: Date
127
128 @UpdatedAt
129 updatedAt: Date
130
131 @AfterUpdate
132 @AfterDestroy
133 static removeTokenCache (instance: UserNotificationSettingModel) {
134 return clearCacheByUserId(instance.userId)
135 }
136
137 toFormattedJSON (): UserNotificationSetting {
138 return {
139 newCommentOnMyVideo: this.newCommentOnMyVideo,
140 newVideoFromSubscription: this.newVideoFromSubscription,
141 videoAbuseAsModerator: this.videoAbuseAsModerator,
142 blacklistOnMyVideo: this.blacklistOnMyVideo,
143 myVideoPublished: this.myVideoPublished,
144 myVideoImportFinished: this.myVideoImportFinished,
145 newUserRegistration: this.newUserRegistration,
146 commentMention: this.commentMention,
147 newFollow: this.newFollow
148 }
149 }
150}
diff --git a/server/models/account/user-notification.ts b/server/models/account/user-notification.ts
new file mode 100644
index 000000000..6cdbb827b
--- /dev/null
+++ b/server/models/account/user-notification.ts
@@ -0,0 +1,472 @@
1import {
2 AllowNull,
3 BelongsTo,
4 Column,
5 CreatedAt,
6 Default,
7 ForeignKey,
8 IFindOptions,
9 Is,
10 Model,
11 Scopes,
12 Table,
13 UpdatedAt
14} from 'sequelize-typescript'
15import { UserNotification, UserNotificationType } from '../../../shared'
16import { getSort, throwIfNotValid } from '../utils'
17import { isBooleanValid } from '../../helpers/custom-validators/misc'
18import { isUserNotificationTypeValid } from '../../helpers/custom-validators/user-notifications'
19import { UserModel } from './user'
20import { VideoModel } from '../video/video'
21import { VideoCommentModel } from '../video/video-comment'
22import { Op } from 'sequelize'
23import { VideoChannelModel } from '../video/video-channel'
24import { AccountModel } from './account'
25import { VideoAbuseModel } from '../video/video-abuse'
26import { VideoBlacklistModel } from '../video/video-blacklist'
27import { VideoImportModel } from '../video/video-import'
28import { ActorModel } from '../activitypub/actor'
29import { ActorFollowModel } from '../activitypub/actor-follow'
30import { AvatarModel } from '../avatar/avatar'
31import { ServerModel } from '../server/server'
32
33enum ScopeNames {
34 WITH_ALL = 'WITH_ALL'
35}
36
37function buildActorWithAvatarInclude () {
38 return {
39 attributes: [ 'preferredUsername' ],
40 model: () => ActorModel.unscoped(),
41 required: true,
42 include: [
43 {
44 attributes: [ 'filename' ],
45 model: () => AvatarModel.unscoped(),
46 required: false
47 },
48 {
49 attributes: [ 'host' ],
50 model: () => ServerModel.unscoped(),
51 required: false
52 }
53 ]
54 }
55}
56
57function buildVideoInclude (required: boolean) {
58 return {
59 attributes: [ 'id', 'uuid', 'name' ],
60 model: () => VideoModel.unscoped(),
61 required
62 }
63}
64
65function buildChannelInclude (required: boolean, withActor = false) {
66 return {
67 required,
68 attributes: [ 'id', 'name' ],
69 model: () => VideoChannelModel.unscoped(),
70 include: withActor === true ? [ buildActorWithAvatarInclude() ] : []
71 }
72}
73
74function buildAccountInclude (required: boolean, withActor = false) {
75 return {
76 required,
77 attributes: [ 'id', 'name' ],
78 model: () => AccountModel.unscoped(),
79 include: withActor === true ? [ buildActorWithAvatarInclude() ] : []
80 }
81}
82
83@Scopes({
84 [ScopeNames.WITH_ALL]: {
85 include: [
86 Object.assign(buildVideoInclude(false), {
87 include: [ buildChannelInclude(true, true) ]
88 }),
89
90 {
91 attributes: [ 'id', 'originCommentId' ],
92 model: () => VideoCommentModel.unscoped(),
93 required: false,
94 include: [
95 buildAccountInclude(true, true),
96 buildVideoInclude(true)
97 ]
98 },
99
100 {
101 attributes: [ 'id' ],
102 model: () => VideoAbuseModel.unscoped(),
103 required: false,
104 include: [ buildVideoInclude(true) ]
105 },
106
107 {
108 attributes: [ 'id' ],
109 model: () => VideoBlacklistModel.unscoped(),
110 required: false,
111 include: [ buildVideoInclude(true) ]
112 },
113
114 {
115 attributes: [ 'id', 'magnetUri', 'targetUrl', 'torrentName' ],
116 model: () => VideoImportModel.unscoped(),
117 required: false,
118 include: [ buildVideoInclude(false) ]
119 },
120
121 {
122 attributes: [ 'id' ],
123 model: () => ActorFollowModel.unscoped(),
124 required: false,
125 include: [
126 {
127 attributes: [ 'preferredUsername' ],
128 model: () => ActorModel.unscoped(),
129 required: true,
130 as: 'ActorFollower',
131 include: [
132 {
133 attributes: [ 'id', 'name' ],
134 model: () => AccountModel.unscoped(),
135 required: true
136 },
137 {
138 attributes: [ 'filename' ],
139 model: () => AvatarModel.unscoped(),
140 required: false
141 },
142 {
143 attributes: [ 'host' ],
144 model: () => ServerModel.unscoped(),
145 required: false
146 }
147 ]
148 },
149 {
150 attributes: [ 'preferredUsername' ],
151 model: () => ActorModel.unscoped(),
152 required: true,
153 as: 'ActorFollowing',
154 include: [
155 buildChannelInclude(false),
156 buildAccountInclude(false)
157 ]
158 }
159 ]
160 },
161
162 buildAccountInclude(false, true)
163 ]
164 }
165})
166@Table({
167 tableName: 'userNotification',
168 indexes: [
169 {
170 fields: [ 'userId' ]
171 },
172 {
173 fields: [ 'videoId' ],
174 where: {
175 videoId: {
176 [Op.ne]: null
177 }
178 }
179 },
180 {
181 fields: [ 'commentId' ],
182 where: {
183 commentId: {
184 [Op.ne]: null
185 }
186 }
187 },
188 {
189 fields: [ 'videoAbuseId' ],
190 where: {
191 videoAbuseId: {
192 [Op.ne]: null
193 }
194 }
195 },
196 {
197 fields: [ 'videoBlacklistId' ],
198 where: {
199 videoBlacklistId: {
200 [Op.ne]: null
201 }
202 }
203 },
204 {
205 fields: [ 'videoImportId' ],
206 where: {
207 videoImportId: {
208 [Op.ne]: null
209 }
210 }
211 },
212 {
213 fields: [ 'accountId' ],
214 where: {
215 accountId: {
216 [Op.ne]: null
217 }
218 }
219 },
220 {
221 fields: [ 'actorFollowId' ],
222 where: {
223 actorFollowId: {
224 [Op.ne]: null
225 }
226 }
227 }
228 ]
229})
230export class UserNotificationModel extends Model<UserNotificationModel> {
231
232 @AllowNull(false)
233 @Default(null)
234 @Is('UserNotificationType', value => throwIfNotValid(value, isUserNotificationTypeValid, 'type'))
235 @Column
236 type: UserNotificationType
237
238 @AllowNull(false)
239 @Default(false)
240 @Is('UserNotificationRead', value => throwIfNotValid(value, isBooleanValid, 'read'))
241 @Column
242 read: boolean
243
244 @CreatedAt
245 createdAt: Date
246
247 @UpdatedAt
248 updatedAt: Date
249
250 @ForeignKey(() => UserModel)
251 @Column
252 userId: number
253
254 @BelongsTo(() => UserModel, {
255 foreignKey: {
256 allowNull: false
257 },
258 onDelete: 'cascade'
259 })
260 User: UserModel
261
262 @ForeignKey(() => VideoModel)
263 @Column
264 videoId: number
265
266 @BelongsTo(() => VideoModel, {
267 foreignKey: {
268 allowNull: true
269 },
270 onDelete: 'cascade'
271 })
272 Video: VideoModel
273
274 @ForeignKey(() => VideoCommentModel)
275 @Column
276 commentId: number
277
278 @BelongsTo(() => VideoCommentModel, {
279 foreignKey: {
280 allowNull: true
281 },
282 onDelete: 'cascade'
283 })
284 Comment: VideoCommentModel
285
286 @ForeignKey(() => VideoAbuseModel)
287 @Column
288 videoAbuseId: number
289
290 @BelongsTo(() => VideoAbuseModel, {
291 foreignKey: {
292 allowNull: true
293 },
294 onDelete: 'cascade'
295 })
296 VideoAbuse: VideoAbuseModel
297
298 @ForeignKey(() => VideoBlacklistModel)
299 @Column
300 videoBlacklistId: number
301
302 @BelongsTo(() => VideoBlacklistModel, {
303 foreignKey: {
304 allowNull: true
305 },
306 onDelete: 'cascade'
307 })
308 VideoBlacklist: VideoBlacklistModel
309
310 @ForeignKey(() => VideoImportModel)
311 @Column
312 videoImportId: number
313
314 @BelongsTo(() => VideoImportModel, {
315 foreignKey: {
316 allowNull: true
317 },
318 onDelete: 'cascade'
319 })
320 VideoImport: VideoImportModel
321
322 @ForeignKey(() => AccountModel)
323 @Column
324 accountId: number
325
326 @BelongsTo(() => AccountModel, {
327 foreignKey: {
328 allowNull: true
329 },
330 onDelete: 'cascade'
331 })
332 Account: AccountModel
333
334 @ForeignKey(() => ActorFollowModel)
335 @Column
336 actorFollowId: number
337
338 @BelongsTo(() => ActorFollowModel, {
339 foreignKey: {
340 allowNull: true
341 },
342 onDelete: 'cascade'
343 })
344 ActorFollow: ActorFollowModel
345
346 static listForApi (userId: number, start: number, count: number, sort: string, unread?: boolean) {
347 const query: IFindOptions<UserNotificationModel> = {
348 offset: start,
349 limit: count,
350 order: getSort(sort),
351 where: {
352 userId
353 }
354 }
355
356 if (unread !== undefined) query.where['read'] = !unread
357
358 return UserNotificationModel.scope(ScopeNames.WITH_ALL)
359 .findAndCountAll(query)
360 .then(({ rows, count }) => {
361 return {
362 data: rows,
363 total: count
364 }
365 })
366 }
367
368 static markAsRead (userId: number, notificationIds: number[]) {
369 const query = {
370 where: {
371 userId,
372 id: {
373 [Op.any]: notificationIds
374 }
375 }
376 }
377
378 return UserNotificationModel.update({ read: true }, query)
379 }
380
381 static markAllAsRead (userId: number) {
382 const query = { where: { userId } }
383
384 return UserNotificationModel.update({ read: true }, query)
385 }
386
387 toFormattedJSON (): UserNotification {
388 const video = this.Video
389 ? Object.assign(this.formatVideo(this.Video),{ channel: this.formatActor(this.Video.VideoChannel) })
390 : undefined
391
392 const videoImport = this.VideoImport ? {
393 id: this.VideoImport.id,
394 video: this.VideoImport.Video ? this.formatVideo(this.VideoImport.Video) : undefined,
395 torrentName: this.VideoImport.torrentName,
396 magnetUri: this.VideoImport.magnetUri,
397 targetUrl: this.VideoImport.targetUrl
398 } : undefined
399
400 const comment = this.Comment ? {
401 id: this.Comment.id,
402 threadId: this.Comment.getThreadId(),
403 account: this.formatActor(this.Comment.Account),
404 video: this.formatVideo(this.Comment.Video)
405 } : undefined
406
407 const videoAbuse = this.VideoAbuse ? {
408 id: this.VideoAbuse.id,
409 video: this.formatVideo(this.VideoAbuse.Video)
410 } : undefined
411
412 const videoBlacklist = this.VideoBlacklist ? {
413 id: this.VideoBlacklist.id,
414 video: this.formatVideo(this.VideoBlacklist.Video)
415 } : undefined
416
417 const account = this.Account ? this.formatActor(this.Account) : undefined
418
419 const actorFollow = this.ActorFollow ? {
420 id: this.ActorFollow.id,
421 follower: {
422 id: this.ActorFollow.ActorFollower.Account.id,
423 displayName: this.ActorFollow.ActorFollower.Account.getDisplayName(),
424 name: this.ActorFollow.ActorFollower.preferredUsername,
425 avatar: this.ActorFollow.ActorFollower.Avatar ? { path: this.ActorFollow.ActorFollower.Avatar.getWebserverPath() } : undefined,
426 host: this.ActorFollow.ActorFollower.getHost()
427 },
428 following: {
429 type: this.ActorFollow.ActorFollowing.VideoChannel ? 'channel' as 'channel' : 'account' as 'account',
430 displayName: (this.ActorFollow.ActorFollowing.VideoChannel || this.ActorFollow.ActorFollowing.Account).getDisplayName(),
431 name: this.ActorFollow.ActorFollowing.preferredUsername
432 }
433 } : undefined
434
435 return {
436 id: this.id,
437 type: this.type,
438 read: this.read,
439 video,
440 videoImport,
441 comment,
442 videoAbuse,
443 videoBlacklist,
444 account,
445 actorFollow,
446 createdAt: this.createdAt.toISOString(),
447 updatedAt: this.updatedAt.toISOString()
448 }
449 }
450
451 private formatVideo (video: VideoModel) {
452 return {
453 id: video.id,
454 uuid: video.uuid,
455 name: video.name
456 }
457 }
458
459 private formatActor (accountOrChannel: AccountModel | VideoChannelModel) {
460 const avatar = accountOrChannel.Actor.Avatar
461 ? { path: accountOrChannel.Actor.Avatar.getWebserverPath() }
462 : undefined
463
464 return {
465 id: accountOrChannel.id,
466 displayName: accountOrChannel.getDisplayName(),
467 name: accountOrChannel.Actor.preferredUsername,
468 host: accountOrChannel.Actor.getHost(),
469 avatar
470 }
471 }
472}
diff --git a/server/models/account/user-video-history.ts b/server/models/account/user-video-history.ts
index 0476cad9d..15cb399c9 100644
--- a/server/models/account/user-video-history.ts
+++ b/server/models/account/user-video-history.ts
@@ -1,6 +1,7 @@
1import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, IsInt, Min, Model, Table, UpdatedAt } from 'sequelize-typescript' 1import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, IsInt, Model, Table, UpdatedAt } from 'sequelize-typescript'
2import { VideoModel } from '../video/video' 2import { VideoModel } from '../video/video'
3import { UserModel } from './user' 3import { UserModel } from './user'
4import { Transaction, Op, DestroyOptions } from 'sequelize'
4 5
5@Table({ 6@Table({
6 tableName: 'userVideoHistory', 7 tableName: 'userVideoHistory',
@@ -52,4 +53,34 @@ export class UserVideoHistoryModel extends Model<UserVideoHistoryModel> {
52 onDelete: 'CASCADE' 53 onDelete: 'CASCADE'
53 }) 54 })
54 User: UserModel 55 User: UserModel
56
57 static listForApi (user: UserModel, start: number, count: number) {
58 return VideoModel.listForApi({
59 start,
60 count,
61 sort: '-UserVideoHistories.updatedAt',
62 nsfw: null, // All
63 includeLocalVideos: true,
64 withFiles: false,
65 user,
66 historyOfUser: user
67 })
68 }
69
70 static removeHistoryBefore (user: UserModel, beforeDate: string, t: Transaction) {
71 const query: DestroyOptions = {
72 where: {
73 userId: user.id
74 },
75 transaction: t
76 }
77
78 if (beforeDate) {
79 query.where.updatedAt = {
80 [Op.lt]: beforeDate
81 }
82 }
83
84 return UserVideoHistoryModel.destroy(query)
85 }
55} 86}
diff --git a/server/models/account/user.ts b/server/models/account/user.ts
index 1843603f1..017a96657 100644
--- a/server/models/account/user.ts
+++ b/server/models/account/user.ts
@@ -32,6 +32,7 @@ import {
32 isUserUsernameValid, 32 isUserUsernameValid,
33 isUserVideoQuotaDailyValid, 33 isUserVideoQuotaDailyValid,
34 isUserVideoQuotaValid, 34 isUserVideoQuotaValid,
35 isUserVideosHistoryEnabledValid,
35 isUserWebTorrentEnabledValid 36 isUserWebTorrentEnabledValid
36} from '../../helpers/custom-validators/users' 37} from '../../helpers/custom-validators/users'
37import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto' 38import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto'
@@ -43,6 +44,11 @@ import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type'
43import { values } from 'lodash' 44import { values } from 'lodash'
44import { NSFW_POLICY_TYPES } from '../../initializers' 45import { NSFW_POLICY_TYPES } from '../../initializers'
45import { clearCacheByUserId } from '../../lib/oauth-model' 46import { clearCacheByUserId } from '../../lib/oauth-model'
47import { UserNotificationSettingModel } from './user-notification-setting'
48import { VideoModel } from '../video/video'
49import { ActorModel } from '../activitypub/actor'
50import { ActorFollowModel } from '../activitypub/actor-follow'
51import { VideoImportModel } from '../video/video-import'
46 52
47enum ScopeNames { 53enum ScopeNames {
48 WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL' 54 WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL'
@@ -53,6 +59,10 @@ enum ScopeNames {
53 { 59 {
54 model: () => AccountModel, 60 model: () => AccountModel,
55 required: true 61 required: true
62 },
63 {
64 model: () => UserNotificationSettingModel,
65 required: true
56 } 66 }
57 ] 67 ]
58}) 68})
@@ -63,6 +73,10 @@ enum ScopeNames {
63 model: () => AccountModel, 73 model: () => AccountModel,
64 required: true, 74 required: true,
65 include: [ () => VideoChannelModel ] 75 include: [ () => VideoChannelModel ]
76 },
77 {
78 model: () => UserNotificationSettingModel,
79 required: true
66 } 80 }
67 ] 81 ]
68 } 82 }
@@ -116,6 +130,12 @@ export class UserModel extends Model<UserModel> {
116 130
117 @AllowNull(false) 131 @AllowNull(false)
118 @Default(true) 132 @Default(true)
133 @Is('UserVideosHistoryEnabled', value => throwIfNotValid(value, isUserVideosHistoryEnabledValid, 'Videos history enabled'))
134 @Column
135 videosHistoryEnabled: boolean
136
137 @AllowNull(false)
138 @Default(true)
119 @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean')) 139 @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean'))
120 @Column 140 @Column
121 autoPlayVideo: boolean 141 autoPlayVideo: boolean
@@ -160,6 +180,19 @@ export class UserModel extends Model<UserModel> {
160 }) 180 })
161 Account: AccountModel 181 Account: AccountModel
162 182
183 @HasOne(() => UserNotificationSettingModel, {
184 foreignKey: 'userId',
185 onDelete: 'cascade',
186 hooks: true
187 })
188 NotificationSetting: UserNotificationSettingModel
189
190 @HasMany(() => VideoImportModel, {
191 foreignKey: 'userId',
192 onDelete: 'cascade'
193 })
194 VideoImports: VideoImportModel[]
195
163 @HasMany(() => OAuthTokenModel, { 196 @HasMany(() => OAuthTokenModel, {
164 foreignKey: 'userId', 197 foreignKey: 'userId',
165 onDelete: 'cascade' 198 onDelete: 'cascade'
@@ -242,13 +275,12 @@ export class UserModel extends Model<UserModel> {
242 }) 275 })
243 } 276 }
244 277
245 static listEmailsWithRight (right: UserRight) { 278 static listWithRight (right: UserRight) {
246 const roles = Object.keys(USER_ROLE_LABELS) 279 const roles = Object.keys(USER_ROLE_LABELS)
247 .map(k => parseInt(k, 10) as UserRole) 280 .map(k => parseInt(k, 10) as UserRole)
248 .filter(role => hasUserRight(role, right)) 281 .filter(role => hasUserRight(role, right))
249 282
250 const query = { 283 const query = {
251 attribute: [ 'email' ],
252 where: { 284 where: {
253 role: { 285 role: {
254 [Sequelize.Op.in]: roles 286 [Sequelize.Op.in]: roles
@@ -256,9 +288,56 @@ export class UserModel extends Model<UserModel> {
256 } 288 }
257 } 289 }
258 290
259 return UserModel.unscoped() 291 return UserModel.findAll(query)
260 .findAll(query) 292 }
261 .then(u => u.map(u => u.email)) 293
294 static listUserSubscribersOf (actorId: number) {
295 const query = {
296 include: [
297 {
298 model: UserNotificationSettingModel.unscoped(),
299 required: true
300 },
301 {
302 attributes: [ 'userId' ],
303 model: AccountModel.unscoped(),
304 required: true,
305 include: [
306 {
307 attributes: [ ],
308 model: ActorModel.unscoped(),
309 required: true,
310 where: {
311 serverId: null
312 },
313 include: [
314 {
315 attributes: [ ],
316 as: 'ActorFollowings',
317 model: ActorFollowModel.unscoped(),
318 required: true,
319 where: {
320 targetActorId: actorId
321 }
322 }
323 ]
324 }
325 ]
326 }
327 ]
328 }
329
330 return UserModel.unscoped().findAll(query)
331 }
332
333 static listByUsernames (usernames: string[]) {
334 const query = {
335 where: {
336 username: usernames
337 }
338 }
339
340 return UserModel.findAll(query)
262 } 341 }
263 342
264 static loadById (id: number) { 343 static loadById (id: number) {
@@ -307,6 +386,95 @@ export class UserModel extends Model<UserModel> {
307 return UserModel.findOne(query) 386 return UserModel.findOne(query)
308 } 387 }
309 388
389 static loadByVideoId (videoId: number) {
390 const query = {
391 include: [
392 {
393 required: true,
394 attributes: [ 'id' ],
395 model: AccountModel.unscoped(),
396 include: [
397 {
398 required: true,
399 attributes: [ 'id' ],
400 model: VideoChannelModel.unscoped(),
401 include: [
402 {
403 required: true,
404 attributes: [ 'id' ],
405 model: VideoModel.unscoped(),
406 where: {
407 id: videoId
408 }
409 }
410 ]
411 }
412 ]
413 }
414 ]
415 }
416
417 return UserModel.findOne(query)
418 }
419
420 static loadByVideoImportId (videoImportId: number) {
421 const query = {
422 include: [
423 {
424 required: true,
425 attributes: [ 'id' ],
426 model: VideoImportModel.unscoped(),
427 where: {
428 id: videoImportId
429 }
430 }
431 ]
432 }
433
434 return UserModel.findOne(query)
435 }
436
437 static loadByChannelActorId (videoChannelActorId: number) {
438 const query = {
439 include: [
440 {
441 required: true,
442 attributes: [ 'id' ],
443 model: AccountModel.unscoped(),
444 include: [
445 {
446 required: true,
447 attributes: [ 'id' ],
448 model: VideoChannelModel.unscoped(),
449 where: {
450 actorId: videoChannelActorId
451 }
452 }
453 ]
454 }
455 ]
456 }
457
458 return UserModel.findOne(query)
459 }
460
461 static loadByAccountActorId (accountActorId: number) {
462 const query = {
463 include: [
464 {
465 required: true,
466 attributes: [ 'id' ],
467 model: AccountModel.unscoped(),
468 where: {
469 actorId: accountActorId
470 }
471 }
472 ]
473 }
474
475 return UserModel.findOne(query)
476 }
477
310 static getOriginalVideoFileTotalFromUser (user: UserModel) { 478 static getOriginalVideoFileTotalFromUser (user: UserModel) {
311 // Don't use sequelize because we need to use a sub query 479 // Don't use sequelize because we need to use a sub query
312 const query = UserModel.generateUserQuotaBaseSQL() 480 const query = UserModel.generateUserQuotaBaseSQL()
@@ -363,6 +531,7 @@ export class UserModel extends Model<UserModel> {
363 emailVerified: this.emailVerified, 531 emailVerified: this.emailVerified,
364 nsfwPolicy: this.nsfwPolicy, 532 nsfwPolicy: this.nsfwPolicy,
365 webTorrentEnabled: this.webTorrentEnabled, 533 webTorrentEnabled: this.webTorrentEnabled,
534 videosHistoryEnabled: this.videosHistoryEnabled,
366 autoPlayVideo: this.autoPlayVideo, 535 autoPlayVideo: this.autoPlayVideo,
367 role: this.role, 536 role: this.role,
368 roleLabel: USER_ROLE_LABELS[ this.role ], 537 roleLabel: USER_ROLE_LABELS[ this.role ],
@@ -372,6 +541,7 @@ export class UserModel extends Model<UserModel> {
372 blocked: this.blocked, 541 blocked: this.blocked,
373 blockedReason: this.blockedReason, 542 blockedReason: this.blockedReason,
374 account: this.Account.toFormattedJSON(), 543 account: this.Account.toFormattedJSON(),
544 notificationSettings: this.NotificationSetting ? this.NotificationSetting.toFormattedJSON() : undefined,
375 videoChannels: [], 545 videoChannels: [],
376 videoQuotaUsed: videoQuotaUsed !== undefined 546 videoQuotaUsed: videoQuotaUsed !== undefined
377 ? parseInt(videoQuotaUsed, 10) 547 ? parseInt(videoQuotaUsed, 10)
diff --git a/server/models/activitypub/actor-follow.ts b/server/models/activitypub/actor-follow.ts
index 0a6935083..796e07a42 100644
--- a/server/models/activitypub/actor-follow.ts
+++ b/server/models/activitypub/actor-follow.ts
@@ -127,22 +127,6 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
127 if (numberOfActorFollowsRemoved) logger.info('Removed bad %d actor follows.', numberOfActorFollowsRemoved) 127 if (numberOfActorFollowsRemoved) logger.info('Removed bad %d actor follows.', numberOfActorFollowsRemoved)
128 } 128 }
129 129
130 static updateActorFollowsScore (goodInboxes: string[], badInboxes: string[], t: Sequelize.Transaction | undefined) {
131 if (goodInboxes.length === 0 && badInboxes.length === 0) return
132
133 logger.info('Updating %d good actor follows and %d bad actor follows scores.', goodInboxes.length, badInboxes.length)
134
135 if (goodInboxes.length !== 0) {
136 ActorFollowModel.incrementScores(goodInboxes, ACTOR_FOLLOW_SCORE.BONUS, t)
137 .catch(err => logger.error('Cannot increment scores of good actor follows.', { err }))
138 }
139
140 if (badInboxes.length !== 0) {
141 ActorFollowModel.incrementScores(badInboxes, ACTOR_FOLLOW_SCORE.PENALTY, t)
142 .catch(err => logger.error('Cannot decrement scores of bad actor follows.', { err }))
143 }
144 }
145
146 static loadByActorAndTarget (actorId: number, targetActorId: number, t?: Sequelize.Transaction) { 130 static loadByActorAndTarget (actorId: number, targetActorId: number, t?: Sequelize.Transaction) {
147 const query = { 131 const query = {
148 where: { 132 where: {
@@ -323,7 +307,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
323 }) 307 })
324 } 308 }
325 309
326 static listFollowersForApi (id: number, start: number, count: number, sort: string, search?: string) { 310 static listFollowersForApi (actorId: number, start: number, count: number, sort: string, search?: string) {
327 const query = { 311 const query = {
328 distinct: true, 312 distinct: true,
329 offset: start, 313 offset: start,
@@ -351,7 +335,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
351 as: 'ActorFollowing', 335 as: 'ActorFollowing',
352 required: true, 336 required: true,
353 where: { 337 where: {
354 id 338 id: actorId
355 } 339 }
356 } 340 }
357 ] 341 ]
@@ -366,7 +350,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
366 }) 350 })
367 } 351 }
368 352
369 static listSubscriptionsForApi (id: number, start: number, count: number, sort: string) { 353 static listSubscriptionsForApi (actorId: number, start: number, count: number, sort: string) {
370 const query = { 354 const query = {
371 attributes: [], 355 attributes: [],
372 distinct: true, 356 distinct: true,
@@ -374,7 +358,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
374 limit: count, 358 limit: count,
375 order: getSort(sort), 359 order: getSort(sort),
376 where: { 360 where: {
377 actorId: id 361 actorId: actorId
378 }, 362 },
379 include: [ 363 include: [
380 { 364 {
@@ -464,6 +448,22 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
464 } 448 }
465 } 449 }
466 450
451 static updateFollowScore (inboxUrl: string, value: number, t?: Sequelize.Transaction) {
452 const query = `UPDATE "actorFollow" SET "score" = LEAST("score" + ${value}, ${ACTOR_FOLLOW_SCORE.MAX}) ` +
453 'WHERE id IN (' +
454 'SELECT "actorFollow"."id" FROM "actorFollow" ' +
455 'INNER JOIN "actor" ON "actor"."id" = "actorFollow"."actorId" ' +
456 `WHERE "actor"."inboxUrl" = '${inboxUrl}' OR "actor"."sharedInboxUrl" = '${inboxUrl}'` +
457 ')'
458
459 const options = {
460 type: Sequelize.QueryTypes.BULKUPDATE,
461 transaction: t
462 }
463
464 return ActorFollowModel.sequelize.query(query, options)
465 }
466
467 private static async createListAcceptedFollowForApiQuery ( 467 private static async createListAcceptedFollowForApiQuery (
468 type: 'followers' | 'following', 468 type: 'followers' | 'following',
469 actorIds: number[], 469 actorIds: number[],
@@ -518,24 +518,6 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
518 } 518 }
519 } 519 }
520 520
521 private static incrementScores (inboxUrls: string[], value: number, t: Sequelize.Transaction | undefined) {
522 const inboxUrlsString = inboxUrls.map(url => `'${url}'`).join(',')
523
524 const query = `UPDATE "actorFollow" SET "score" = LEAST("score" + ${value}, ${ACTOR_FOLLOW_SCORE.MAX}) ` +
525 'WHERE id IN (' +
526 'SELECT "actorFollow"."id" FROM "actorFollow" ' +
527 'INNER JOIN "actor" ON "actor"."id" = "actorFollow"."actorId" ' +
528 'WHERE "actor"."inboxUrl" IN (' + inboxUrlsString + ') OR "actor"."sharedInboxUrl" IN (' + inboxUrlsString + ')' +
529 ')'
530
531 const options = t ? {
532 type: Sequelize.QueryTypes.BULKUPDATE,
533 transaction: t
534 } : undefined
535
536 return ActorFollowModel.sequelize.query(query, options)
537 }
538
539 private static listBadActorFollows () { 521 private static listBadActorFollows () {
540 const query = { 522 const query = {
541 where: { 523 where: {
diff --git a/server/models/activitypub/actor.ts b/server/models/activitypub/actor.ts
index 12b83916e..dda57a8ba 100644
--- a/server/models/activitypub/actor.ts
+++ b/server/models/activitypub/actor.ts
@@ -219,6 +219,7 @@ export class ActorModel extends Model<ActorModel> {
219 name: 'actorId', 219 name: 'actorId',
220 allowNull: false 220 allowNull: false
221 }, 221 },
222 as: 'ActorFollowings',
222 onDelete: 'cascade' 223 onDelete: 'cascade'
223 }) 224 })
224 ActorFollowing: ActorFollowModel[] 225 ActorFollowing: ActorFollowModel[]
diff --git a/server/models/redundancy/video-redundancy.ts b/server/models/redundancy/video-redundancy.ts
index 9de4356b4..8f2ef2d9a 100644
--- a/server/models/redundancy/video-redundancy.ts
+++ b/server/models/redundancy/video-redundancy.ts
@@ -15,7 +15,7 @@ import {
15import { ActorModel } from '../activitypub/actor' 15import { ActorModel } from '../activitypub/actor'
16import { getVideoSort, throwIfNotValid } from '../utils' 16import { getVideoSort, throwIfNotValid } from '../utils'
17import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc' 17import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc'
18import { CONFIG, CONSTRAINTS_FIELDS, VIDEO_EXT_MIMETYPE } from '../../initializers' 18import { CONFIG, CONSTRAINTS_FIELDS, MIMETYPES } from '../../initializers'
19import { VideoFileModel } from '../video/video-file' 19import { VideoFileModel } from '../video/video-file'
20import { getServerActor } from '../../helpers/utils' 20import { getServerActor } from '../../helpers/utils'
21import { VideoModel } from '../video/video' 21import { VideoModel } from '../video/video'
@@ -124,7 +124,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
124 const logIdentifier = `${videoFile.Video.uuid}-${videoFile.resolution}` 124 const logIdentifier = `${videoFile.Video.uuid}-${videoFile.resolution}`
125 logger.info('Removing duplicated video file %s.', logIdentifier) 125 logger.info('Removing duplicated video file %s.', logIdentifier)
126 126
127 videoFile.Video.removeFile(videoFile) 127 videoFile.Video.removeFile(videoFile, true)
128 .catch(err => logger.error('Cannot delete %s files.', logIdentifier, { err })) 128 .catch(err => logger.error('Cannot delete %s files.', logIdentifier, { err }))
129 129
130 return undefined 130 return undefined
@@ -395,7 +395,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
395 ] 395 ]
396 } 396 }
397 397
398 return VideoRedundancyModel.find(query as any) // FIXME: typings 398 return VideoRedundancyModel.findOne(query as any) // FIXME: typings
399 .then((r: any) => ({ 399 .then((r: any) => ({
400 totalUsed: parseInt(r.totalUsed.toString(), 10), 400 totalUsed: parseInt(r.totalUsed.toString(), 10),
401 totalVideos: r.totalVideos, 401 totalVideos: r.totalVideos,
@@ -415,8 +415,8 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
415 expires: this.expiresOn.toISOString(), 415 expires: this.expiresOn.toISOString(),
416 url: { 416 url: {
417 type: 'Link', 417 type: 'Link',
418 mimeType: VIDEO_EXT_MIMETYPE[ this.VideoFile.extname ] as any, 418 mimeType: MIMETYPES.VIDEO.EXT_MIMETYPE[ this.VideoFile.extname ] as any,
419 mediaType: VIDEO_EXT_MIMETYPE[ this.VideoFile.extname ] as any, 419 mediaType: MIMETYPES.VIDEO.EXT_MIMETYPE[ this.VideoFile.extname ] as any,
420 href: this.fileUrl, 420 href: this.fileUrl,
421 height: this.VideoFile.resolution, 421 height: this.VideoFile.resolution,
422 size: this.VideoFile.size, 422 size: this.VideoFile.size,
diff --git a/server/models/utils.ts b/server/models/utils.ts
index 60b0906e8..5b4093aec 100644
--- a/server/models/utils.ts
+++ b/server/models/utils.ts
@@ -29,7 +29,11 @@ function getVideoSort (value: string, lastSort: string[] = [ 'id', 'ASC' ]) {
29 ] 29 ]
30 } 30 }
31 31
32 return [ [ field, direction ], lastSort ] 32 const firstSort = typeof field === 'string' ?
33 field.split('.').concat([ direction ]) :
34 [ field, direction ]
35
36 return [ firstSort, lastSort ]
33} 37}
34 38
35function getSortOnModel (model: any, value: string, lastSort: string[] = [ 'id', 'ASC' ]) { 39function getSortOnModel (model: any, value: string, lastSort: string[] = [ 'id', 'ASC' ]) {
diff --git a/server/models/video/video-abuse.ts b/server/models/video/video-abuse.ts
index dbb88ca45..cc47644f2 100644
--- a/server/models/video/video-abuse.ts
+++ b/server/models/video/video-abuse.ts
@@ -1,17 +1,4 @@
1import { 1import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
2 AfterCreate,
3 AllowNull,
4 BelongsTo,
5 Column,
6 CreatedAt,
7 DataType,
8 Default,
9 ForeignKey,
10 Is,
11 Model,
12 Table,
13 UpdatedAt
14} from 'sequelize-typescript'
15import { VideoAbuseObject } from '../../../shared/models/activitypub/objects' 2import { VideoAbuseObject } from '../../../shared/models/activitypub/objects'
16import { VideoAbuse } from '../../../shared/models/videos' 3import { VideoAbuse } from '../../../shared/models/videos'
17import { 4import {
@@ -19,7 +6,6 @@ import {
19 isVideoAbuseReasonValid, 6 isVideoAbuseReasonValid,
20 isVideoAbuseStateValid 7 isVideoAbuseStateValid
21} from '../../helpers/custom-validators/video-abuses' 8} from '../../helpers/custom-validators/video-abuses'
22import { Emailer } from '../../lib/emailer'
23import { AccountModel } from '../account/account' 9import { AccountModel } from '../account/account'
24import { getSort, throwIfNotValid } from '../utils' 10import { getSort, throwIfNotValid } from '../utils'
25import { VideoModel } from './video' 11import { VideoModel } from './video'
@@ -40,8 +26,9 @@ import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers'
40export class VideoAbuseModel extends Model<VideoAbuseModel> { 26export class VideoAbuseModel extends Model<VideoAbuseModel> {
41 27
42 @AllowNull(false) 28 @AllowNull(false)
29 @Default(null)
43 @Is('VideoAbuseReason', value => throwIfNotValid(value, isVideoAbuseReasonValid, 'reason')) 30 @Is('VideoAbuseReason', value => throwIfNotValid(value, isVideoAbuseReasonValid, 'reason'))
44 @Column 31 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_ABUSES.REASON.max))
45 reason: string 32 reason: string
46 33
47 @AllowNull(false) 34 @AllowNull(false)
@@ -86,11 +73,6 @@ export class VideoAbuseModel extends Model<VideoAbuseModel> {
86 }) 73 })
87 Video: VideoModel 74 Video: VideoModel
88 75
89 @AfterCreate
90 static sendEmailNotification (instance: VideoAbuseModel) {
91 return Emailer.Instance.addVideoAbuseReportJob(instance.videoId)
92 }
93
94 static loadByIdAndVideoId (id: number, videoId: number) { 76 static loadByIdAndVideoId (id: number, videoId: number) {
95 const query = { 77 const query = {
96 where: { 78 where: {
diff --git a/server/models/video/video-blacklist.ts b/server/models/video/video-blacklist.ts
index 67f7cd487..3b567e488 100644
--- a/server/models/video/video-blacklist.ts
+++ b/server/models/video/video-blacklist.ts
@@ -1,21 +1,7 @@
1import { 1import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
2 AfterCreate,
3 AfterDestroy,
4 AllowNull,
5 BelongsTo,
6 Column,
7 CreatedAt,
8 DataType,
9 ForeignKey,
10 Is,
11 Model,
12 Table,
13 UpdatedAt
14} from 'sequelize-typescript'
15import { getSortOnModel, SortType, throwIfNotValid } from '../utils' 2import { getSortOnModel, SortType, throwIfNotValid } from '../utils'
16import { VideoModel } from './video' 3import { VideoModel } from './video'
17import { isVideoBlacklistReasonValid } from '../../helpers/custom-validators/video-blacklist' 4import { isVideoBlacklistReasonValid } from '../../helpers/custom-validators/video-blacklist'
18import { Emailer } from '../../lib/emailer'
19import { VideoBlacklist } from '../../../shared/models/videos' 5import { VideoBlacklist } from '../../../shared/models/videos'
20import { CONSTRAINTS_FIELDS } from '../../initializers' 6import { CONSTRAINTS_FIELDS } from '../../initializers'
21 7
@@ -35,6 +21,10 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
35 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_BLACKLIST.REASON.max)) 21 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEO_BLACKLIST.REASON.max))
36 reason: string 22 reason: string
37 23
24 @AllowNull(false)
25 @Column
26 unfederated: boolean
27
38 @CreatedAt 28 @CreatedAt
39 createdAt: Date 29 createdAt: Date
40 30
@@ -53,16 +43,6 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
53 }) 43 })
54 Video: VideoModel 44 Video: VideoModel
55 45
56 @AfterCreate
57 static sendBlacklistEmailNotification (instance: VideoBlacklistModel) {
58 return Emailer.Instance.addVideoBlacklistReportJob(instance.videoId, instance.reason)
59 }
60
61 @AfterDestroy
62 static sendUnblacklistEmailNotification (instance: VideoBlacklistModel) {
63 return Emailer.Instance.addVideoUnblacklistReportJob(instance.videoId)
64 }
65
66 static listForApi (start: number, count: number, sort: SortType) { 46 static listForApi (start: number, count: number, sort: SortType) {
67 const query = { 47 const query = {
68 offset: start, 48 offset: start,
@@ -103,6 +83,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
103 createdAt: this.createdAt, 83 createdAt: this.createdAt,
104 updatedAt: this.updatedAt, 84 updatedAt: this.updatedAt,
105 reason: this.reason, 85 reason: this.reason,
86 unfederated: this.unfederated,
106 87
107 video: { 88 video: {
108 id: video.id, 89 id: video.id,
diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts
index f4586917e..5598d80f6 100644
--- a/server/models/video/video-channel.ts
+++ b/server/models/video/video-channel.ts
@@ -233,6 +233,27 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
233 }) 233 })
234 } 234 }
235 235
236 static listLocalsForSitemap (sort: string) {
237 const query = {
238 attributes: [ ],
239 offset: 0,
240 order: getSort(sort),
241 include: [
242 {
243 attributes: [ 'preferredUsername', 'serverId' ],
244 model: ActorModel.unscoped(),
245 where: {
246 serverId: null
247 }
248 }
249 ]
250 }
251
252 return VideoChannelModel
253 .unscoped()
254 .findAll(query)
255 }
256
236 static searchForApi (options: { 257 static searchForApi (options: {
237 actorId: number 258 actorId: number
238 search: string 259 search: string
@@ -449,4 +470,8 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
449 getDisplayName () { 470 getDisplayName () {
450 return this.name 471 return this.name
451 } 472 }
473
474 isOutdated () {
475 return this.Actor.isOutdated()
476 }
452} 477}
diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts
index dd6d08139..cf6278da7 100644
--- a/server/models/video/video-comment.ts
+++ b/server/models/video/video-comment.ts
@@ -18,7 +18,7 @@ import { ActivityTagObject } from '../../../shared/models/activitypub/objects/co
18import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object' 18import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object'
19import { VideoComment } from '../../../shared/models/videos/video-comment.model' 19import { VideoComment } from '../../../shared/models/videos/video-comment.model'
20import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 20import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
21import { CONSTRAINTS_FIELDS } from '../../initializers' 21import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers'
22import { sendDeleteVideoComment } from '../../lib/activitypub/send' 22import { sendDeleteVideoComment } from '../../lib/activitypub/send'
23import { AccountModel } from '../account/account' 23import { AccountModel } from '../account/account'
24import { ActorModel } from '../activitypub/actor' 24import { ActorModel } from '../activitypub/actor'
@@ -29,6 +29,9 @@ import { VideoModel } from './video'
29import { VideoChannelModel } from './video-channel' 29import { VideoChannelModel } from './video-channel'
30import { getServerActor } from '../../helpers/utils' 30import { getServerActor } from '../../helpers/utils'
31import { UserModel } from '../account/user' 31import { UserModel } from '../account/user'
32import { actorNameAlphabet } from '../../helpers/custom-validators/activitypub/actor'
33import { regexpCapture } from '../../helpers/regexp'
34import { uniq } from 'lodash'
32 35
33enum ScopeNames { 36enum ScopeNames {
34 WITH_ACCOUNT = 'WITH_ACCOUNT', 37 WITH_ACCOUNT = 'WITH_ACCOUNT',
@@ -370,9 +373,11 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
370 id: { 373 id: {
371 [ Sequelize.Op.in ]: Sequelize.literal('(' + 374 [ Sequelize.Op.in ]: Sequelize.literal('(' +
372 'WITH RECURSIVE children (id, "inReplyToCommentId") AS ( ' + 375 'WITH RECURSIVE children (id, "inReplyToCommentId") AS ( ' +
373 'SELECT id, "inReplyToCommentId" FROM "videoComment" WHERE id = ' + comment.id + ' UNION ' + 376 `SELECT id, "inReplyToCommentId" FROM "videoComment" WHERE id = ${comment.id} ` +
374 'SELECT p.id, p."inReplyToCommentId" from "videoComment" p ' + 377 'UNION ' +
375 'INNER JOIN children c ON c."inReplyToCommentId" = p.id) ' + 378 'SELECT "parent"."id", "parent"."inReplyToCommentId" FROM "videoComment" "parent" ' +
379 'INNER JOIN "children" ON "children"."inReplyToCommentId" = "parent"."id"' +
380 ') ' +
376 'SELECT id FROM children' + 381 'SELECT id FROM children' +
377 ')'), 382 ')'),
378 [ Sequelize.Op.ne ]: comment.id 383 [ Sequelize.Op.ne ]: comment.id
@@ -448,6 +453,10 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
448 } 453 }
449 } 454 }
450 455
456 getCommentStaticPath () {
457 return this.Video.getWatchStaticPath() + ';threadId=' + this.getThreadId()
458 }
459
451 getThreadId (): number { 460 getThreadId (): number {
452 return this.originCommentId || this.id 461 return this.originCommentId || this.id
453 } 462 }
@@ -456,6 +465,34 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
456 return this.Account.isOwned() 465 return this.Account.isOwned()
457 } 466 }
458 467
468 extractMentions () {
469 if (!this.text) return []
470
471 const localMention = `@(${actorNameAlphabet}+)`
472 const remoteMention = `${localMention}@${CONFIG.WEBSERVER.HOST}`
473
474 const remoteMentionsRegex = new RegExp(' ' + remoteMention + ' ', 'g')
475 const localMentionsRegex = new RegExp(' ' + localMention + ' ', 'g')
476 const firstMentionRegex = new RegExp('^(?:(?:' + remoteMention + ')|(?:' + localMention + ')) ', 'g')
477 const endMentionRegex = new RegExp(' (?:(?:' + remoteMention + ')|(?:' + localMention + '))$', 'g')
478
479 return uniq(
480 [].concat(
481 regexpCapture(this.text, remoteMentionsRegex)
482 .map(([ , username ]) => username),
483
484 regexpCapture(this.text, localMentionsRegex)
485 .map(([ , username ]) => username),
486
487 regexpCapture(this.text, firstMentionRegex)
488 .map(([ , username1, username2 ]) => username1 || username2),
489
490 regexpCapture(this.text, endMentionRegex)
491 .map(([ , username1, username2 ]) => username1 || username2)
492 )
493 )
494 }
495
459 toFormattedJSON () { 496 toFormattedJSON () {
460 return { 497 return {
461 id: this.id, 498 id: this.id,
diff --git a/server/models/video/video-file.ts b/server/models/video/video-file.ts
index adebdf0c7..1f1b76c1e 100644
--- a/server/models/video/video-file.ts
+++ b/server/models/video/video-file.ts
@@ -1,4 +1,3 @@
1import { values } from 'lodash'
2import { 1import {
3 AllowNull, 2 AllowNull,
4 BelongsTo, 3 BelongsTo,
@@ -14,12 +13,12 @@ import {
14 UpdatedAt 13 UpdatedAt
15} from 'sequelize-typescript' 14} from 'sequelize-typescript'
16import { 15import {
16 isVideoFileExtnameValid,
17 isVideoFileInfoHashValid, 17 isVideoFileInfoHashValid,
18 isVideoFileResolutionValid, 18 isVideoFileResolutionValid,
19 isVideoFileSizeValid, 19 isVideoFileSizeValid,
20 isVideoFPSResolutionValid 20 isVideoFPSResolutionValid
21} from '../../helpers/custom-validators/videos' 21} from '../../helpers/custom-validators/videos'
22import { CONSTRAINTS_FIELDS } from '../../initializers'
23import { throwIfNotValid } from '../utils' 22import { throwIfNotValid } from '../utils'
24import { VideoModel } from './video' 23import { VideoModel } from './video'
25import * as Sequelize from 'sequelize' 24import * as Sequelize from 'sequelize'
@@ -58,7 +57,8 @@ export class VideoFileModel extends Model<VideoFileModel> {
58 size: number 57 size: number
59 58
60 @AllowNull(false) 59 @AllowNull(false)
61 @Column(DataType.ENUM(values(CONSTRAINTS_FIELDS.VIDEOS.EXTNAME))) 60 @Is('VideoFileExtname', value => throwIfNotValid(value, isVideoFileExtnameValid, 'extname'))
61 @Column
62 extname: string 62 extname: string
63 63
64 @AllowNull(false) 64 @AllowNull(false)
@@ -120,6 +120,26 @@ export class VideoFileModel extends Model<VideoFileModel> {
120 return VideoFileModel.findById(id, options) 120 return VideoFileModel.findById(id, options)
121 } 121 }
122 122
123 static async getStats () {
124 let totalLocalVideoFilesSize = await VideoFileModel.sum('size', {
125 include: [
126 {
127 attributes: [],
128 model: VideoModel.unscoped(),
129 where: {
130 remote: false
131 }
132 }
133 ]
134 } as any)
135 // Sequelize could return null...
136 if (!totalLocalVideoFilesSize) totalLocalVideoFilesSize = 0
137
138 return {
139 totalLocalVideoFilesSize
140 }
141 }
142
123 hasSameUniqueKeysThan (other: VideoFileModel) { 143 hasSameUniqueKeysThan (other: VideoFileModel) {
124 return this.fps === other.fps && 144 return this.fps === other.fps &&
125 this.resolution === other.resolution && 145 this.resolution === other.resolution &&
diff --git a/server/models/video/video-format-utils.ts b/server/models/video/video-format-utils.ts
index e3f8d525b..de0747f22 100644
--- a/server/models/video/video-format-utils.ts
+++ b/server/models/video/video-format-utils.ts
@@ -2,7 +2,7 @@ import { Video, VideoDetails, VideoFile } from '../../../shared/models/videos'
2import { VideoModel } from './video' 2import { VideoModel } from './video'
3import { VideoFileModel } from './video-file' 3import { VideoFileModel } from './video-file'
4import { ActivityUrlObject, VideoTorrentObject } from '../../../shared/models/activitypub/objects' 4import { ActivityUrlObject, VideoTorrentObject } from '../../../shared/models/activitypub/objects'
5import { CONFIG, THUMBNAILS_SIZE, VIDEO_EXT_MIMETYPE } from '../../initializers' 5import { CONFIG, MIMETYPES, THUMBNAILS_SIZE } from '../../initializers'
6import { VideoCaptionModel } from './video-caption' 6import { VideoCaptionModel } from './video-caption'
7import { 7import {
8 getVideoCommentsActivityPubUrl, 8 getVideoCommentsActivityPubUrl,
@@ -207,8 +207,8 @@ function videoModelToActivityPubObject (video: VideoModel): VideoTorrentObject {
207 for (const file of video.VideoFiles) { 207 for (const file of video.VideoFiles) {
208 url.push({ 208 url.push({
209 type: 'Link', 209 type: 'Link',
210 mimeType: VIDEO_EXT_MIMETYPE[ file.extname ] as any, 210 mimeType: MIMETYPES.VIDEO.EXT_MIMETYPE[ file.extname ] as any,
211 mediaType: VIDEO_EXT_MIMETYPE[ file.extname ] as any, 211 mediaType: MIMETYPES.VIDEO.EXT_MIMETYPE[ file.extname ] as any,
212 href: video.getVideoFileUrl(file, baseUrlHttp), 212 href: video.getVideoFileUrl(file, baseUrlHttp),
213 height: file.resolution, 213 height: file.resolution,
214 size: file.size, 214 size: file.size,
diff --git a/server/models/video/video-import.ts b/server/models/video/video-import.ts
index 8d442b3f8..c723e57c0 100644
--- a/server/models/video/video-import.ts
+++ b/server/models/video/video-import.ts
@@ -144,6 +144,10 @@ export class VideoImportModel extends Model<VideoImportModel> {
144 }) 144 })
145 } 145 }
146 146
147 getTargetIdentifier () {
148 return this.targetUrl || this.magnetUri || this.torrentName
149 }
150
147 toFormattedJSON (): VideoImport { 151 toFormattedJSON (): VideoImport {
148 const videoFormatOptions = { 152 const videoFormatOptions = {
149 completeDescription: true, 153 completeDescription: true,
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 0f18d9f0c..80a6c7832 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -94,6 +94,7 @@ import {
94import * as validator from 'validator' 94import * as validator from 'validator'
95import { UserVideoHistoryModel } from '../account/user-video-history' 95import { UserVideoHistoryModel } from '../account/user-video-history'
96import { UserModel } from '../account/user' 96import { UserModel } from '../account/user'
97import { VideoImportModel } from './video-import'
97 98
98// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation 99// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
99const indexes: Sequelize.DefineIndexesOptions[] = [ 100const indexes: Sequelize.DefineIndexesOptions[] = [
@@ -102,17 +103,45 @@ const indexes: Sequelize.DefineIndexesOptions[] = [
102 { fields: [ 'createdAt' ] }, 103 { fields: [ 'createdAt' ] },
103 { fields: [ 'publishedAt' ] }, 104 { fields: [ 'publishedAt' ] },
104 { fields: [ 'duration' ] }, 105 { fields: [ 'duration' ] },
105 { fields: [ 'category' ] },
106 { fields: [ 'licence' ] },
107 { fields: [ 'nsfw' ] },
108 { fields: [ 'language' ] },
109 { fields: [ 'waitTranscoding' ] },
110 { fields: [ 'state' ] },
111 { fields: [ 'remote' ] },
112 { fields: [ 'views' ] }, 106 { fields: [ 'views' ] },
113 { fields: [ 'likes' ] },
114 { fields: [ 'channelId' ] }, 107 { fields: [ 'channelId' ] },
115 { 108 {
109 fields: [ 'category' ], // We don't care videos with an unknown category
110 where: {
111 category: {
112 [Sequelize.Op.ne]: null
113 }
114 }
115 },
116 {
117 fields: [ 'licence' ], // We don't care videos with an unknown licence
118 where: {
119 licence: {
120 [Sequelize.Op.ne]: null
121 }
122 }
123 },
124 {
125 fields: [ 'language' ], // We don't care videos with an unknown language
126 where: {
127 language: {
128 [Sequelize.Op.ne]: null
129 }
130 }
131 },
132 {
133 fields: [ 'nsfw' ], // Most of the videos are not NSFW
134 where: {
135 nsfw: true
136 }
137 },
138 {
139 fields: [ 'remote' ], // Only index local videos
140 where: {
141 remote: false
142 }
143 },
144 {
116 fields: [ 'uuid' ], 145 fields: [ 'uuid' ],
117 unique: true 146 unique: true
118 }, 147 },
@@ -140,7 +169,7 @@ type ForAPIOptions = {
140 169
141type AvailableForListIDsOptions = { 170type AvailableForListIDsOptions = {
142 serverAccountId: number 171 serverAccountId: number
143 actorId: number 172 followerActorId: number
144 includeLocalVideos: boolean 173 includeLocalVideos: boolean
145 filter?: VideoFilter 174 filter?: VideoFilter
146 categoryOneOf?: number[] 175 categoryOneOf?: number[]
@@ -153,7 +182,8 @@ type AvailableForListIDsOptions = {
153 accountId?: number 182 accountId?: number
154 videoChannelId?: number 183 videoChannelId?: number
155 trendingDays?: number 184 trendingDays?: number
156 user?: UserModel 185 user?: UserModel,
186 historyOfUser?: UserModel
157} 187}
158 188
159@Scopes({ 189@Scopes({
@@ -315,7 +345,7 @@ type AvailableForListIDsOptions = {
315 query.include.push(videoChannelInclude) 345 query.include.push(videoChannelInclude)
316 } 346 }
317 347
318 if (options.actorId) { 348 if (options.followerActorId) {
319 let localVideosReq = '' 349 let localVideosReq = ''
320 if (options.includeLocalVideos === true) { 350 if (options.includeLocalVideos === true) {
321 localVideosReq = ' UNION ALL ' + 351 localVideosReq = ' UNION ALL ' +
@@ -327,7 +357,7 @@ type AvailableForListIDsOptions = {
327 } 357 }
328 358
329 // Force actorId to be a number to avoid SQL injections 359 // Force actorId to be a number to avoid SQL injections
330 const actorIdNumber = parseInt(options.actorId.toString(), 10) 360 const actorIdNumber = parseInt(options.followerActorId.toString(), 10)
331 query.where[ 'id' ][ Sequelize.Op.and ].push({ 361 query.where[ 'id' ][ Sequelize.Op.and ].push({
332 [ Sequelize.Op.in ]: Sequelize.literal( 362 [ Sequelize.Op.in ]: Sequelize.literal(
333 '(' + 363 '(' +
@@ -416,6 +446,21 @@ type AvailableForListIDsOptions = {
416 query.subQuery = false 446 query.subQuery = false
417 } 447 }
418 448
449 if (options.historyOfUser) {
450 query.include.push({
451 model: UserVideoHistoryModel,
452 required: true,
453 where: {
454 userId: options.historyOfUser.id
455 }
456 })
457
458 // Even if the relation is n:m, we know that a user only have 0..1 video history
459 // So we won't have multiple rows for the same video
460 // Without this, we would not be able to sort on "updatedAt" column of UserVideoHistoryModel
461 query.subQuery = false
462 }
463
419 return query 464 return query
420 }, 465 },
421 [ ScopeNames.WITH_ACCOUNT_DETAILS ]: { 466 [ ScopeNames.WITH_ACCOUNT_DETAILS ]: {
@@ -741,6 +786,15 @@ export class VideoModel extends Model<VideoModel> {
741 }) 786 })
742 VideoBlacklist: VideoBlacklistModel 787 VideoBlacklist: VideoBlacklistModel
743 788
789 @HasOne(() => VideoImportModel, {
790 foreignKey: {
791 name: 'videoId',
792 allowNull: true
793 },
794 onDelete: 'set null'
795 })
796 VideoImport: VideoImportModel
797
744 @HasMany(() => VideoCaptionModel, { 798 @HasMany(() => VideoCaptionModel, {
745 foreignKey: { 799 foreignKey: {
746 name: 'videoId', 800 name: 'videoId',
@@ -985,9 +1039,10 @@ export class VideoModel extends Model<VideoModel> {
985 filter?: VideoFilter, 1039 filter?: VideoFilter,
986 accountId?: number, 1040 accountId?: number,
987 videoChannelId?: number, 1041 videoChannelId?: number,
988 actorId?: number 1042 followerActorId?: number
989 trendingDays?: number, 1043 trendingDays?: number,
990 user?: UserModel 1044 user?: UserModel,
1045 historyOfUser?: UserModel
991 }, countVideos = true) { 1046 }, countVideos = true) {
992 if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) { 1047 if (options.filter && options.filter === 'all-local' && !options.user.hasRight(UserRight.SEE_ALL_VIDEOS)) {
993 throw new Error('Try to filter all-local but no user has not the see all videos right') 1048 throw new Error('Try to filter all-local but no user has not the see all videos right')
@@ -1008,11 +1063,11 @@ export class VideoModel extends Model<VideoModel> {
1008 1063
1009 const serverActor = await getServerActor() 1064 const serverActor = await getServerActor()
1010 1065
1011 // actorId === null has a meaning, so just check undefined 1066 // followerActorId === null has a meaning, so just check undefined
1012 const actorId = options.actorId !== undefined ? options.actorId : serverActor.id 1067 const followerActorId = options.followerActorId !== undefined ? options.followerActorId : serverActor.id
1013 1068
1014 const queryOptions = { 1069 const queryOptions = {
1015 actorId, 1070 followerActorId,
1016 serverAccountId: serverActor.Account.id, 1071 serverAccountId: serverActor.Account.id,
1017 nsfw: options.nsfw, 1072 nsfw: options.nsfw,
1018 categoryOneOf: options.categoryOneOf, 1073 categoryOneOf: options.categoryOneOf,
@@ -1026,6 +1081,7 @@ export class VideoModel extends Model<VideoModel> {
1026 videoChannelId: options.videoChannelId, 1081 videoChannelId: options.videoChannelId,
1027 includeLocalVideos: options.includeLocalVideos, 1082 includeLocalVideos: options.includeLocalVideos,
1028 user: options.user, 1083 user: options.user,
1084 historyOfUser: options.historyOfUser,
1029 trendingDays 1085 trendingDays
1030 } 1086 }
1031 1087
@@ -1118,7 +1174,7 @@ export class VideoModel extends Model<VideoModel> {
1118 1174
1119 const serverActor = await getServerActor() 1175 const serverActor = await getServerActor()
1120 const queryOptions = { 1176 const queryOptions = {
1121 actorId: serverActor.id, 1177 followerActorId: serverActor.id,
1122 serverAccountId: serverActor.Account.id, 1178 serverAccountId: serverActor.Account.id,
1123 includeLocalVideos: options.includeLocalVideos, 1179 includeLocalVideos: options.includeLocalVideos,
1124 nsfw: options.nsfw, 1180 nsfw: options.nsfw,
@@ -1273,11 +1329,11 @@ export class VideoModel extends Model<VideoModel> {
1273 // threshold corresponds to how many video the field should have to be returned 1329 // threshold corresponds to how many video the field should have to be returned
1274 static async getRandomFieldSamples (field: 'category' | 'channelId', threshold: number, count: number) { 1330 static async getRandomFieldSamples (field: 'category' | 'channelId', threshold: number, count: number) {
1275 const serverActor = await getServerActor() 1331 const serverActor = await getServerActor()
1276 const actorId = serverActor.id 1332 const followerActorId = serverActor.id
1277 1333
1278 const scopeOptions: AvailableForListIDsOptions = { 1334 const scopeOptions: AvailableForListIDsOptions = {
1279 serverAccountId: serverActor.Account.id, 1335 serverAccountId: serverActor.Account.id,
1280 actorId, 1336 followerActorId,
1281 includeLocalVideos: true 1337 includeLocalVideos: true
1282 } 1338 }
1283 1339
@@ -1341,7 +1397,7 @@ export class VideoModel extends Model<VideoModel> {
1341 } 1397 }
1342 1398
1343 const [ count, rowsId ] = await Promise.all([ 1399 const [ count, rowsId ] = await Promise.all([
1344 countVideos ? VideoModel.scope(countScope).count(countQuery) : Promise.resolve(undefined), 1400 countVideos ? VideoModel.scope(countScope).count(countQuery) : Promise.resolve<number>(undefined),
1345 VideoModel.scope(idsScope).findAll(query) 1401 VideoModel.scope(idsScope).findAll(query)
1346 ]) 1402 ])
1347 const ids = rowsId.map(r => r.id) 1403 const ids = rowsId.map(r => r.id)
@@ -1481,6 +1537,10 @@ export class VideoModel extends Model<VideoModel> {
1481 videoFile.infoHash = parsedTorrent.infoHash 1537 videoFile.infoHash = parsedTorrent.infoHash
1482 } 1538 }
1483 1539
1540 getWatchStaticPath () {
1541 return '/videos/watch/' + this.uuid
1542 }
1543
1484 getEmbedStaticPath () { 1544 getEmbedStaticPath () {
1485 return '/videos/embed/' + this.uuid 1545 return '/videos/embed/' + this.uuid
1486 } 1546 }
@@ -1538,8 +1598,10 @@ export class VideoModel extends Model<VideoModel> {
1538 .catch(err => logger.warn('Cannot delete preview %s.', previewPath, { err })) 1598 .catch(err => logger.warn('Cannot delete preview %s.', previewPath, { err }))
1539 } 1599 }
1540 1600
1541 removeFile (videoFile: VideoFileModel) { 1601 removeFile (videoFile: VideoFileModel, isRedundancy = false) {
1542 const filePath = join(CONFIG.STORAGE.VIDEOS_DIR, this.getVideoFilename(videoFile)) 1602 const baseDir = isRedundancy ? CONFIG.STORAGE.REDUNDANCY_DIR : CONFIG.STORAGE.VIDEOS_DIR
1603
1604 const filePath = join(baseDir, this.getVideoFilename(videoFile))
1543 return remove(filePath) 1605 return remove(filePath)
1544 .catch(err => logger.warn('Cannot delete file %s.', filePath, { err })) 1606 .catch(err => logger.warn('Cannot delete file %s.', filePath, { err }))
1545 } 1607 }
@@ -1617,6 +1679,10 @@ export class VideoModel extends Model<VideoModel> {
1617 return baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename(videoFile) 1679 return baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename(videoFile)
1618 } 1680 }
1619 1681
1682 getVideoRedundancyUrl (videoFile: VideoFileModel, baseUrlHttp: string) {
1683 return baseUrlHttp + STATIC_PATHS.REDUNDANCY + this.getVideoFilename(videoFile)
1684 }
1685
1620 getVideoFileDownloadUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 1686 getVideoFileDownloadUrl (videoFile: VideoFileModel, baseUrlHttp: string) {
1621 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.VIDEOS + this.getVideoFilename(videoFile) 1687 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.VIDEOS + this.getVideoFilename(videoFile)
1622 } 1688 }
diff --git a/server/tests/api/activitypub/client.ts b/server/tests/api/activitypub/client.ts
index ea0682634..6d90d8643 100644
--- a/server/tests/api/activitypub/client.ts
+++ b/server/tests/api/activitypub/client.ts
@@ -8,10 +8,10 @@ import {
8 flushTests, 8 flushTests,
9 killallServers, 9 killallServers,
10 makeActivityPubGetRequest, 10 makeActivityPubGetRequest,
11 runServer,
12 ServerInfo, 11 ServerInfo,
13 setAccessTokensToServers, uploadVideo 12 setAccessTokensToServers,
14} from '../../utils' 13 uploadVideo
14} from '../../../../shared/utils'
15 15
16const expect = chai.expect 16const expect = chai.expect
17 17
diff --git a/server/tests/api/activitypub/fetch.ts b/server/tests/api/activitypub/fetch.ts
index a42c606c6..03609c1a9 100644
--- a/server/tests/api/activitypub/fetch.ts
+++ b/server/tests/api/activitypub/fetch.ts
@@ -11,12 +11,13 @@ import {
11 killallServers, 11 killallServers,
12 ServerInfo, 12 ServerInfo,
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 setActorField,
15 setVideoField,
14 uploadVideo, 16 uploadVideo,
15 userLogin 17 userLogin,
16} from '../../utils' 18 waitJobs
19} from '../../../../shared/utils'
17import * as chai from 'chai' 20import * as chai from 'chai'
18import { setActorField, setVideoField } from '../../utils/miscs/sql'
19import { waitJobs } from '../../utils/server/jobs'
20import { Video } from '../../../../shared/models/videos' 21import { Video } from '../../../../shared/models/videos'
21 22
22const expect = chai.expect 23const expect = chai.expect
diff --git a/server/tests/api/activitypub/helpers.ts b/server/tests/api/activitypub/helpers.ts
index 610846247..ac6e755c3 100644
--- a/server/tests/api/activitypub/helpers.ts
+++ b/server/tests/api/activitypub/helpers.ts
@@ -2,7 +2,7 @@
2 2
3import 'mocha' 3import 'mocha'
4import { expect } from 'chai' 4import { expect } from 'chai'
5import { buildRequestStub } from '../../utils' 5import { buildRequestStub } from '../../../../shared/utils/miscs/stubs'
6import { isHTTPSignatureVerified, isJsonLDSignatureVerified, parseHTTPSignature } from '../../../helpers/peertube-crypto' 6import { isHTTPSignatureVerified, isJsonLDSignatureVerified, parseHTTPSignature } from '../../../helpers/peertube-crypto'
7import { cloneDeep } from 'lodash' 7import { cloneDeep } from 'lodash'
8import { buildSignedActivity } from '../../../helpers/activitypub' 8import { buildSignedActivity } from '../../../helpers/activitypub'
@@ -91,7 +91,7 @@ describe('Test activity pub helpers', function () {
91 req.headers = mastodonObject.headers 91 req.headers = mastodonObject.headers
92 req.headers.signature = 'Signature ' + req.headers.signature 92 req.headers.signature = 'Signature ' + req.headers.signature
93 93
94 const parsed = parseHTTPSignature(req, 3600 * 365 * 3) 94 const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
95 const publicKey = require('./json/mastodon/public-key.json').publicKey 95 const publicKey = require('./json/mastodon/public-key.json').publicKey
96 96
97 const actor = { publicKey } 97 const actor = { publicKey }
@@ -110,7 +110,7 @@ describe('Test activity pub helpers', function () {
110 req.headers = mastodonObject.headers 110 req.headers = mastodonObject.headers
111 req.headers.signature = 'Signature ' + req.headers.signature 111 req.headers.signature = 'Signature ' + req.headers.signature
112 112
113 const parsed = parseHTTPSignature(req, 3600 * 365 * 3) 113 const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
114 const publicKey = require('./json/mastodon/bad-public-key.json').publicKey 114 const publicKey = require('./json/mastodon/bad-public-key.json').publicKey
115 115
116 const actor = { publicKey } 116 const actor = { publicKey }
@@ -150,7 +150,7 @@ describe('Test activity pub helpers', function () {
150 150
151 let errored = false 151 let errored = false
152 try { 152 try {
153 parseHTTPSignature(req, 3600 * 365 * 3) 153 parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
154 } catch { 154 } catch {
155 errored = true 155 errored = true
156 } 156 }
@@ -168,7 +168,7 @@ describe('Test activity pub helpers', function () {
168 req.headers = mastodonObject.headers 168 req.headers = mastodonObject.headers
169 req.headers.signature = 'Signature ' + req.headers.signature 169 req.headers.signature = 'Signature ' + req.headers.signature
170 170
171 const parsed = parseHTTPSignature(req, 3600 * 365 * 3) 171 const parsed = parseHTTPSignature(req, 3600 * 1000 * 365 * 10)
172 const publicKey = require('./json/mastodon/public-key.json').publicKey 172 const publicKey = require('./json/mastodon/public-key.json').publicKey
173 173
174 const actor = { publicKey } 174 const actor = { publicKey }
diff --git a/server/tests/api/activitypub/refresher.ts b/server/tests/api/activitypub/refresher.ts
index 67e04f79e..62ad8a0b5 100644
--- a/server/tests/api/activitypub/refresher.ts
+++ b/server/tests/api/activitypub/refresher.ts
@@ -1,10 +1,19 @@
1/* tslint:disable:no-unused-expression */ 1/* tslint:disable:no-unused-expression */
2 2
3import 'mocha' 3import 'mocha'
4import { doubleFollow, getVideo, reRunServer } from '../../utils' 4import {
5import { flushAndRunMultipleServers, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo, wait } from '../../utils/index' 5 doubleFollow,
6import { waitJobs } from '../../utils/server/jobs' 6 flushAndRunMultipleServers,
7import { setVideoField } from '../../utils/miscs/sql' 7 getVideo,
8 killallServers,
9 reRunServer,
10 ServerInfo,
11 setAccessTokensToServers,
12 uploadVideo,
13 wait,
14 setVideoField,
15 waitJobs
16} from '../../../../shared/utils'
8 17
9describe('Test AP refresher', function () { 18describe('Test AP refresher', function () {
10 let servers: ServerInfo[] = [] 19 let servers: ServerInfo[] = []
@@ -13,7 +22,7 @@ describe('Test AP refresher', function () {
13 let videoUUID3: string 22 let videoUUID3: string
14 23
15 before(async function () { 24 before(async function () {
16 this.timeout(30000) 25 this.timeout(60000)
17 26
18 servers = await flushAndRunMultipleServers(2) 27 servers = await flushAndRunMultipleServers(2)
19 28
diff --git a/server/tests/api/activitypub/security.ts b/server/tests/api/activitypub/security.ts
index 7349749f1..342ae0fa1 100644
--- a/server/tests/api/activitypub/security.ts
+++ b/server/tests/api/activitypub/security.ts
@@ -2,13 +2,19 @@
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { flushAndRunMultipleServers, flushTests, killallServers, ServerInfo } from '../../utils' 5import {
6 flushAndRunMultipleServers,
7 flushTests,
8 killallServers,
9 makeFollowRequest,
10 makePOSTAPRequest,
11 ServerInfo,
12 setActorField
13} from '../../../../shared/utils'
6import { HTTP_SIGNATURE } from '../../../initializers' 14import { HTTP_SIGNATURE } from '../../../initializers'
7import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils' 15import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils'
8import * as chai from 'chai' 16import * as chai from 'chai'
9import { setActorField } from '../../utils/miscs/sql'
10import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub' 17import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub'
11import { makeFollowRequest, makePOSTAPRequest } from '../../utils/requests/activitypub'
12 18
13const expect = chai.expect 19const expect = chai.expect
14 20
diff --git a/server/tests/api/check-params/accounts.ts b/server/tests/api/check-params/accounts.ts
index 9e0b1e35c..68f9519c6 100644
--- a/server/tests/api/check-params/accounts.ts
+++ b/server/tests/api/check-params/accounts.ts
@@ -2,11 +2,15 @@
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { flushTests, killallServers, runServer, ServerInfo } from '../../utils' 5import { flushTests, killallServers, runServer, ServerInfo } from '../../../../shared/utils'
6import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 6import {
7import { getAccount } from '../../utils/users/accounts' 7 checkBadCountPagination,
8 8 checkBadSortPagination,
9describe('Test users API validators', function () { 9 checkBadStartPagination
10} from '../../../../shared/utils/requests/check-api-params'
11import { getAccount } from '../../../../shared/utils/users/accounts'
12
13describe('Test accounts API validators', function () {
10 const path = '/api/v1/accounts/' 14 const path = '/api/v1/accounts/'
11 let server: ServerInfo 15 let server: ServerInfo
12 16
diff --git a/server/tests/api/check-params/blocklist.ts b/server/tests/api/check-params/blocklist.ts
index c745ac975..c20453c16 100644
--- a/server/tests/api/check-params/blocklist.ts
+++ b/server/tests/api/check-params/blocklist.ts
@@ -13,8 +13,12 @@ import {
13 makePostBodyRequest, 13 makePostBodyRequest,
14 ServerInfo, 14 ServerInfo,
15 setAccessTokensToServers, userLogin 15 setAccessTokensToServers, userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 17import {
18 checkBadCountPagination,
19 checkBadSortPagination,
20 checkBadStartPagination
21} from '../../../../shared/utils/requests/check-api-params'
18 22
19describe('Test blocklist API validators', function () { 23describe('Test blocklist API validators', function () {
20 let servers: ServerInfo[] 24 let servers: ServerInfo[]
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts
index d807f910b..4038ecbf0 100644
--- a/server/tests/api/check-params/config.ts
+++ b/server/tests/api/check-params/config.ts
@@ -7,7 +7,7 @@ import { CustomConfig } from '../../../../shared/models/server/custom-config.mod
7import { 7import {
8 createUser, flushTests, killallServers, makeDeleteRequest, makeGetRequest, makePutBodyRequest, runServer, ServerInfo, 8 createUser, flushTests, killallServers, makeDeleteRequest, makeGetRequest, makePutBodyRequest, runServer, ServerInfo,
9 setAccessTokensToServers, userLogin, immutableAssign 9 setAccessTokensToServers, userLogin, immutableAssign
10} from '../../utils' 10} from '../../../../shared/utils'
11 11
12describe('Test config API validators', function () { 12describe('Test config API validators', function () {
13 const path = '/api/v1/config/custom' 13 const path = '/api/v1/config/custom'
@@ -48,12 +48,16 @@ describe('Test config API validators', function () {
48 admin: { 48 admin: {
49 email: 'superadmin1@example.com' 49 email: 'superadmin1@example.com'
50 }, 50 },
51 contactForm: {
52 enabled: false
53 },
51 user: { 54 user: {
52 videoQuota: 5242881, 55 videoQuota: 5242881,
53 videoQuotaDaily: 318742 56 videoQuotaDaily: 318742
54 }, 57 },
55 transcoding: { 58 transcoding: {
56 enabled: true, 59 enabled: true,
60 allowAdditionalExtensions: true,
57 threads: 1, 61 threads: 1,
58 resolutions: { 62 resolutions: {
59 '240p': false, 63 '240p': false,
diff --git a/server/tests/api/check-params/contact-form.ts b/server/tests/api/check-params/contact-form.ts
new file mode 100644
index 000000000..c7e014b1f
--- /dev/null
+++ b/server/tests/api/check-params/contact-form.ts
@@ -0,0 +1,96 @@
1/* tslint:disable:no-unused-expression */
2
3import 'mocha'
4
5import {
6 flushTests,
7 immutableAssign,
8 killallServers,
9 reRunServer,
10 runServer,
11 ServerInfo,
12 setAccessTokensToServers
13} from '../../../../shared/utils'
14import {
15 checkBadCountPagination,
16 checkBadSortPagination,
17 checkBadStartPagination
18} from '../../../../shared/utils/requests/check-api-params'
19import { getAccount } from '../../../../shared/utils/users/accounts'
20import { sendContactForm } from '../../../../shared/utils/server/contact-form'
21import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
22
23describe('Test contact form API validators', function () {
24 let server: ServerInfo
25 const emails: object[] = []
26 const defaultBody = {
27 fromName: 'super name',
28 fromEmail: 'toto@example.com',
29 body: 'Hello, how are you?'
30 }
31
32 // ---------------------------------------------------------------
33
34 before(async function () {
35 this.timeout(60000)
36
37 await flushTests()
38 await MockSmtpServer.Instance.collectEmails(emails)
39
40 // Email is disabled
41 server = await runServer(1)
42 })
43
44 it('Should not accept a contact form if emails are disabled', async function () {
45 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 409 }))
46 })
47
48 it('Should not accept a contact form if it is disabled in the configuration', async function () {
49 this.timeout(10000)
50
51 killallServers([ server ])
52
53 // Contact form is disabled
54 await reRunServer(server, { smtp: { hostname: 'localhost' }, contact_form: { enabled: false } })
55 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 409 }))
56 })
57
58 it('Should not accept a contact form if from email is invalid', async function () {
59 this.timeout(10000)
60
61 killallServers([ server ])
62
63 // Email & contact form enabled
64 await reRunServer(server, { smtp: { hostname: 'localhost' } })
65
66 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: 'badEmail' }))
67 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: 'badEmail@' }))
68 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromEmail: undefined }))
69 })
70
71 it('Should not accept a contact form if from name is invalid', async function () {
72 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: 'name'.repeat(100) }))
73 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: '' }))
74 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, fromName: undefined }))
75 })
76
77 it('Should not accept a contact form if body is invalid', async function () {
78 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: 'body'.repeat(5000) }))
79 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: 'a' }))
80 await sendContactForm(immutableAssign(defaultBody, { url: server.url, expectedStatus: 400, body: undefined }))
81 })
82
83 it('Should accept a contact form with the correct parameters', async function () {
84 await sendContactForm(immutableAssign(defaultBody, { url: server.url }))
85 })
86
87 after(async function () {
88 MockSmtpServer.Instance.kill()
89 killallServers([ server ])
90
91 // Keep the logs if the test failed
92 if (this['ok']) {
93 await flushTests()
94 }
95 })
96})
diff --git a/server/tests/api/check-params/follows.ts b/server/tests/api/check-params/follows.ts
index cdc95c81a..2ad1575a3 100644
--- a/server/tests/api/check-params/follows.ts
+++ b/server/tests/api/check-params/follows.ts
@@ -5,8 +5,12 @@ import 'mocha'
5import { 5import {
6 createUser, flushTests, killallServers, makeDeleteRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers, 6 createUser, flushTests, killallServers, makeDeleteRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers,
7 userLogin 7 userLogin
8} from '../../utils' 8} from '../../../../shared/utils'
9import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 9import {
10 checkBadCountPagination,
11 checkBadSortPagination,
12 checkBadStartPagination
13} from '../../../../shared/utils/requests/check-api-params'
10 14
11describe('Test server follows API validators', function () { 15describe('Test server follows API validators', function () {
12 let server: ServerInfo 16 let server: ServerInfo
diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts
index 877ceb0a7..77c17036a 100644
--- a/server/tests/api/check-params/index.ts
+++ b/server/tests/api/check-params/index.ts
@@ -1,12 +1,13 @@
1// Order of the tests we want to execute
2import './accounts' 1import './accounts'
3import './blocklist' 2import './blocklist'
4import './config' 3import './config'
4import './contact-form'
5import './follows' 5import './follows'
6import './jobs' 6import './jobs'
7import './redundancy' 7import './redundancy'
8import './search' 8import './search'
9import './services' 9import './services'
10import './user-notifications'
10import './user-subscriptions' 11import './user-subscriptions'
11import './users' 12import './users'
12import './video-abuses' 13import './video-abuses'
diff --git a/server/tests/api/check-params/jobs.ts b/server/tests/api/check-params/jobs.ts
index ce3ac8809..89760ff98 100644
--- a/server/tests/api/check-params/jobs.ts
+++ b/server/tests/api/check-params/jobs.ts
@@ -2,9 +2,21 @@
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { createUser, flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, userLogin } from '../../utils' 5import {
6import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 6 createUser,
7import { makeGetRequest } from '../../utils/requests/requests' 7 flushTests,
8 killallServers,
9 runServer,
10 ServerInfo,
11 setAccessTokensToServers,
12 userLogin
13} from '../../../../shared/utils'
14import {
15 checkBadCountPagination,
16 checkBadSortPagination,
17 checkBadStartPagination
18} from '../../../../shared/utils/requests/check-api-params'
19import { makeGetRequest } from '../../../../shared/utils/requests/requests'
8 20
9describe('Test jobs API validators', function () { 21describe('Test jobs API validators', function () {
10 const path = '/api/v1/jobs/failed' 22 const path = '/api/v1/jobs/failed'
diff --git a/server/tests/api/check-params/redundancy.ts b/server/tests/api/check-params/redundancy.ts
index aa588e3dd..ff4726ceb 100644
--- a/server/tests/api/check-params/redundancy.ts
+++ b/server/tests/api/check-params/redundancy.ts
@@ -12,7 +12,7 @@ import {
12 ServerInfo, 12 ServerInfo,
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 userLogin 14 userLogin
15} from '../../utils' 15} from '../../../../shared/utils'
16 16
17describe('Test server redundancy API validators', function () { 17describe('Test server redundancy API validators', function () {
18 let servers: ServerInfo[] 18 let servers: ServerInfo[]
diff --git a/server/tests/api/check-params/search.ts b/server/tests/api/check-params/search.ts
index eabf602ac..aa81965f3 100644
--- a/server/tests/api/check-params/search.ts
+++ b/server/tests/api/check-params/search.ts
@@ -2,8 +2,12 @@
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { flushTests, immutableAssign, killallServers, makeGetRequest, runServer, ServerInfo } from '../../utils' 5import { flushTests, immutableAssign, killallServers, makeGetRequest, runServer, ServerInfo } from '../../../../shared/utils'
6import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 6import {
7 checkBadCountPagination,
8 checkBadSortPagination,
9 checkBadStartPagination
10} from '../../../../shared/utils/requests/check-api-params'
7 11
8describe('Test videos API validator', function () { 12describe('Test videos API validator', function () {
9 let server: ServerInfo 13 let server: ServerInfo
diff --git a/server/tests/api/check-params/services.ts b/server/tests/api/check-params/services.ts
index fcde7e179..28591af9d 100644
--- a/server/tests/api/check-params/services.ts
+++ b/server/tests/api/check-params/services.ts
@@ -2,7 +2,15 @@
2 2
3import 'mocha' 3import 'mocha'
4 4
5import { flushTests, killallServers, makeGetRequest, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils' 5import {
6 flushTests,
7 killallServers,
8 makeGetRequest,
9 runServer,
10 ServerInfo,
11 setAccessTokensToServers,
12 uploadVideo
13} from '../../../../shared/utils'
6 14
7describe('Test services API validators', function () { 15describe('Test services API validators', function () {
8 let server: ServerInfo 16 let server: ServerInfo
diff --git a/server/tests/api/check-params/user-notifications.ts b/server/tests/api/check-params/user-notifications.ts
new file mode 100644
index 000000000..714f481e9
--- /dev/null
+++ b/server/tests/api/check-params/user-notifications.ts
@@ -0,0 +1,297 @@
1/* tslint:disable:no-unused-expression */
2
3import 'mocha'
4import * as io from 'socket.io-client'
5
6import {
7 flushTests,
8 immutableAssign,
9 killallServers,
10 makeGetRequest,
11 makePostBodyRequest,
12 makePutBodyRequest,
13 runServer,
14 ServerInfo,
15 setAccessTokensToServers,
16 wait
17} from '../../../../shared/utils'
18import {
19 checkBadCountPagination,
20 checkBadSortPagination,
21 checkBadStartPagination
22} from '../../../../shared/utils/requests/check-api-params'
23import { UserNotificationSetting, UserNotificationSettingValue } from '../../../../shared/models/users'
24
25describe('Test user notifications API validators', function () {
26 let server: ServerInfo
27
28 // ---------------------------------------------------------------
29
30 before(async function () {
31 this.timeout(30000)
32
33 await flushTests()
34
35 server = await runServer(1)
36
37 await setAccessTokensToServers([ server ])
38 })
39
40 describe('When listing my notifications', function () {
41 const path = '/api/v1/users/me/notifications'
42
43 it('Should fail with a bad start pagination', async function () {
44 await checkBadStartPagination(server.url, path, server.accessToken)
45 })
46
47 it('Should fail with a bad count pagination', async function () {
48 await checkBadCountPagination(server.url, path, server.accessToken)
49 })
50
51 it('Should fail with an incorrect sort', async function () {
52 await checkBadSortPagination(server.url, path, server.accessToken)
53 })
54
55 it('Should fail with an incorrect unread parameter', async function () {
56 await makeGetRequest({
57 url: server.url,
58 path,
59 query: {
60 unread: 'toto'
61 },
62 token: server.accessToken,
63 statusCodeExpected: 200
64 })
65 })
66
67 it('Should fail with a non authenticated user', async function () {
68 await makeGetRequest({
69 url: server.url,
70 path,
71 statusCodeExpected: 401
72 })
73 })
74
75 it('Should succeed with the correct parameters', async function () {
76 await makeGetRequest({
77 url: server.url,
78 path,
79 token: server.accessToken,
80 statusCodeExpected: 200
81 })
82 })
83 })
84
85 describe('When marking as read my notifications', function () {
86 const path = '/api/v1/users/me/notifications/read'
87
88 it('Should fail with wrong ids parameters', async function () {
89 await makePostBodyRequest({
90 url: server.url,
91 path,
92 fields: {
93 ids: [ 'hello' ]
94 },
95 token: server.accessToken,
96 statusCodeExpected: 400
97 })
98
99 await makePostBodyRequest({
100 url: server.url,
101 path,
102 fields: {
103 ids: [ ]
104 },
105 token: server.accessToken,
106 statusCodeExpected: 400
107 })
108
109 await makePostBodyRequest({
110 url: server.url,
111 path,
112 fields: {
113 ids: 5
114 },
115 token: server.accessToken,
116 statusCodeExpected: 400
117 })
118 })
119
120 it('Should fail with a non authenticated user', async function () {
121 await makePostBodyRequest({
122 url: server.url,
123 path,
124 fields: {
125 ids: [ 5 ]
126 },
127 statusCodeExpected: 401
128 })
129 })
130
131 it('Should succeed with the correct parameters', async function () {
132 await makePostBodyRequest({
133 url: server.url,
134 path,
135 fields: {
136 ids: [ 5 ]
137 },
138 token: server.accessToken,
139 statusCodeExpected: 204
140 })
141 })
142 })
143
144 describe('When marking as read my notifications', function () {
145 const path = '/api/v1/users/me/notifications/read-all'
146
147 it('Should fail with a non authenticated user', async function () {
148 await makePostBodyRequest({
149 url: server.url,
150 path,
151 statusCodeExpected: 401
152 })
153 })
154
155 it('Should succeed with the correct parameters', async function () {
156 await makePostBodyRequest({
157 url: server.url,
158 path,
159 token: server.accessToken,
160 statusCodeExpected: 204
161 })
162 })
163 })
164
165 describe('When updating my notification settings', function () {
166 const path = '/api/v1/users/me/notification-settings'
167 const correctFields: UserNotificationSetting = {
168 newVideoFromSubscription: UserNotificationSettingValue.WEB,
169 newCommentOnMyVideo: UserNotificationSettingValue.WEB,
170 videoAbuseAsModerator: UserNotificationSettingValue.WEB,
171 blacklistOnMyVideo: UserNotificationSettingValue.WEB,
172 myVideoImportFinished: UserNotificationSettingValue.WEB,
173 myVideoPublished: UserNotificationSettingValue.WEB,
174 commentMention: UserNotificationSettingValue.WEB,
175 newFollow: UserNotificationSettingValue.WEB,
176 newUserRegistration: UserNotificationSettingValue.WEB
177 }
178
179 it('Should fail with missing fields', async function () {
180 await makePutBodyRequest({
181 url: server.url,
182 path,
183 token: server.accessToken,
184 fields: { newVideoFromSubscription: UserNotificationSettingValue.WEB },
185 statusCodeExpected: 400
186 })
187 })
188
189 it('Should fail with incorrect field values', async function () {
190 {
191 const fields = immutableAssign(correctFields, { newCommentOnMyVideo: 15 })
192
193 await makePutBodyRequest({
194 url: server.url,
195 path,
196 token: server.accessToken,
197 fields,
198 statusCodeExpected: 400
199 })
200 }
201
202 {
203 const fields = immutableAssign(correctFields, { newCommentOnMyVideo: 'toto' })
204
205 await makePutBodyRequest({
206 url: server.url,
207 path,
208 fields,
209 token: server.accessToken,
210 statusCodeExpected: 400
211 })
212 }
213 })
214
215 it('Should fail with a non authenticated user', async function () {
216 await makePutBodyRequest({
217 url: server.url,
218 path,
219 fields: correctFields,
220 statusCodeExpected: 401
221 })
222 })
223
224 it('Should succeed with the correct parameters', async function () {
225 await makePutBodyRequest({
226 url: server.url,
227 path,
228 token: server.accessToken,
229 fields: correctFields,
230 statusCodeExpected: 204
231 })
232 })
233 })
234
235 describe('When connecting to my notification socket', function () {
236 it('Should fail with no token', function (next) {
237 const socket = io('http://localhost:9001/user-notifications', { reconnection: false })
238
239 socket.on('error', () => {
240 socket.removeListener('error', this)
241 socket.disconnect()
242 next()
243 })
244
245 socket.on('connect', () => {
246 socket.disconnect()
247 next(new Error('Connected with a missing token.'))
248 })
249 })
250
251 it('Should fail with an invalid token', function (next) {
252 const socket = io('http://localhost:9001/user-notifications', {
253 query: { accessToken: 'bad_access_token' },
254 reconnection: false
255 })
256
257 socket.on('error', () => {
258 socket.removeListener('error', this)
259 socket.disconnect()
260 next()
261 })
262
263 socket.on('connect', () => {
264 socket.disconnect()
265 next(new Error('Connected with an invalid token.'))
266 })
267 })
268
269 it('Should success with the correct token', function (next) {
270 const socket = io('http://localhost:9001/user-notifications', {
271 query: { accessToken: server.accessToken },
272 reconnection: false
273 })
274
275 const errorListener = socket.on('error', err => {
276 next(new Error('Error in connection: ' + err))
277 })
278
279 socket.on('connect', async () => {
280 socket.removeListener('error', errorListener)
281 socket.disconnect()
282
283 await wait(500)
284 next()
285 })
286 })
287 })
288
289 after(async function () {
290 killallServers([ server ])
291
292 // Keep the logs if the test failed
293 if (this['ok']) {
294 await flushTests()
295 }
296 })
297})
diff --git a/server/tests/api/check-params/user-subscriptions.ts b/server/tests/api/check-params/user-subscriptions.ts
index 6af7ed43b..8a9ced7c1 100644
--- a/server/tests/api/check-params/user-subscriptions.ts
+++ b/server/tests/api/check-params/user-subscriptions.ts
@@ -13,9 +13,14 @@ import {
13 ServerInfo, 13 ServerInfo,
14 setAccessTokensToServers, 14 setAccessTokensToServers,
15 userLogin 15 userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 17
18import { waitJobs } from '../../utils/server/jobs' 18import {
19 checkBadCountPagination,
20 checkBadSortPagination,
21 checkBadStartPagination
22} from '../../../../shared/utils/requests/check-api-params'
23import { waitJobs } from '../../../../shared/utils/server/jobs'
19 24
20describe('Test user subscriptions API validators', function () { 25describe('Test user subscriptions API validators', function () {
21 const path = '/api/v1/users/me/subscriptions' 26 const path = '/api/v1/users/me/subscriptions'
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts
index 273be1679..a3e8e2e9c 100644
--- a/server/tests/api/check-params/users.ts
+++ b/server/tests/api/check-params/users.ts
@@ -9,11 +9,15 @@ import {
9 createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest, 9 createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest,
10 makePostBodyRequest, makeUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers, 10 makePostBodyRequest, makeUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers,
11 updateUser, uploadVideo, userLogin, deleteMe, unblockUser, blockUser 11 updateUser, uploadVideo, userLogin, deleteMe, unblockUser, blockUser
12} from '../../utils' 12} from '../../../../shared/utils'
13import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 13import {
14import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../utils/videos/video-imports' 14 checkBadCountPagination,
15 checkBadSortPagination,
16 checkBadStartPagination
17} from '../../../../shared/utils/requests/check-api-params'
18import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../../../shared/utils/videos/video-imports'
15import { VideoPrivacy } from '../../../../shared/models/videos' 19import { VideoPrivacy } from '../../../../shared/models/videos'
16import { waitJobs } from '../../utils/server/jobs' 20import { waitJobs } from '../../../../shared/utils/server/jobs'
17import { expect } from 'chai' 21import { expect } from 'chai'
18 22
19describe('Test users API validators', function () { 23describe('Test users API validators', function () {
@@ -99,13 +103,13 @@ describe('Test users API validators', function () {
99 } 103 }
100 104
101 it('Should fail with a too small username', async function () { 105 it('Should fail with a too small username', async function () {
102 const fields = immutableAssign(baseCorrectParams, { username: 'fi' }) 106 const fields = immutableAssign(baseCorrectParams, { username: '' })
103 107
104 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 108 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
105 }) 109 })
106 110
107 it('Should fail with a too long username', async function () { 111 it('Should fail with a too long username', async function () {
108 const fields = immutableAssign(baseCorrectParams, { username: 'my_super_username_which_is_very_long' }) 112 const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
109 113
110 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 114 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
111 }) 115 })
@@ -304,6 +308,14 @@ describe('Test users API validators', function () {
304 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields }) 308 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
305 }) 309 })
306 310
311 it('Should fail with an invalid videosHistoryEnabled attribute', async function () {
312 const fields = {
313 videosHistoryEnabled: -1
314 }
315
316 await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields })
317 })
318
307 it('Should fail with an non authenticated user', async function () { 319 it('Should fail with an non authenticated user', async function () {
308 const fields = { 320 const fields = {
309 currentPassword: 'my super password', 321 currentPassword: 'my super password',
@@ -473,11 +485,10 @@ describe('Test users API validators', function () {
473 email: 'email@example.com', 485 email: 'email@example.com',
474 emailVerified: true, 486 emailVerified: true,
475 videoQuota: 42, 487 videoQuota: 42,
476 role: UserRole.MODERATOR 488 role: UserRole.USER
477 } 489 }
478 490
479 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 }) 491 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields, statusCodeExpected: 204 })
480 userAccessToken = await userLogin(server, user)
481 }) 492 })
482 }) 493 })
483 494
@@ -550,13 +561,13 @@ describe('Test users API validators', function () {
550 } 561 }
551 562
552 it('Should fail with a too small username', async function () { 563 it('Should fail with a too small username', async function () {
553 const fields = immutableAssign(baseCorrectParams, { username: 'ji' }) 564 const fields = immutableAssign(baseCorrectParams, { username: '' })
554 565
555 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields }) 566 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
556 }) 567 })
557 568
558 it('Should fail with a too long username', async function () { 569 it('Should fail with a too long username', async function () {
559 const fields = immutableAssign(baseCorrectParams, { username: 'my_super_username_which_is_very_long' }) 570 const fields = immutableAssign(baseCorrectParams, { username: 'super'.repeat(50) })
560 571
561 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields }) 572 await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields })
562 }) 573 })
diff --git a/server/tests/api/check-params/video-abuses.ts b/server/tests/api/check-params/video-abuses.ts
index d2bed6a2a..3b8f5f14d 100644
--- a/server/tests/api/check-params/video-abuses.ts
+++ b/server/tests/api/check-params/video-abuses.ts
@@ -15,8 +15,12 @@ import {
15 updateVideoAbuse, 15 updateVideoAbuse,
16 uploadVideo, 16 uploadVideo,
17 userLogin 17 userLogin
18} from '../../utils' 18} from '../../../../shared/utils'
19import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 19import {
20 checkBadCountPagination,
21 checkBadSortPagination,
22 checkBadStartPagination
23} from '../../../../shared/utils/requests/check-api-params'
20import { VideoAbuseState } from '../../../../shared/models/videos' 24import { VideoAbuseState } from '../../../../shared/models/videos'
21 25
22describe('Test video abuses API validators', function () { 26describe('Test video abuses API validators', function () {
@@ -109,8 +113,8 @@ describe('Test video abuses API validators', function () {
109 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 113 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
110 }) 114 })
111 115
112 it('Should fail with a reason too big', async function () { 116 it('Should fail with a too big reason', async function () {
113 const fields = { reason: 'super'.repeat(61) } 117 const fields = { reason: 'super'.repeat(605) }
114 118
115 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 119 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
116 }) 120 })
@@ -150,7 +154,7 @@ describe('Test video abuses API validators', function () {
150 }) 154 })
151 155
152 it('Should fail with a bad moderation comment', async function () { 156 it('Should fail with a bad moderation comment', async function () {
153 const body = { moderationComment: 'b'.repeat(305) } 157 const body = { moderationComment: 'b'.repeat(3001) }
154 await updateVideoAbuse(server.url, server.accessToken, server.video.uuid, videoAbuseId, body, 400) 158 await updateVideoAbuse(server.url, server.accessToken, server.video.uuid, videoAbuseId, body, 400)
155 }) 159 })
156 160
diff --git a/server/tests/api/check-params/video-blacklist.ts b/server/tests/api/check-params/video-blacklist.ts
index 473216236..6b82643f4 100644
--- a/server/tests/api/check-params/video-blacklist.ts
+++ b/server/tests/api/check-params/video-blacklist.ts
@@ -4,25 +4,33 @@ import 'mocha'
4 4
5import { 5import {
6 createUser, 6 createUser,
7 doubleFollow,
8 flushAndRunMultipleServers,
7 flushTests, 9 flushTests,
8 getBlacklistedVideosList, getVideo, getVideoWithToken, 10 getBlacklistedVideosList,
11 getVideo,
12 getVideoWithToken,
9 killallServers, 13 killallServers,
10 makePostBodyRequest, 14 makePostBodyRequest,
11 makePutBodyRequest, 15 makePutBodyRequest,
12 removeVideoFromBlacklist, 16 removeVideoFromBlacklist,
13 runServer,
14 ServerInfo, 17 ServerInfo,
15 setAccessTokensToServers, 18 setAccessTokensToServers,
16 uploadVideo, 19 uploadVideo,
17 userLogin 20 userLogin, waitJobs
18} from '../../utils' 21} from '../../../../shared/utils'
19import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 22import {
23 checkBadCountPagination,
24 checkBadSortPagination,
25 checkBadStartPagination
26} from '../../../../shared/utils/requests/check-api-params'
20import { VideoDetails } from '../../../../shared/models/videos' 27import { VideoDetails } from '../../../../shared/models/videos'
21import { expect } from 'chai' 28import { expect } from 'chai'
22 29
23describe('Test video blacklist API validators', function () { 30describe('Test video blacklist API validators', function () {
24 let server: ServerInfo 31 let servers: ServerInfo[]
25 let notBlacklistedVideoId: number 32 let notBlacklistedVideoId: number
33 let remoteVideoUUID: string
26 let userAccessToken1 = '' 34 let userAccessToken1 = ''
27 let userAccessToken2 = '' 35 let userAccessToken2 = ''
28 36
@@ -32,75 +40,89 @@ describe('Test video blacklist API validators', function () {
32 this.timeout(120000) 40 this.timeout(120000)
33 41
34 await flushTests() 42 await flushTests()
43 servers = await flushAndRunMultipleServers(2)
35 44
36 server = await runServer(1) 45 await setAccessTokensToServers(servers)
37 46 await doubleFollow(servers[0], servers[1])
38 await setAccessTokensToServers([ server ])
39 47
40 { 48 {
41 const username = 'user1' 49 const username = 'user1'
42 const password = 'my super password' 50 const password = 'my super password'
43 await createUser(server.url, server.accessToken, username, password) 51 await createUser(servers[0].url, servers[0].accessToken, username, password)
44 userAccessToken1 = await userLogin(server, { username, password }) 52 userAccessToken1 = await userLogin(servers[0], { username, password })
45 } 53 }
46 54
47 { 55 {
48 const username = 'user2' 56 const username = 'user2'
49 const password = 'my super password' 57 const password = 'my super password'
50 await createUser(server.url, server.accessToken, username, password) 58 await createUser(servers[0].url, servers[0].accessToken, username, password)
51 userAccessToken2 = await userLogin(server, { username, password }) 59 userAccessToken2 = await userLogin(servers[0], { username, password })
52 } 60 }
53 61
54 { 62 {
55 const res = await uploadVideo(server.url, userAccessToken1, {}) 63 const res = await uploadVideo(servers[0].url, userAccessToken1, {})
56 server.video = res.body.video 64 servers[0].video = res.body.video
57 } 65 }
58 66
59 { 67 {
60 const res = await uploadVideo(server.url, server.accessToken, {}) 68 const res = await uploadVideo(servers[0].url, servers[0].accessToken, {})
61 notBlacklistedVideoId = res.body.video.uuid 69 notBlacklistedVideoId = res.body.video.uuid
62 } 70 }
71
72 {
73 const res = await uploadVideo(servers[1].url, servers[1].accessToken, {})
74 remoteVideoUUID = res.body.video.uuid
75 }
76
77 await waitJobs(servers)
63 }) 78 })
64 79
65 describe('When adding a video in blacklist', function () { 80 describe('When adding a video in blacklist', function () {
66 const basePath = '/api/v1/videos/' 81 const basePath = '/api/v1/videos/'
67 82
68 it('Should fail with nothing', async function () { 83 it('Should fail with nothing', async function () {
69 const path = basePath + server.video + '/blacklist' 84 const path = basePath + servers[0].video + '/blacklist'
70 const fields = {} 85 const fields = {}
71 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 86 await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields })
72 }) 87 })
73 88
74 it('Should fail with a wrong video', async function () { 89 it('Should fail with a wrong video', async function () {
75 const wrongPath = '/api/v1/videos/blabla/blacklist' 90 const wrongPath = '/api/v1/videos/blabla/blacklist'
76 const fields = {} 91 const fields = {}
77 await makePostBodyRequest({ url: server.url, path: wrongPath, token: server.accessToken, fields }) 92 await makePostBodyRequest({ url: servers[0].url, path: wrongPath, token: servers[0].accessToken, fields })
78 }) 93 })
79 94
80 it('Should fail with a non authenticated user', async function () { 95 it('Should fail with a non authenticated user', async function () {
81 const path = basePath + server.video + '/blacklist' 96 const path = basePath + servers[0].video + '/blacklist'
82 const fields = {} 97 const fields = {}
83 await makePostBodyRequest({ url: server.url, path, token: 'hello', fields, statusCodeExpected: 401 }) 98 await makePostBodyRequest({ url: servers[0].url, path, token: 'hello', fields, statusCodeExpected: 401 })
84 }) 99 })
85 100
86 it('Should fail with a non admin user', async function () { 101 it('Should fail with a non admin user', async function () {
87 const path = basePath + server.video + '/blacklist' 102 const path = basePath + servers[0].video + '/blacklist'
88 const fields = {} 103 const fields = {}
89 await makePostBodyRequest({ url: server.url, path, token: userAccessToken2, fields, statusCodeExpected: 403 }) 104 await makePostBodyRequest({ url: servers[0].url, path, token: userAccessToken2, fields, statusCodeExpected: 403 })
90 }) 105 })
91 106
92 it('Should fail with an invalid reason', async function () { 107 it('Should fail with an invalid reason', async function () {
93 const path = basePath + server.video.uuid + '/blacklist' 108 const path = basePath + servers[0].video.uuid + '/blacklist'
94 const fields = { reason: 'a'.repeat(305) } 109 const fields = { reason: 'a'.repeat(305) }
95 110
96 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 111 await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields })
112 })
113
114 it('Should fail to unfederate a remote video', async function () {
115 const path = basePath + remoteVideoUUID + '/blacklist'
116 const fields = { unfederate: true }
117
118 await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 409 })
97 }) 119 })
98 120
99 it('Should succeed with the correct params', async function () { 121 it('Should succeed with the correct params', async function () {
100 const path = basePath + server.video.uuid + '/blacklist' 122 const path = basePath + servers[0].video.uuid + '/blacklist'
101 const fields = { } 123 const fields = { }
102 124
103 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 }) 125 await makePostBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 204 })
104 }) 126 })
105 }) 127 })
106 128
@@ -110,61 +132,61 @@ describe('Test video blacklist API validators', function () {
110 it('Should fail with a wrong video', async function () { 132 it('Should fail with a wrong video', async function () {
111 const wrongPath = '/api/v1/videos/blabla/blacklist' 133 const wrongPath = '/api/v1/videos/blabla/blacklist'
112 const fields = {} 134 const fields = {}
113 await makePutBodyRequest({ url: server.url, path: wrongPath, token: server.accessToken, fields }) 135 await makePutBodyRequest({ url: servers[0].url, path: wrongPath, token: servers[0].accessToken, fields })
114 }) 136 })
115 137
116 it('Should fail with a video not blacklisted', async function () { 138 it('Should fail with a video not blacklisted', async function () {
117 const path = '/api/v1/videos/' + notBlacklistedVideoId + '/blacklist' 139 const path = '/api/v1/videos/' + notBlacklistedVideoId + '/blacklist'
118 const fields = {} 140 const fields = {}
119 await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 404 }) 141 await makePutBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 404 })
120 }) 142 })
121 143
122 it('Should fail with a non authenticated user', async function () { 144 it('Should fail with a non authenticated user', async function () {
123 const path = basePath + server.video + '/blacklist' 145 const path = basePath + servers[0].video + '/blacklist'
124 const fields = {} 146 const fields = {}
125 await makePutBodyRequest({ url: server.url, path, token: 'hello', fields, statusCodeExpected: 401 }) 147 await makePutBodyRequest({ url: servers[0].url, path, token: 'hello', fields, statusCodeExpected: 401 })
126 }) 148 })
127 149
128 it('Should fail with a non admin user', async function () { 150 it('Should fail with a non admin user', async function () {
129 const path = basePath + server.video + '/blacklist' 151 const path = basePath + servers[0].video + '/blacklist'
130 const fields = {} 152 const fields = {}
131 await makePutBodyRequest({ url: server.url, path, token: userAccessToken2, fields, statusCodeExpected: 403 }) 153 await makePutBodyRequest({ url: servers[0].url, path, token: userAccessToken2, fields, statusCodeExpected: 403 })
132 }) 154 })
133 155
134 it('Should fail with an invalid reason', async function () { 156 it('Should fail with an invalid reason', async function () {
135 const path = basePath + server.video.uuid + '/blacklist' 157 const path = basePath + servers[0].video.uuid + '/blacklist'
136 const fields = { reason: 'a'.repeat(305) } 158 const fields = { reason: 'a'.repeat(305) }
137 159
138 await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields }) 160 await makePutBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields })
139 }) 161 })
140 162
141 it('Should succeed with the correct params', async function () { 163 it('Should succeed with the correct params', async function () {
142 const path = basePath + server.video.uuid + '/blacklist' 164 const path = basePath + servers[0].video.uuid + '/blacklist'
143 const fields = { reason: 'hello' } 165 const fields = { reason: 'hello' }
144 166
145 await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields, statusCodeExpected: 204 }) 167 await makePutBodyRequest({ url: servers[0].url, path, token: servers[0].accessToken, fields, statusCodeExpected: 204 })
146 }) 168 })
147 }) 169 })
148 170
149 describe('When getting blacklisted video', function () { 171 describe('When getting blacklisted video', function () {
150 172
151 it('Should fail with a non authenticated user', async function () { 173 it('Should fail with a non authenticated user', async function () {
152 await getVideo(server.url, server.video.uuid, 401) 174 await getVideo(servers[0].url, servers[0].video.uuid, 401)
153 }) 175 })
154 176
155 it('Should fail with another user', async function () { 177 it('Should fail with another user', async function () {
156 await getVideoWithToken(server.url, userAccessToken2, server.video.uuid, 403) 178 await getVideoWithToken(servers[0].url, userAccessToken2, servers[0].video.uuid, 403)
157 }) 179 })
158 180
159 it('Should succeed with the owner authenticated user', async function () { 181 it('Should succeed with the owner authenticated user', async function () {
160 const res = await getVideoWithToken(server.url, userAccessToken1, server.video.uuid, 200) 182 const res = await getVideoWithToken(servers[0].url, userAccessToken1, servers[0].video.uuid, 200)
161 const video: VideoDetails = res.body 183 const video: VideoDetails = res.body
162 184
163 expect(video.blacklisted).to.be.true 185 expect(video.blacklisted).to.be.true
164 }) 186 })
165 187
166 it('Should succeed with an admin', async function () { 188 it('Should succeed with an admin', async function () {
167 const res = await getVideoWithToken(server.url, server.accessToken, server.video.uuid, 200) 189 const res = await getVideoWithToken(servers[0].url, servers[0].accessToken, servers[0].video.uuid, 200)
168 const video: VideoDetails = res.body 190 const video: VideoDetails = res.body
169 191
170 expect(video.blacklisted).to.be.true 192 expect(video.blacklisted).to.be.true
@@ -173,24 +195,24 @@ describe('Test video blacklist API validators', function () {
173 195
174 describe('When removing a video in blacklist', function () { 196 describe('When removing a video in blacklist', function () {
175 it('Should fail with a non authenticated user', async function () { 197 it('Should fail with a non authenticated user', async function () {
176 await removeVideoFromBlacklist(server.url, 'fake token', server.video.uuid, 401) 198 await removeVideoFromBlacklist(servers[0].url, 'fake token', servers[0].video.uuid, 401)
177 }) 199 })
178 200
179 it('Should fail with a non admin user', async function () { 201 it('Should fail with a non admin user', async function () {
180 await removeVideoFromBlacklist(server.url, userAccessToken2, server.video.uuid, 403) 202 await removeVideoFromBlacklist(servers[0].url, userAccessToken2, servers[0].video.uuid, 403)
181 }) 203 })
182 204
183 it('Should fail with an incorrect id', async function () { 205 it('Should fail with an incorrect id', async function () {
184 await removeVideoFromBlacklist(server.url, server.accessToken, 'hello', 400) 206 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, 'hello', 400)
185 }) 207 })
186 208
187 it('Should fail with a not blacklisted video', async function () { 209 it('Should fail with a not blacklisted video', async function () {
188 // The video was not added to the blacklist so it should fail 210 // The video was not added to the blacklist so it should fail
189 await removeVideoFromBlacklist(server.url, server.accessToken, notBlacklistedVideoId, 404) 211 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, notBlacklistedVideoId, 404)
190 }) 212 })
191 213
192 it('Should succeed with the correct params', async function () { 214 it('Should succeed with the correct params', async function () {
193 await removeVideoFromBlacklist(server.url, server.accessToken, server.video.uuid, 204) 215 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, servers[0].video.uuid, 204)
194 }) 216 })
195 }) 217 })
196 218
@@ -198,28 +220,28 @@ describe('Test video blacklist API validators', function () {
198 const basePath = '/api/v1/videos/blacklist/' 220 const basePath = '/api/v1/videos/blacklist/'
199 221
200 it('Should fail with a non authenticated user', async function () { 222 it('Should fail with a non authenticated user', async function () {
201 await getBlacklistedVideosList(server.url, 'fake token', 401) 223 await getBlacklistedVideosList(servers[0].url, 'fake token', 401)
202 }) 224 })
203 225
204 it('Should fail with a non admin user', async function () { 226 it('Should fail with a non admin user', async function () {
205 await getBlacklistedVideosList(server.url, userAccessToken2, 403) 227 await getBlacklistedVideosList(servers[0].url, userAccessToken2, 403)
206 }) 228 })
207 229
208 it('Should fail with a bad start pagination', async function () { 230 it('Should fail with a bad start pagination', async function () {
209 await checkBadStartPagination(server.url, basePath, server.accessToken) 231 await checkBadStartPagination(servers[0].url, basePath, servers[0].accessToken)
210 }) 232 })
211 233
212 it('Should fail with a bad count pagination', async function () { 234 it('Should fail with a bad count pagination', async function () {
213 await checkBadCountPagination(server.url, basePath, server.accessToken) 235 await checkBadCountPagination(servers[0].url, basePath, servers[0].accessToken)
214 }) 236 })
215 237
216 it('Should fail with an incorrect sort', async function () { 238 it('Should fail with an incorrect sort', async function () {
217 await checkBadSortPagination(server.url, basePath, server.accessToken) 239 await checkBadSortPagination(servers[0].url, basePath, servers[0].accessToken)
218 }) 240 })
219 }) 241 })
220 242
221 after(async function () { 243 after(async function () {
222 killallServers([ server ]) 244 killallServers(servers)
223 245
224 // Keep the logs if the test failed 246 // Keep the logs if the test failed
225 if (this['ok']) { 247 if (this['ok']) {
diff --git a/server/tests/api/check-params/video-captions.ts b/server/tests/api/check-params/video-captions.ts
index 8d46971a1..e4d36fd4f 100644
--- a/server/tests/api/check-params/video-captions.ts
+++ b/server/tests/api/check-params/video-captions.ts
@@ -13,9 +13,9 @@ import {
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 uploadVideo, 14 uploadVideo,
15 userLogin 15 userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { join } from 'path' 17import { join } from 'path'
18import { createVideoCaption } from '../../utils/videos/video-captions' 18import { createVideoCaption } from '../../../../shared/utils/videos/video-captions'
19 19
20describe('Test video captions API validator', function () { 20describe('Test video captions API validator', function () {
21 const path = '/api/v1/videos/' 21 const path = '/api/v1/videos/'
diff --git a/server/tests/api/check-params/video-channels.ts b/server/tests/api/check-params/video-channels.ts
index e5696224d..14e4deaf7 100644
--- a/server/tests/api/check-params/video-channels.ts
+++ b/server/tests/api/check-params/video-channels.ts
@@ -20,8 +20,12 @@ import {
20 ServerInfo, 20 ServerInfo,
21 setAccessTokensToServers, 21 setAccessTokensToServers,
22 userLogin 22 userLogin
23} from '../../utils' 23} from '../../../../shared/utils'
24import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 24import {
25 checkBadCountPagination,
26 checkBadSortPagination,
27 checkBadStartPagination
28} from '../../../../shared/utils/requests/check-api-params'
25import { User } from '../../../../shared/models/users' 29import { User } from '../../../../shared/models/users'
26import { join } from 'path' 30import { join } from 'path'
27 31
diff --git a/server/tests/api/check-params/video-comments.ts b/server/tests/api/check-params/video-comments.ts
index 5241832fe..5981780ed 100644
--- a/server/tests/api/check-params/video-comments.ts
+++ b/server/tests/api/check-params/video-comments.ts
@@ -6,9 +6,13 @@ import {
6 createUser, 6 createUser,
7 flushTests, killallServers, makeDeleteRequest, makeGetRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers, 7 flushTests, killallServers, makeDeleteRequest, makeGetRequest, makePostBodyRequest, runServer, ServerInfo, setAccessTokensToServers,
8 uploadVideo, userLogin 8 uploadVideo, userLogin
9} from '../../utils' 9} from '../../../../shared/utils'
10import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 10import {
11import { addVideoCommentThread } from '../../utils/videos/video-comments' 11 checkBadCountPagination,
12 checkBadSortPagination,
13 checkBadStartPagination
14} from '../../../../shared/utils/requests/check-api-params'
15import { addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
12 16
13const expect = chai.expect 17const expect = chai.expect
14 18
diff --git a/server/tests/api/check-params/video-imports.ts b/server/tests/api/check-params/video-imports.ts
index b51f3d2cd..7bf187007 100644
--- a/server/tests/api/check-params/video-imports.ts
+++ b/server/tests/api/check-params/video-imports.ts
@@ -18,9 +18,13 @@ import {
18 setAccessTokensToServers, 18 setAccessTokensToServers,
19 updateCustomSubConfig, 19 updateCustomSubConfig,
20 userLogin 20 userLogin
21} from '../../utils' 21} from '../../../../shared/utils'
22import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 22import {
23import { getMagnetURI, getYoutubeVideoUrl } from '../../utils/videos/video-imports' 23 checkBadCountPagination,
24 checkBadSortPagination,
25 checkBadStartPagination
26} from '../../../../shared/utils/requests/check-api-params'
27import { getMagnetURI, getYoutubeVideoUrl } from '../../../../shared/utils/videos/video-imports'
24 28
25describe('Test video imports API validator', function () { 29describe('Test video imports API validator', function () {
26 const path = '/api/v1/videos/imports' 30 const path = '/api/v1/videos/imports'
diff --git a/server/tests/api/check-params/videos-filter.ts b/server/tests/api/check-params/videos-filter.ts
index 784cd8ba1..e998c8a3d 100644
--- a/server/tests/api/check-params/videos-filter.ts
+++ b/server/tests/api/check-params/videos-filter.ts
@@ -11,7 +11,7 @@ import {
11 ServerInfo, 11 ServerInfo,
12 setAccessTokensToServers, 12 setAccessTokensToServers,
13 userLogin 13 userLogin
14} from '../../utils' 14} from '../../../../shared/utils'
15import { UserRole } from '../../../../shared/models/users' 15import { UserRole } from '../../../../shared/models/users'
16 16
17const expect = chai.expect 17const expect = chai.expect
diff --git a/server/tests/api/check-params/videos-history.ts b/server/tests/api/check-params/videos-history.ts
index 808c3b616..8c079a956 100644
--- a/server/tests/api/check-params/videos-history.ts
+++ b/server/tests/api/check-params/videos-history.ts
@@ -3,20 +3,25 @@
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { 5import {
6 checkBadCountPagination,
7 checkBadStartPagination,
6 flushTests, 8 flushTests,
7 killallServers, 9 killallServers,
10 makeGetRequest,
8 makePostBodyRequest, 11 makePostBodyRequest,
9 makePutBodyRequest, 12 makePutBodyRequest,
10 runServer, 13 runServer,
11 ServerInfo, 14 ServerInfo,
12 setAccessTokensToServers, 15 setAccessTokensToServers,
13 uploadVideo 16 uploadVideo
14} from '../../utils' 17} from '../../../../shared/utils'
15 18
16const expect = chai.expect 19const expect = chai.expect
17 20
18describe('Test videos history API validator', function () { 21describe('Test videos history API validator', function () {
19 let path: string 22 let watchingPath: string
23 let myHistoryPath = '/api/v1/users/me/history/videos'
24 let myHistoryRemove = myHistoryPath + '/remove'
20 let server: ServerInfo 25 let server: ServerInfo
21 26
22 // --------------------------------------------------------------- 27 // ---------------------------------------------------------------
@@ -33,14 +38,14 @@ describe('Test videos history API validator', function () {
33 const res = await uploadVideo(server.url, server.accessToken, {}) 38 const res = await uploadVideo(server.url, server.accessToken, {})
34 const videoUUID = res.body.video.uuid 39 const videoUUID = res.body.video.uuid
35 40
36 path = '/api/v1/videos/' + videoUUID + '/watching' 41 watchingPath = '/api/v1/videos/' + videoUUID + '/watching'
37 }) 42 })
38 43
39 describe('When notifying a user is watching a video', function () { 44 describe('When notifying a user is watching a video', function () {
40 45
41 it('Should fail with an unauthenticated user', async function () { 46 it('Should fail with an unauthenticated user', async function () {
42 const fields = { currentTime: 5 } 47 const fields = { currentTime: 5 }
43 await makePutBodyRequest({ url: server.url, path, fields, statusCodeExpected: 401 }) 48 await makePutBodyRequest({ url: server.url, path: watchingPath, fields, statusCodeExpected: 401 })
44 }) 49 })
45 50
46 it('Should fail with an incorrect video id', async function () { 51 it('Should fail with an incorrect video id', async function () {
@@ -58,13 +63,68 @@ describe('Test videos history API validator', function () {
58 63
59 it('Should fail with a bad current time', async function () { 64 it('Should fail with a bad current time', async function () {
60 const fields = { currentTime: 'hello' } 65 const fields = { currentTime: 'hello' }
61 await makePutBodyRequest({ url: server.url, path, fields, token: server.accessToken, statusCodeExpected: 400 }) 66 await makePutBodyRequest({ url: server.url, path: watchingPath, fields, token: server.accessToken, statusCodeExpected: 400 })
62 }) 67 })
63 68
64 it('Should succeed with the correct parameters', async function () { 69 it('Should succeed with the correct parameters', async function () {
65 const fields = { currentTime: 5 } 70 const fields = { currentTime: 5 }
66 71
67 await makePutBodyRequest({ url: server.url, path, fields, token: server.accessToken, statusCodeExpected: 204 }) 72 await makePutBodyRequest({ url: server.url, path: watchingPath, fields, token: server.accessToken, statusCodeExpected: 204 })
73 })
74 })
75
76 describe('When listing user videos history', function () {
77 it('Should fail with a bad start pagination', async function () {
78 await checkBadStartPagination(server.url, myHistoryPath, server.accessToken)
79 })
80
81 it('Should fail with a bad count pagination', async function () {
82 await checkBadCountPagination(server.url, myHistoryPath, server.accessToken)
83 })
84
85 it('Should fail with an unauthenticated user', async function () {
86 await makeGetRequest({ url: server.url, path: myHistoryPath, statusCodeExpected: 401 })
87 })
88
89 it('Should succeed with the correct params', async function () {
90 await makeGetRequest({ url: server.url, token: server.accessToken, path: myHistoryPath, statusCodeExpected: 200 })
91 })
92 })
93
94 describe('When removing user videos history', function () {
95 it('Should fail with an unauthenticated user', async function () {
96 await makePostBodyRequest({ url: server.url, path: myHistoryPath + '/remove', statusCodeExpected: 401 })
97 })
98
99 it('Should fail with a bad beforeDate parameter', async function () {
100 const body = { beforeDate: '15' }
101 await makePostBodyRequest({
102 url: server.url,
103 token: server.accessToken,
104 path: myHistoryRemove,
105 fields: body,
106 statusCodeExpected: 400
107 })
108 })
109
110 it('Should succeed with a valid beforeDate param', async function () {
111 const body = { beforeDate: new Date().toISOString() }
112 await makePostBodyRequest({
113 url: server.url,
114 token: server.accessToken,
115 path: myHistoryRemove,
116 fields: body,
117 statusCodeExpected: 204
118 })
119 })
120
121 it('Should succeed without body', async function () {
122 await makePostBodyRequest({
123 url: server.url,
124 token: server.accessToken,
125 path: myHistoryRemove,
126 statusCodeExpected: 204
127 })
68 }) 128 })
69 }) 129 })
70 130
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index 699f135c7..f26b91435 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -8,9 +8,13 @@ import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enu
8import { 8import {
9 createUser, flushTests, getMyUserInformation, getVideo, getVideosList, immutableAssign, killallServers, makeDeleteRequest, 9 createUser, flushTests, getMyUserInformation, getVideo, getVideosList, immutableAssign, killallServers, makeDeleteRequest,
10 makeGetRequest, makeUploadRequest, makePutBodyRequest, removeVideo, runServer, ServerInfo, setAccessTokensToServers, userLogin 10 makeGetRequest, makeUploadRequest, makePutBodyRequest, removeVideo, runServer, ServerInfo, setAccessTokensToServers, userLogin
11} from '../../utils' 11} from '../../../../shared/utils'
12import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' 12import {
13import { getAccountsList } from '../../utils/users/accounts' 13 checkBadCountPagination,
14 checkBadSortPagination,
15 checkBadStartPagination
16} from '../../../../shared/utils/requests/check-api-params'
17import { getAccountsList } from '../../../../shared/utils/users/accounts'
14 18
15const expect = chai.expect 19const expect = chai.expect
16 20
@@ -316,10 +320,15 @@ describe('Test videos API validator', function () {
316 320
317 it('Should fail without an incorrect input file', async function () { 321 it('Should fail without an incorrect input file', async function () {
318 const fields = baseCorrectParams 322 const fields = baseCorrectParams
319 const attaches = { 323 let attaches = {
320 'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short_fake.webm') 324 'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short_fake.webm')
321 } 325 }
322 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 326 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
327
328 attaches = {
329 'videofile': join(__dirname, '..', '..', 'fixtures', 'video_short.mkv')
330 }
331 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
323 }) 332 })
324 333
325 it('Should fail with an incorrect thumbnail file', async function () { 334 it('Should fail with an incorrect thumbnail file', async function () {
diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts
index a8a2f305f..9d3ce8153 100644
--- a/server/tests/api/redundancy/redundancy.ts
+++ b/server/tests/api/redundancy/redundancy.ts
@@ -18,15 +18,16 @@ import {
18 wait, 18 wait,
19 waitUntilLog, 19 waitUntilLog,
20 checkVideoFilesWereRemoved, removeVideo, getVideoWithToken 20 checkVideoFilesWereRemoved, removeVideo, getVideoWithToken
21} from '../../utils' 21} from '../../../../shared/utils'
22import { waitJobs } from '../../utils/server/jobs' 22import { waitJobs } from '../../../../shared/utils/server/jobs'
23
23import * as magnetUtil from 'magnet-uri' 24import * as magnetUtil from 'magnet-uri'
24import { updateRedundancy } from '../../utils/server/redundancy' 25import { updateRedundancy } from '../../../../shared/utils/server/redundancy'
25import { ActorFollow } from '../../../../shared/models/actors' 26import { ActorFollow } from '../../../../shared/models/actors'
26import { readdir } from 'fs-extra' 27import { readdir } from 'fs-extra'
27import { join } from 'path' 28import { join } from 'path'
28import { VideoRedundancyStrategy } from '../../../../shared/models/redundancy' 29import { VideoRedundancyStrategy } from '../../../../shared/models/redundancy'
29import { getStats } from '../../utils/server/stats' 30import { getStats } from '../../../../shared/utils/server/stats'
30import { ServerStats } from '../../../../shared/models/server/server-stats.model' 31import { ServerStats } from '../../../../shared/models/server/server-stats.model'
31 32
32const expect = chai.expect 33const expect = chai.expect
@@ -136,7 +137,7 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st
136 if (!videoUUID) videoUUID = video1Server2UUID 137 if (!videoUUID) videoUUID = video1Server2UUID
137 138
138 const webseeds = [ 139 const webseeds = [
139 'http://localhost:9001/static/webseed/' + videoUUID, 140 'http://localhost:9001/static/redundancy/' + videoUUID,
140 'http://localhost:9002/static/webseed/' + videoUUID 141 'http://localhost:9002/static/webseed/' + videoUUID
141 ] 142 ]
142 143
@@ -148,20 +149,23 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st
148 for (const file of video.files) { 149 for (const file of video.files) {
149 checkMagnetWebseeds(file, webseeds, server) 150 checkMagnetWebseeds(file, webseeds, server)
150 151
151 // Only servers 1 and 2 have the video 152 await makeGetRequest({
152 if (server.serverNumber !== 3) { 153 url: servers[0].url,
153 await makeGetRequest({ 154 statusCodeExpected: 200,
154 url: server.url, 155 path: '/static/redundancy/' + `${videoUUID}-${file.resolution.id}.mp4`,
155 statusCodeExpected: 200, 156 contentType: null
156 path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`, 157 })
157 contentType: null 158 await makeGetRequest({
158 }) 159 url: servers[1].url,
159 } 160 statusCodeExpected: 200,
161 path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`,
162 contentType: null
163 })
160 } 164 }
161 } 165 }
162 166
163 for (const directory of [ 'test1', 'test2' ]) { 167 for (const directory of [ 'test1/redundancy', 'test2/videos' ]) {
164 const files = await readdir(join(root(), directory, 'videos')) 168 const files = await readdir(join(root(), directory))
165 expect(files).to.have.length.at.least(4) 169 expect(files).to.have.length.at.least(4)
166 170
167 for (const resolution of [ 240, 360, 480, 720 ]) { 171 for (const resolution of [ 240, 360, 480, 720 ]) {
diff --git a/server/tests/api/search/search-activitypub-video-channels.ts b/server/tests/api/search/search-activitypub-video-channels.ts
index a287c5bdf..a411e973b 100644
--- a/server/tests/api/search/search-activitypub-video-channels.ts
+++ b/server/tests/api/search/search-activitypub-video-channels.ts
@@ -17,10 +17,10 @@ import {
17 uploadVideo, 17 uploadVideo,
18 userLogin, 18 userLogin,
19 wait 19 wait
20} from '../../utils' 20} from '../../../../shared/utils'
21import { waitJobs } from '../../utils/server/jobs' 21import { waitJobs } from '../../../../shared/utils/server/jobs'
22import { VideoChannel } from '../../../../shared/models/videos' 22import { VideoChannel } from '../../../../shared/models/videos'
23import { searchVideoChannel } from '../../utils/search/video-channels' 23import { searchVideoChannel } from '../../../../shared/utils/search/video-channels'
24 24
25const expect = chai.expect 25const expect = chai.expect
26 26
diff --git a/server/tests/api/search/search-activitypub-videos.ts b/server/tests/api/search/search-activitypub-videos.ts
index 28f4fac50..f881917e7 100644
--- a/server/tests/api/search/search-activitypub-videos.ts
+++ b/server/tests/api/search/search-activitypub-videos.ts
@@ -16,8 +16,8 @@ import {
16 uploadVideo, 16 uploadVideo,
17 wait, 17 wait,
18 searchVideo 18 searchVideo
19} from '../../utils' 19} from '../../../../shared/utils'
20import { waitJobs } from '../../utils/server/jobs' 20import { waitJobs } from '../../../../shared/utils/server/jobs'
21import { Video, VideoPrivacy } from '../../../../shared/models/videos' 21import { Video, VideoPrivacy } from '../../../../shared/models/videos'
22 22
23const expect = chai.expect 23const expect = chai.expect
diff --git a/server/tests/api/search/search-videos.ts b/server/tests/api/search/search-videos.ts
index f1392ffea..50da837da 100644
--- a/server/tests/api/search/search-videos.ts
+++ b/server/tests/api/search/search-videos.ts
@@ -13,7 +13,7 @@ import {
13 uploadVideo, 13 uploadVideo,
14 wait, 14 wait,
15 immutableAssign 15 immutableAssign
16} from '../../utils' 16} from '../../../../shared/utils'
17 17
18const expect = chai.expect 18const expect = chai.expect
19 19
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts
index facd1688d..bebfc7398 100644
--- a/server/tests/api/server/config.ts
+++ b/server/tests/api/server/config.ts
@@ -4,8 +4,11 @@ import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { About } from '../../../../shared/models/server/about.model' 5import { About } from '../../../../shared/models/server/about.model'
6import { CustomConfig } from '../../../../shared/models/server/custom-config.model' 6import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
7import { deleteCustomConfig, getAbout, killallServers, reRunServer } from '../../utils'
8import { 7import {
8 deleteCustomConfig,
9 getAbout,
10 killallServers,
11 reRunServer,
9 flushTests, 12 flushTests,
10 getConfig, 13 getConfig,
11 getCustomConfig, 14 getCustomConfig,
@@ -13,7 +16,8 @@ import {
13 runServer, 16 runServer,
14 setAccessTokensToServers, 17 setAccessTokensToServers,
15 updateCustomConfig 18 updateCustomConfig
16} from '../../utils/index' 19} from '../../../../shared/utils'
20import { ServerConfig } from '../../../../shared/models'
17 21
18const expect = chai.expect 22const expect = chai.expect
19 23
@@ -29,17 +33,24 @@ function checkInitialConfig (data: CustomConfig) {
29 expect(data.instance.defaultNSFWPolicy).to.equal('display') 33 expect(data.instance.defaultNSFWPolicy).to.equal('display')
30 expect(data.instance.customizations.css).to.be.empty 34 expect(data.instance.customizations.css).to.be.empty
31 expect(data.instance.customizations.javascript).to.be.empty 35 expect(data.instance.customizations.javascript).to.be.empty
36
32 expect(data.services.twitter.username).to.equal('@Chocobozzz') 37 expect(data.services.twitter.username).to.equal('@Chocobozzz')
33 expect(data.services.twitter.whitelisted).to.be.false 38 expect(data.services.twitter.whitelisted).to.be.false
39
34 expect(data.cache.previews.size).to.equal(1) 40 expect(data.cache.previews.size).to.equal(1)
35 expect(data.cache.captions.size).to.equal(1) 41 expect(data.cache.captions.size).to.equal(1)
42
36 expect(data.signup.enabled).to.be.true 43 expect(data.signup.enabled).to.be.true
37 expect(data.signup.limit).to.equal(4) 44 expect(data.signup.limit).to.equal(4)
38 expect(data.signup.requiresEmailVerification).to.be.false 45 expect(data.signup.requiresEmailVerification).to.be.false
46
39 expect(data.admin.email).to.equal('admin1@example.com') 47 expect(data.admin.email).to.equal('admin1@example.com')
48 expect(data.contactForm.enabled).to.be.true
49
40 expect(data.user.videoQuota).to.equal(5242880) 50 expect(data.user.videoQuota).to.equal(5242880)
41 expect(data.user.videoQuotaDaily).to.equal(-1) 51 expect(data.user.videoQuotaDaily).to.equal(-1)
42 expect(data.transcoding.enabled).to.be.false 52 expect(data.transcoding.enabled).to.be.false
53 expect(data.transcoding.allowAdditionalExtensions).to.be.false
43 expect(data.transcoding.threads).to.equal(2) 54 expect(data.transcoding.threads).to.equal(2)
44 expect(data.transcoding.resolutions['240p']).to.be.true 55 expect(data.transcoding.resolutions['240p']).to.be.true
45 expect(data.transcoding.resolutions['360p']).to.be.true 56 expect(data.transcoding.resolutions['360p']).to.be.true
@@ -59,23 +70,32 @@ function checkUpdatedConfig (data: CustomConfig) {
59 expect(data.instance.defaultNSFWPolicy).to.equal('blur') 70 expect(data.instance.defaultNSFWPolicy).to.equal('blur')
60 expect(data.instance.customizations.javascript).to.equal('alert("coucou")') 71 expect(data.instance.customizations.javascript).to.equal('alert("coucou")')
61 expect(data.instance.customizations.css).to.equal('body { background-color: red; }') 72 expect(data.instance.customizations.css).to.equal('body { background-color: red; }')
73
62 expect(data.services.twitter.username).to.equal('@Kuja') 74 expect(data.services.twitter.username).to.equal('@Kuja')
63 expect(data.services.twitter.whitelisted).to.be.true 75 expect(data.services.twitter.whitelisted).to.be.true
76
64 expect(data.cache.previews.size).to.equal(2) 77 expect(data.cache.previews.size).to.equal(2)
65 expect(data.cache.captions.size).to.equal(3) 78 expect(data.cache.captions.size).to.equal(3)
79
66 expect(data.signup.enabled).to.be.false 80 expect(data.signup.enabled).to.be.false
67 expect(data.signup.limit).to.equal(5) 81 expect(data.signup.limit).to.equal(5)
68 expect(data.signup.requiresEmailVerification).to.be.true 82 expect(data.signup.requiresEmailVerification).to.be.true
83
69 expect(data.admin.email).to.equal('superadmin1@example.com') 84 expect(data.admin.email).to.equal('superadmin1@example.com')
85 expect(data.contactForm.enabled).to.be.false
86
70 expect(data.user.videoQuota).to.equal(5242881) 87 expect(data.user.videoQuota).to.equal(5242881)
71 expect(data.user.videoQuotaDaily).to.equal(318742) 88 expect(data.user.videoQuotaDaily).to.equal(318742)
89
72 expect(data.transcoding.enabled).to.be.true 90 expect(data.transcoding.enabled).to.be.true
73 expect(data.transcoding.threads).to.equal(1) 91 expect(data.transcoding.threads).to.equal(1)
92 expect(data.transcoding.allowAdditionalExtensions).to.be.true
74 expect(data.transcoding.resolutions['240p']).to.be.false 93 expect(data.transcoding.resolutions['240p']).to.be.false
75 expect(data.transcoding.resolutions['360p']).to.be.true 94 expect(data.transcoding.resolutions['360p']).to.be.true
76 expect(data.transcoding.resolutions['480p']).to.be.true 95 expect(data.transcoding.resolutions['480p']).to.be.true
77 expect(data.transcoding.resolutions['720p']).to.be.false 96 expect(data.transcoding.resolutions['720p']).to.be.false
78 expect(data.transcoding.resolutions['1080p']).to.be.false 97 expect(data.transcoding.resolutions['1080p']).to.be.false
98
79 expect(data.import.videos.http.enabled).to.be.false 99 expect(data.import.videos.http.enabled).to.be.false
80 expect(data.import.videos.torrent.enabled).to.be.false 100 expect(data.import.videos.torrent.enabled).to.be.false
81} 101}
@@ -93,7 +113,7 @@ describe('Test config', function () {
93 113
94 it('Should have a correct config on a server with registration enabled', async function () { 114 it('Should have a correct config on a server with registration enabled', async function () {
95 const res = await getConfig(server.url) 115 const res = await getConfig(server.url)
96 const data = res.body 116 const data: ServerConfig = res.body
97 117
98 expect(data.signup.allowed).to.be.true 118 expect(data.signup.allowed).to.be.true
99 }) 119 })
@@ -108,11 +128,23 @@ describe('Test config', function () {
108 ]) 128 ])
109 129
110 const res = await getConfig(server.url) 130 const res = await getConfig(server.url)
111 const data = res.body 131 const data: ServerConfig = res.body
112 132
113 expect(data.signup.allowed).to.be.false 133 expect(data.signup.allowed).to.be.false
114 }) 134 })
115 135
136 it('Should have the correct video allowed extensions', async function () {
137 const res = await getConfig(server.url)
138 const data: ServerConfig = res.body
139
140 expect(data.video.file.extensions).to.have.lengthOf(3)
141 expect(data.video.file.extensions).to.contain('.mp4')
142 expect(data.video.file.extensions).to.contain('.webm')
143 expect(data.video.file.extensions).to.contain('.ogv')
144
145 expect(data.contactForm.enabled).to.be.true
146 })
147
116 it('Should get the customized configuration', async function () { 148 it('Should get the customized configuration', async function () {
117 const res = await getCustomConfig(server.url, server.accessToken) 149 const res = await getCustomConfig(server.url, server.accessToken)
118 const data = res.body as CustomConfig 150 const data = res.body as CustomConfig
@@ -156,12 +188,16 @@ describe('Test config', function () {
156 admin: { 188 admin: {
157 email: 'superadmin1@example.com' 189 email: 'superadmin1@example.com'
158 }, 190 },
191 contactForm: {
192 enabled: false
193 },
159 user: { 194 user: {
160 videoQuota: 5242881, 195 videoQuota: 5242881,
161 videoQuotaDaily: 318742 196 videoQuotaDaily: 318742
162 }, 197 },
163 transcoding: { 198 transcoding: {
164 enabled: true, 199 enabled: true,
200 allowAdditionalExtensions: true,
165 threads: 1, 201 threads: 1,
166 resolutions: { 202 resolutions: {
167 '240p': false, 203 '240p': false,
@@ -190,6 +226,18 @@ describe('Test config', function () {
190 checkUpdatedConfig(data) 226 checkUpdatedConfig(data)
191 }) 227 })
192 228
229 it('Should have the correct updated video allowed extensions', async function () {
230 const res = await getConfig(server.url)
231 const data: ServerConfig = res.body
232
233 expect(data.video.file.extensions).to.have.length.above(3)
234 expect(data.video.file.extensions).to.contain('.mp4')
235 expect(data.video.file.extensions).to.contain('.webm')
236 expect(data.video.file.extensions).to.contain('.ogv')
237 expect(data.video.file.extensions).to.contain('.flv')
238 expect(data.video.file.extensions).to.contain('.mkv')
239 })
240
193 it('Should have the configuration updated after a restart', async function () { 241 it('Should have the configuration updated after a restart', async function () {
194 this.timeout(10000) 242 this.timeout(10000)
195 243
diff --git a/server/tests/api/server/contact-form.ts b/server/tests/api/server/contact-form.ts
new file mode 100644
index 000000000..93221d0a3
--- /dev/null
+++ b/server/tests/api/server/contact-form.ts
@@ -0,0 +1,86 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import { flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, wait } from '../../../../shared/utils'
6import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
7import { waitJobs } from '../../../../shared/utils/server/jobs'
8import { sendContactForm } from '../../../../shared/utils/server/contact-form'
9
10const expect = chai.expect
11
12describe('Test contact form', function () {
13 let server: ServerInfo
14 const emails: object[] = []
15
16 before(async function () {
17 this.timeout(30000)
18
19 await MockSmtpServer.Instance.collectEmails(emails)
20
21 await flushTests()
22
23 const overrideConfig = {
24 smtp: {
25 hostname: 'localhost'
26 }
27 }
28 server = await runServer(1, overrideConfig)
29 await setAccessTokensToServers([ server ])
30 })
31
32 it('Should send a contact form', async function () {
33 this.timeout(10000)
34
35 await sendContactForm({
36 url: server.url,
37 fromEmail: 'toto@example.com',
38 body: 'my super message',
39 fromName: 'Super toto'
40 })
41
42 await waitJobs(server)
43
44 expect(emails).to.have.lengthOf(1)
45
46 const email = emails[0]
47
48 expect(email['from'][0]['address']).equal('toto@example.com')
49 expect(email['to'][0]['address']).equal('admin1@example.com')
50 expect(email['subject']).contains('Contact form')
51 expect(email['text']).contains('my super message')
52 })
53
54 it('Should not be able to send another contact form because of the anti spam checker', async function () {
55 await sendContactForm({
56 url: server.url,
57 fromEmail: 'toto@example.com',
58 body: 'my super message',
59 fromName: 'Super toto'
60 })
61
62 await sendContactForm({
63 url: server.url,
64 fromEmail: 'toto@example.com',
65 body: 'my super message',
66 fromName: 'Super toto',
67 expectedStatus: 403
68 })
69 })
70
71 it('Should be able to send another contact form after a while', async function () {
72 await wait(1000)
73
74 await sendContactForm({
75 url: server.url,
76 fromEmail: 'toto@example.com',
77 body: 'my super message',
78 fromName: 'Super toto'
79 })
80 })
81
82 after(async function () {
83 MockSmtpServer.Instance.kill()
84 killallServers([ server ])
85 })
86})
diff --git a/server/tests/api/server/email.ts b/server/tests/api/server/email.ts
index 713a27143..f96c57b66 100644
--- a/server/tests/api/server/email.ts
+++ b/server/tests/api/server/email.ts
@@ -14,11 +14,14 @@ import {
14 unblockUser, 14 unblockUser,
15 uploadVideo, 15 uploadVideo,
16 userLogin, 16 userLogin,
17 verifyEmail 17 verifyEmail,
18} from '../../utils' 18 flushTests,
19import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index' 19 killallServers,
20import { mockSmtpServer } from '../../utils/miscs/email' 20 ServerInfo,
21import { waitJobs } from '../../utils/server/jobs' 21 setAccessTokensToServers
22} from '../../../../shared/utils'
23import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
24import { waitJobs } from '../../../../shared/utils/server/jobs'
22 25
23const expect = chai.expect 26const expect = chai.expect
24 27
@@ -38,7 +41,7 @@ describe('Test emails', function () {
38 before(async function () { 41 before(async function () {
39 this.timeout(30000) 42 this.timeout(30000)
40 43
41 await mockSmtpServer(emails) 44 await MockSmtpServer.Instance.collectEmails(emails)
42 45
43 await flushTests() 46 await flushTests()
44 47
@@ -248,6 +251,7 @@ describe('Test emails', function () {
248 }) 251 })
249 252
250 after(async function () { 253 after(async function () {
254 MockSmtpServer.Instance.kill()
251 killallServers([ server ]) 255 killallServers([ server ])
252 }) 256 })
253}) 257})
diff --git a/server/tests/api/server/follow-constraints.ts b/server/tests/api/server/follow-constraints.ts
index 3135fc568..8bb073c41 100644
--- a/server/tests/api/server/follow-constraints.ts
+++ b/server/tests/api/server/follow-constraints.ts
@@ -2,11 +2,21 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { doubleFollow, getAccountVideos, getVideo, getVideoChannelVideos, getVideoWithToken } from '../../utils' 5import {
6import { flushAndRunMultipleServers, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils/index' 6 doubleFollow,
7import { unfollow } from '../../utils/server/follows' 7 getAccountVideos,
8import { userLogin } from '../../utils/users/login' 8 getVideo,
9import { createUser } from '../../utils/users/users' 9 getVideoChannelVideos,
10 getVideoWithToken,
11 flushAndRunMultipleServers,
12 killallServers,
13 ServerInfo,
14 setAccessTokensToServers,
15 uploadVideo
16} from '../../../../shared/utils'
17import { unfollow } from '../../../../shared/utils/server/follows'
18import { userLogin } from '../../../../shared/utils/users/login'
19import { createUser } from '../../../../shared/utils/users/users'
10 20
11const expect = chai.expect 21const expect = chai.expect
12 22
diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts
index e80e93e7f..b0fc5d293 100644
--- a/server/tests/api/server/follows.ts
+++ b/server/tests/api/server/follows.ts
@@ -4,7 +4,7 @@ import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { Video, VideoPrivacy } from '../../../../shared/models/videos' 5import { Video, VideoPrivacy } from '../../../../shared/models/videos'
6import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 6import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
7import { completeVideoCheck } from '../../utils' 7import { completeVideoCheck } from '../../../../shared/utils'
8import { 8import {
9 flushAndRunMultipleServers, 9 flushAndRunMultipleServers,
10 getVideosList, 10 getVideosList,
@@ -12,21 +12,26 @@ import {
12 ServerInfo, 12 ServerInfo,
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 uploadVideo 14 uploadVideo
15} from '../../utils/index' 15} from '../../../../shared/utils/index'
16import { dateIsValid } from '../../utils/miscs/miscs' 16import { dateIsValid } from '../../../../shared/utils/miscs/miscs'
17import { follow, getFollowersListPaginationAndSort, getFollowingListPaginationAndSort, unfollow } from '../../utils/server/follows' 17import {
18import { expectAccountFollows } from '../../utils/users/accounts' 18 follow,
19import { userLogin } from '../../utils/users/login' 19 getFollowersListPaginationAndSort,
20import { createUser } from '../../utils/users/users' 20 getFollowingListPaginationAndSort,
21 unfollow
22} from '../../../../shared/utils/server/follows'
23import { expectAccountFollows } from '../../../../shared/utils/users/accounts'
24import { userLogin } from '../../../../shared/utils/users/login'
25import { createUser } from '../../../../shared/utils/users/users'
21import { 26import {
22 addVideoCommentReply, 27 addVideoCommentReply,
23 addVideoCommentThread, 28 addVideoCommentThread,
24 getVideoCommentThreads, 29 getVideoCommentThreads,
25 getVideoThreadComments 30 getVideoThreadComments
26} from '../../utils/videos/video-comments' 31} from '../../../../shared/utils/videos/video-comments'
27import { rateVideo } from '../../utils/videos/videos' 32import { rateVideo } from '../../../../shared/utils/videos/videos'
28import { waitJobs } from '../../utils/server/jobs' 33import { waitJobs } from '../../../../shared/utils/server/jobs'
29import { createVideoCaption, listVideoCaptions, testCaptionFile } from '../../utils/videos/video-captions' 34import { createVideoCaption, listVideoCaptions, testCaptionFile } from '../../../../shared/utils/videos/video-captions'
30import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model' 35import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
31 36
32const expect = chai.expect 37const expect = chai.expect
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts
index 0421b2b40..cd7baadad 100644
--- a/server/tests/api/server/handle-down.ts
+++ b/server/tests/api/server/handle-down.ts
@@ -5,24 +5,30 @@ import 'mocha'
5import { JobState, Video } from '../../../../shared/models' 5import { JobState, Video } from '../../../../shared/models'
6import { VideoPrivacy } from '../../../../shared/models/videos' 6import { VideoPrivacy } from '../../../../shared/models/videos'
7import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 7import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
8import { completeVideoCheck, getVideo, immutableAssign, reRunServer, unfollow, updateVideo, viewVideo } from '../../utils' 8
9import { 9import {
10 completeVideoCheck,
10 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
12 getVideo,
11 getVideosList, 13 getVideosList,
14 immutableAssign,
12 killallServers, 15 killallServers,
16 reRunServer,
13 ServerInfo, 17 ServerInfo,
14 setAccessTokensToServers, 18 setAccessTokensToServers,
19 unfollow,
20 updateVideo,
15 uploadVideo, 21 uploadVideo,
16 wait 22 wait
17} from '../../utils/index' 23} from '../../../../shared/utils'
18import { follow, getFollowersListPaginationAndSort } from '../../utils/server/follows' 24import { follow, getFollowersListPaginationAndSort } from '../../../../shared/utils/server/follows'
19import { getJobsListPaginationAndSort, waitJobs } from '../../utils/server/jobs' 25import { getJobsListPaginationAndSort, waitJobs } from '../../../../shared/utils/server/jobs'
20import { 26import {
21 addVideoCommentReply, 27 addVideoCommentReply,
22 addVideoCommentThread, 28 addVideoCommentThread,
23 getVideoCommentThreads, 29 getVideoCommentThreads,
24 getVideoThreadComments 30 getVideoThreadComments
25} from '../../utils/videos/video-comments' 31} from '../../../../shared/utils/videos/video-comments'
26 32
27const expect = chai.expect 33const expect = chai.expect
28 34
diff --git a/server/tests/api/server/index.ts b/server/tests/api/server/index.ts
index 6afcab1f9..1f80cc6cf 100644
--- a/server/tests/api/server/index.ts
+++ b/server/tests/api/server/index.ts
@@ -1,4 +1,5 @@
1import './config' 1import './config'
2import './contact-form'
2import './email' 3import './email'
3import './follow-constraints' 4import './follow-constraints'
4import './follows' 5import './follows'
diff --git a/server/tests/api/server/jobs.ts b/server/tests/api/server/jobs.ts
index cd59d9a1b..52948b1d6 100644
--- a/server/tests/api/server/jobs.ts
+++ b/server/tests/api/server/jobs.ts
@@ -2,12 +2,12 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index' 5import { killallServers, ServerInfo, setAccessTokensToServers } from '../../../../shared/utils/index'
6import { doubleFollow } from '../../utils/server/follows' 6import { doubleFollow } from '../../../../shared/utils/server/follows'
7import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../utils/server/jobs' 7import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../../../shared/utils/server/jobs'
8import { flushAndRunMultipleServers } from '../../utils/server/servers' 8import { flushAndRunMultipleServers } from '../../../../shared/utils/server/servers'
9import { uploadVideo } from '../../utils/videos/videos' 9import { uploadVideo } from '../../../../shared/utils/videos/videos'
10import { dateIsValid } from '../../utils/miscs/miscs' 10import { dateIsValid } from '../../../../shared/utils/miscs/miscs'
11 11
12const expect = chai.expect 12const expect = chai.expect
13 13
diff --git a/server/tests/api/server/no-client.ts b/server/tests/api/server/no-client.ts
index 6d6ce8532..3b95ce945 100644
--- a/server/tests/api/server/no-client.ts
+++ b/server/tests/api/server/no-client.ts
@@ -4,8 +4,8 @@ import {
4 flushTests, 4 flushTests,
5 killallServers, 5 killallServers,
6 ServerInfo 6 ServerInfo
7} from '../../utils/index' 7} from '../../../../shared/utils'
8import { runServer } from '../../utils/server/servers' 8import { runServer } from '../../../../shared/utils/server/servers'
9 9
10describe('Start and stop server without web client routes', function () { 10describe('Start and stop server without web client routes', function () {
11 let server: ServerInfo 11 let server: ServerInfo
diff --git a/server/tests/api/server/reverse-proxy.ts b/server/tests/api/server/reverse-proxy.ts
index e2c2a293e..d4c08c346 100644
--- a/server/tests/api/server/reverse-proxy.ts
+++ b/server/tests/api/server/reverse-proxy.ts
@@ -15,7 +15,7 @@ import {
15 userLogin, 15 userLogin,
16 viewVideo, 16 viewVideo,
17 wait 17 wait
18} from '../../utils' 18} from '../../../../shared/utils'
19const expect = chai.expect 19const expect = chai.expect
20 20
21import { 21import {
@@ -23,7 +23,7 @@ import {
23 flushTests, 23 flushTests,
24 runServer, 24 runServer,
25 registerUser, getCustomConfig, setAccessTokensToServers, updateCustomConfig 25 registerUser, getCustomConfig, setAccessTokensToServers, updateCustomConfig
26} from '../../utils/index' 26} from '../../../../shared/utils/index'
27 27
28describe('Test application behind a reverse proxy', function () { 28describe('Test application behind a reverse proxy', function () {
29 let server = null 29 let server = null
diff --git a/server/tests/api/server/stats.ts b/server/tests/api/server/stats.ts
index cb229e876..aaa6c62f7 100644
--- a/server/tests/api/server/stats.ts
+++ b/server/tests/api/server/stats.ts
@@ -13,11 +13,11 @@ import {
13 uploadVideo, 13 uploadVideo,
14 viewVideo, 14 viewVideo,
15 wait 15 wait
16} from '../../utils' 16} from '../../../../shared/utils'
17import { flushTests, setAccessTokensToServers } from '../../utils/index' 17import { flushTests, setAccessTokensToServers } from '../../../../shared/utils/index'
18import { getStats } from '../../utils/server/stats' 18import { getStats } from '../../../../shared/utils/server/stats'
19import { addVideoCommentThread } from '../../utils/videos/video-comments' 19import { addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
20import { waitJobs } from '../../utils/server/jobs' 20import { waitJobs } from '../../../../shared/utils/server/jobs'
21 21
22const expect = chai.expect 22const expect = chai.expect
23 23
@@ -39,7 +39,7 @@ describe('Test stats (excluding redundancy)', function () {
39 } 39 }
40 await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) 40 await createUser(servers[0].url, servers[0].accessToken, user.username, user.password)
41 41
42 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, {}) 42 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { fixture: 'video_short.webm' })
43 const videoUUID = resVideo.body.video.uuid 43 const videoUUID = resVideo.body.video.uuid
44 44
45 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment') 45 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment')
@@ -60,6 +60,7 @@ describe('Test stats (excluding redundancy)', function () {
60 expect(data.totalLocalVideoComments).to.equal(1) 60 expect(data.totalLocalVideoComments).to.equal(1)
61 expect(data.totalLocalVideos).to.equal(1) 61 expect(data.totalLocalVideos).to.equal(1)
62 expect(data.totalLocalVideoViews).to.equal(1) 62 expect(data.totalLocalVideoViews).to.equal(1)
63 expect(data.totalLocalVideoFilesSize).to.equal(218910)
63 expect(data.totalUsers).to.equal(2) 64 expect(data.totalUsers).to.equal(2)
64 expect(data.totalVideoComments).to.equal(1) 65 expect(data.totalVideoComments).to.equal(1)
65 expect(data.totalVideos).to.equal(1) 66 expect(data.totalVideos).to.equal(1)
@@ -74,6 +75,7 @@ describe('Test stats (excluding redundancy)', function () {
74 expect(data.totalLocalVideoComments).to.equal(0) 75 expect(data.totalLocalVideoComments).to.equal(0)
75 expect(data.totalLocalVideos).to.equal(0) 76 expect(data.totalLocalVideos).to.equal(0)
76 expect(data.totalLocalVideoViews).to.equal(0) 77 expect(data.totalLocalVideoViews).to.equal(0)
78 expect(data.totalLocalVideoFilesSize).to.equal(0)
77 expect(data.totalUsers).to.equal(1) 79 expect(data.totalUsers).to.equal(1)
78 expect(data.totalVideoComments).to.equal(1) 80 expect(data.totalVideoComments).to.equal(1)
79 expect(data.totalVideos).to.equal(1) 81 expect(data.totalVideos).to.equal(1)
diff --git a/server/tests/api/server/tracker.ts b/server/tests/api/server/tracker.ts
index 856f2f4d1..25ca00029 100644
--- a/server/tests/api/server/tracker.ts
+++ b/server/tests/api/server/tracker.ts
@@ -2,8 +2,8 @@
2 2
3import * as magnetUtil from 'magnet-uri' 3import * as magnetUtil from 'magnet-uri'
4import 'mocha' 4import 'mocha'
5import { getVideo, killallServers, runServer, ServerInfo, uploadVideo } from '../../utils' 5import { getVideo, killallServers, runServer, ServerInfo, uploadVideo } from '../../../../shared/utils'
6import { flushTests, setAccessTokensToServers } from '../../utils/index' 6import { flushTests, setAccessTokensToServers } from '../../../../shared/utils/index'
7import { VideoDetails } from '../../../../shared/models/videos' 7import { VideoDetails } from '../../../../shared/models/videos'
8import * as WebTorrent from 'webtorrent' 8import * as WebTorrent from 'webtorrent'
9 9
diff --git a/server/tests/api/users/blocklist.ts b/server/tests/api/users/blocklist.ts
index eed4b9f3e..4bca27a94 100644
--- a/server/tests/api/users/blocklist.ts
+++ b/server/tests/api/users/blocklist.ts
@@ -12,16 +12,16 @@ import {
12 ServerInfo, 12 ServerInfo,
13 uploadVideo, 13 uploadVideo,
14 userLogin 14 userLogin
15} from '../../utils/index' 15} from '../../../../shared/utils/index'
16import { setAccessTokensToServers } from '../../utils/users/login' 16import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
17import { getVideosListWithToken, getVideosList } from '../../utils/videos/videos' 17import { getVideosListWithToken, getVideosList } from '../../../../shared/utils/videos/videos'
18import { 18import {
19 addVideoCommentReply, 19 addVideoCommentReply,
20 addVideoCommentThread, 20 addVideoCommentThread,
21 getVideoCommentThreads, 21 getVideoCommentThreads,
22 getVideoThreadComments 22 getVideoThreadComments
23} from '../../utils/videos/video-comments' 23} from '../../../../shared/utils/videos/video-comments'
24import { waitJobs } from '../../utils/server/jobs' 24import { waitJobs } from '../../../../shared/utils/server/jobs'
25import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 25import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
26import { 26import {
27 addAccountToAccountBlocklist, 27 addAccountToAccountBlocklist,
@@ -36,7 +36,7 @@ import {
36 removeAccountFromServerBlocklist, 36 removeAccountFromServerBlocklist,
37 removeServerFromAccountBlocklist, 37 removeServerFromAccountBlocklist,
38 removeServerFromServerBlocklist 38 removeServerFromServerBlocklist
39} from '../../utils/users/blocklist' 39} from '../../../../shared/utils/users/blocklist'
40 40
41const expect = chai.expect 41const expect = chai.expect
42 42
diff --git a/server/tests/api/users/index.ts b/server/tests/api/users/index.ts
index ff433315d..52ba6984e 100644
--- a/server/tests/api/users/index.ts
+++ b/server/tests/api/users/index.ts
@@ -1,5 +1,6 @@
1import './users-verification'
2import './user-notifications'
1import './blocklist' 3import './blocklist'
2import './user-subscriptions' 4import './user-subscriptions'
3import './users' 5import './users'
4import './users-multiple-servers' 6import './users-multiple-servers'
5import './users-verification'
diff --git a/server/tests/api/users/user-notifications.ts b/server/tests/api/users/user-notifications.ts
new file mode 100644
index 000000000..5260d64cc
--- /dev/null
+++ b/server/tests/api/users/user-notifications.ts
@@ -0,0 +1,1017 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import {
6 addVideoToBlacklist,
7 createUser,
8 doubleFollow,
9 flushAndRunMultipleServers,
10 flushTests,
11 getMyUserInformation,
12 immutableAssign,
13 registerUser,
14 removeVideoFromBlacklist,
15 reportVideoAbuse,
16 updateMyUser,
17 updateVideo,
18 updateVideoChannel,
19 userLogin,
20 wait
21} from '../../../../shared/utils'
22import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index'
23import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
24import { waitJobs } from '../../../../shared/utils/server/jobs'
25import { getUserNotificationSocket } from '../../../../shared/utils/socket/socket-io'
26import {
27 checkCommentMention,
28 CheckerBaseParams,
29 checkMyVideoImportIsFinished,
30 checkNewActorFollow,
31 checkNewBlacklistOnMyVideo,
32 checkNewCommentOnMyVideo,
33 checkNewVideoAbuseForModerators,
34 checkNewVideoFromSubscription,
35 checkUserRegistered,
36 checkVideoIsPublished,
37 getLastNotification,
38 getUserNotifications,
39 markAsReadNotifications,
40 updateMyNotificationSettings,
41 markAsReadAllNotifications
42} from '../../../../shared/utils/users/user-notifications'
43import {
44 User,
45 UserNotification,
46 UserNotificationSetting,
47 UserNotificationSettingValue,
48 UserNotificationType
49} from '../../../../shared/models/users'
50import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
51import { addUserSubscription, removeUserSubscription } from '../../../../shared/utils/users/user-subscriptions'
52import { VideoPrivacy } from '../../../../shared/models/videos'
53import { getBadVideoUrl, getYoutubeVideoUrl, importVideo } from '../../../../shared/utils/videos/video-imports'
54import { addVideoCommentReply, addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
55import * as uuidv4 from 'uuid/v4'
56import { addAccountToAccountBlocklist, removeAccountFromAccountBlocklist } from '../../../../shared/utils/users/blocklist'
57
58const expect = chai.expect
59
60async function uploadVideoByRemoteAccount (servers: ServerInfo[], additionalParams: any = {}) {
61 const name = 'remote video ' + uuidv4()
62
63 const data = Object.assign({ name }, additionalParams)
64 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, data)
65
66 await waitJobs(servers)
67
68 return { uuid: res.body.video.uuid, name }
69}
70
71async function uploadVideoByLocalAccount (servers: ServerInfo[], additionalParams: any = {}) {
72 const name = 'local video ' + uuidv4()
73
74 const data = Object.assign({ name }, additionalParams)
75 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, data)
76
77 await waitJobs(servers)
78
79 return { uuid: res.body.video.uuid, name }
80}
81
82describe('Test users notifications', function () {
83 let servers: ServerInfo[] = []
84 let userAccessToken: string
85 let userNotifications: UserNotification[] = []
86 let adminNotifications: UserNotification[] = []
87 let adminNotificationsServer2: UserNotification[] = []
88 const emails: object[] = []
89 let channelId: number
90
91 const allNotificationSettings: UserNotificationSetting = {
92 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
93 newCommentOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
94 videoAbuseAsModerator: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
95 blacklistOnMyVideo: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
96 myVideoImportFinished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
97 myVideoPublished: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
98 commentMention: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
99 newFollow: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL,
100 newUserRegistration: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
101 }
102
103 before(async function () {
104 this.timeout(120000)
105
106 await MockSmtpServer.Instance.collectEmails(emails)
107
108 await flushTests()
109
110 const overrideConfig = {
111 smtp: {
112 hostname: 'localhost'
113 }
114 }
115 servers = await flushAndRunMultipleServers(2, overrideConfig)
116
117 // Get the access tokens
118 await setAccessTokensToServers(servers)
119
120 // Server 1 and server 2 follow each other
121 await doubleFollow(servers[0], servers[1])
122
123 await waitJobs(servers)
124
125 const user = {
126 username: 'user_1',
127 password: 'super password'
128 }
129 await createUser(servers[0].url, servers[0].accessToken, user.username, user.password, 10 * 1000 * 1000)
130 userAccessToken = await userLogin(servers[0], user)
131
132 await updateMyNotificationSettings(servers[0].url, userAccessToken, allNotificationSettings)
133 await updateMyNotificationSettings(servers[0].url, servers[0].accessToken, allNotificationSettings)
134 await updateMyNotificationSettings(servers[1].url, servers[1].accessToken, allNotificationSettings)
135
136 {
137 const socket = getUserNotificationSocket(servers[ 0 ].url, userAccessToken)
138 socket.on('new-notification', n => userNotifications.push(n))
139 }
140 {
141 const socket = getUserNotificationSocket(servers[ 0 ].url, servers[0].accessToken)
142 socket.on('new-notification', n => adminNotifications.push(n))
143 }
144 {
145 const socket = getUserNotificationSocket(servers[ 1 ].url, servers[1].accessToken)
146 socket.on('new-notification', n => adminNotificationsServer2.push(n))
147 }
148
149 {
150 const resChannel = await getMyUserInformation(servers[0].url, servers[0].accessToken)
151 channelId = resChannel.body.videoChannels[0].id
152 }
153 })
154
155 describe('New video from my subscription notification', function () {
156 let baseParams: CheckerBaseParams
157
158 before(() => {
159 baseParams = {
160 server: servers[0],
161 emails,
162 socketNotifications: userNotifications,
163 token: userAccessToken
164 }
165 })
166
167 it('Should not send notifications if the user does not follow the video publisher', async function () {
168 await uploadVideoByLocalAccount(servers)
169
170 const notification = await getLastNotification(servers[ 0 ].url, userAccessToken)
171 expect(notification).to.be.undefined
172
173 expect(emails).to.have.lengthOf(0)
174 expect(userNotifications).to.have.lengthOf(0)
175 })
176
177 it('Should send a new video notification if the user follows the local video publisher', async function () {
178 this.timeout(15000)
179
180 await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:9001')
181 await waitJobs(servers)
182
183 const { name, uuid } = await uploadVideoByLocalAccount(servers)
184 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
185 })
186
187 it('Should send a new video notification from a remote account', async function () {
188 this.timeout(50000) // Server 2 has transcoding enabled
189
190 await addUserSubscription(servers[0].url, userAccessToken, 'root_channel@localhost:9002')
191 await waitJobs(servers)
192
193 const { name, uuid } = await uploadVideoByRemoteAccount(servers)
194 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
195 })
196
197 it('Should send a new video notification on a scheduled publication', async function () {
198 this.timeout(20000)
199
200 // In 2 seconds
201 let updateAt = new Date(new Date().getTime() + 2000)
202
203 const data = {
204 privacy: VideoPrivacy.PRIVATE,
205 scheduleUpdate: {
206 updateAt: updateAt.toISOString(),
207 privacy: VideoPrivacy.PUBLIC
208 }
209 }
210 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
211
212 await wait(6000)
213 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
214 })
215
216 it('Should send a new video notification on a remote scheduled publication', async function () {
217 this.timeout(20000)
218
219 // In 2 seconds
220 let updateAt = new Date(new Date().getTime() + 2000)
221
222 const data = {
223 privacy: VideoPrivacy.PRIVATE,
224 scheduleUpdate: {
225 updateAt: updateAt.toISOString(),
226 privacy: VideoPrivacy.PUBLIC
227 }
228 }
229 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
230 await waitJobs(servers)
231
232 await wait(6000)
233 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
234 })
235
236 it('Should not send a notification before the video is published', async function () {
237 this.timeout(20000)
238
239 let updateAt = new Date(new Date().getTime() + 100000)
240
241 const data = {
242 privacy: VideoPrivacy.PRIVATE,
243 scheduleUpdate: {
244 updateAt: updateAt.toISOString(),
245 privacy: VideoPrivacy.PUBLIC
246 }
247 }
248 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
249
250 await wait(6000)
251 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
252 })
253
254 it('Should send a new video notification when a video becomes public', async function () {
255 this.timeout(10000)
256
257 const data = { privacy: VideoPrivacy.PRIVATE }
258 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
259
260 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
261
262 await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
263
264 await wait(500)
265 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
266 })
267
268 it('Should send a new video notification when a remote video becomes public', async function () {
269 this.timeout(20000)
270
271 const data = { privacy: VideoPrivacy.PRIVATE }
272 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
273
274 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
275
276 await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.PUBLIC })
277
278 await waitJobs(servers)
279 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
280 })
281
282 it('Should not send a new video notification when a video becomes unlisted', async function () {
283 this.timeout(20000)
284
285 const data = { privacy: VideoPrivacy.PRIVATE }
286 const { name, uuid } = await uploadVideoByLocalAccount(servers, data)
287
288 await updateVideo(servers[0].url, servers[0].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
289
290 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
291 })
292
293 it('Should not send a new video notification when a remote video becomes unlisted', async function () {
294 this.timeout(20000)
295
296 const data = { privacy: VideoPrivacy.PRIVATE }
297 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
298
299 await updateVideo(servers[1].url, servers[1].accessToken, uuid, { privacy: VideoPrivacy.UNLISTED })
300
301 await waitJobs(servers)
302 await checkNewVideoFromSubscription(baseParams, name, uuid, 'absence')
303 })
304
305 it('Should send a new video notification after a video import', async function () {
306 this.timeout(30000)
307
308 const name = 'video import ' + uuidv4()
309
310 const attributes = {
311 name,
312 channelId,
313 privacy: VideoPrivacy.PUBLIC,
314 targetUrl: getYoutubeVideoUrl()
315 }
316 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
317 const uuid = res.body.video.uuid
318
319 await waitJobs(servers)
320
321 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
322 })
323 })
324
325 describe('Comment on my video notifications', function () {
326 let baseParams: CheckerBaseParams
327
328 before(() => {
329 baseParams = {
330 server: servers[0],
331 emails,
332 socketNotifications: userNotifications,
333 token: userAccessToken
334 }
335 })
336
337 it('Should not send a new comment notification after a comment on another video', async function () {
338 this.timeout(10000)
339
340 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
341 const uuid = resVideo.body.video.uuid
342
343 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
344 const commentId = resComment.body.comment.id
345
346 await wait(500)
347 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
348 })
349
350 it('Should not send a new comment notification if I comment my own video', async function () {
351 this.timeout(10000)
352
353 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
354 const uuid = resVideo.body.video.uuid
355
356 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, 'comment')
357 const commentId = resComment.body.comment.id
358
359 await wait(500)
360 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
361 })
362
363 it('Should not send a new comment notification if the account is muted', async function () {
364 this.timeout(10000)
365
366 await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
367
368 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
369 const uuid = resVideo.body.video.uuid
370
371 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
372 const commentId = resComment.body.comment.id
373
374 await wait(500)
375 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'absence')
376
377 await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
378 })
379
380 it('Should send a new comment notification after a local comment on my video', async function () {
381 this.timeout(10000)
382
383 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
384 const uuid = resVideo.body.video.uuid
385
386 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
387 const commentId = resComment.body.comment.id
388
389 await wait(500)
390 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
391 })
392
393 it('Should send a new comment notification after a remote comment on my video', async function () {
394 this.timeout(10000)
395
396 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
397 const uuid = resVideo.body.video.uuid
398
399 await waitJobs(servers)
400
401 const resComment = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
402 const commentId = resComment.body.comment.id
403
404 await waitJobs(servers)
405 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, commentId, 'presence')
406 })
407
408 it('Should send a new comment notification after a local reply on my video', async function () {
409 this.timeout(10000)
410
411 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
412 const uuid = resVideo.body.video.uuid
413
414 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, 'comment')
415 const threadId = resThread.body.comment.id
416
417 const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'reply')
418 const commentId = resComment.body.comment.id
419
420 await wait(500)
421 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
422 })
423
424 it('Should send a new comment notification after a remote reply on my video', async function () {
425 this.timeout(10000)
426
427 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
428 const uuid = resVideo.body.video.uuid
429 await waitJobs(servers)
430
431 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'comment')
432 const threadId = resThread.body.comment.id
433
434 const resComment = await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, 'reply')
435 const commentId = resComment.body.comment.id
436
437 await waitJobs(servers)
438 await checkNewCommentOnMyVideo(baseParams, uuid, commentId, threadId, 'presence')
439 })
440 })
441
442 describe('Mention notifications', function () {
443 let baseParams: CheckerBaseParams
444
445 before(async () => {
446 baseParams = {
447 server: servers[0],
448 emails,
449 socketNotifications: userNotifications,
450 token: userAccessToken
451 }
452
453 await updateMyUser({
454 url: servers[0].url,
455 accessToken: servers[0].accessToken,
456 displayName: 'super root name'
457 })
458
459 await updateMyUser({
460 url: servers[1].url,
461 accessToken: servers[1].accessToken,
462 displayName: 'super root 2 name'
463 })
464 })
465
466 it('Should not send a new mention comment notification if I mention the video owner', async function () {
467 this.timeout(10000)
468
469 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name: 'super video' })
470 const uuid = resVideo.body.video.uuid
471
472 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello')
473 const commentId = resComment.body.comment.id
474
475 await wait(500)
476 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
477 })
478
479 it('Should not send a new mention comment notification if I mention myself', async function () {
480 this.timeout(10000)
481
482 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
483 const uuid = resVideo.body.video.uuid
484
485 const resComment = await addVideoCommentThread(servers[0].url, userAccessToken, uuid, '@user_1 hello')
486 const commentId = resComment.body.comment.id
487
488 await wait(500)
489 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
490 })
491
492 it('Should not send a new mention notification if the account is muted', async function () {
493 this.timeout(10000)
494
495 await addAccountToAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
496
497 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
498 const uuid = resVideo.body.video.uuid
499
500 const resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello')
501 const commentId = resComment.body.comment.id
502
503 await wait(500)
504 await checkCommentMention(baseParams, uuid, commentId, commentId, 'super root name', 'absence')
505
506 await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root')
507 })
508
509 it('Should send a new mention notification after local comments', async function () {
510 this.timeout(10000)
511
512 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
513 const uuid = resVideo.body.video.uuid
514
515 const resThread = await addVideoCommentThread(servers[0].url, servers[0].accessToken, uuid, '@user_1 hello 1')
516 const threadId = resThread.body.comment.id
517
518 await wait(500)
519 await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root name', 'presence')
520
521 const resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, uuid, threadId, 'hello 2 @user_1')
522 const commentId = resComment.body.comment.id
523
524 await wait(500)
525 await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root name', 'presence')
526 })
527
528 it('Should send a new mention notification after remote comments', async function () {
529 this.timeout(20000)
530
531 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' })
532 const uuid = resVideo.body.video.uuid
533
534 await waitJobs(servers)
535 const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, 'hello @user_1@localhost:9001 1')
536 const threadId = resThread.body.comment.id
537
538 await waitJobs(servers)
539 await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root 2 name', 'presence')
540
541 const text = '@user_1@localhost:9001 hello 2 @root@localhost:9001'
542 const resComment = await addVideoCommentReply(servers[1].url, servers[1].accessToken, uuid, threadId, text)
543 const commentId = resComment.body.comment.id
544
545 await waitJobs(servers)
546 await checkCommentMention(baseParams, uuid, commentId, threadId, 'super root 2 name', 'presence')
547 })
548 })
549
550 describe('Video abuse for moderators notification' , function () {
551 let baseParams: CheckerBaseParams
552
553 before(() => {
554 baseParams = {
555 server: servers[0],
556 emails,
557 socketNotifications: adminNotifications,
558 token: servers[0].accessToken
559 }
560 })
561
562 it('Should send a notification to moderators on local video abuse', async function () {
563 this.timeout(10000)
564
565 const name = 'video for abuse ' + uuidv4()
566 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
567 const uuid = resVideo.body.video.uuid
568
569 await reportVideoAbuse(servers[0].url, servers[0].accessToken, uuid, 'super reason')
570
571 await waitJobs(servers)
572 await checkNewVideoAbuseForModerators(baseParams, uuid, name, 'presence')
573 })
574
575 it('Should send a notification to moderators on remote video abuse', async function () {
576 this.timeout(10000)
577
578 const name = 'video for abuse ' + uuidv4()
579 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
580 const uuid = resVideo.body.video.uuid
581
582 await waitJobs(servers)
583
584 await reportVideoAbuse(servers[1].url, servers[1].accessToken, uuid, 'super reason')
585
586 await waitJobs(servers)
587 await checkNewVideoAbuseForModerators(baseParams, uuid, name, 'presence')
588 })
589 })
590
591 describe('Video blacklist on my video', function () {
592 let baseParams: CheckerBaseParams
593
594 before(() => {
595 baseParams = {
596 server: servers[0],
597 emails,
598 socketNotifications: userNotifications,
599 token: userAccessToken
600 }
601 })
602
603 it('Should send a notification to video owner on blacklist', async function () {
604 this.timeout(10000)
605
606 const name = 'video for abuse ' + uuidv4()
607 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
608 const uuid = resVideo.body.video.uuid
609
610 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
611
612 await waitJobs(servers)
613 await checkNewBlacklistOnMyVideo(baseParams, uuid, name, 'blacklist')
614 })
615
616 it('Should send a notification to video owner on unblacklist', async function () {
617 this.timeout(10000)
618
619 const name = 'video for abuse ' + uuidv4()
620 const resVideo = await uploadVideo(servers[0].url, userAccessToken, { name })
621 const uuid = resVideo.body.video.uuid
622
623 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, uuid)
624
625 await waitJobs(servers)
626 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, uuid)
627 await waitJobs(servers)
628
629 await wait(500)
630 await checkNewBlacklistOnMyVideo(baseParams, uuid, name, 'unblacklist')
631 })
632 })
633
634 describe('My video is published', function () {
635 let baseParams: CheckerBaseParams
636
637 before(() => {
638 baseParams = {
639 server: servers[1],
640 emails,
641 socketNotifications: adminNotificationsServer2,
642 token: servers[1].accessToken
643 }
644 })
645
646 it('Should not send a notification if transcoding is not enabled', async function () {
647 const { name, uuid } = await uploadVideoByLocalAccount(servers)
648 await waitJobs(servers)
649
650 await checkVideoIsPublished(baseParams, name, uuid, 'absence')
651 })
652
653 it('Should not send a notification if the wait transcoding is false', async function () {
654 this.timeout(50000)
655
656 await uploadVideoByRemoteAccount(servers, { waitTranscoding: false })
657 await waitJobs(servers)
658
659 const notification = await getLastNotification(servers[ 0 ].url, userAccessToken)
660 if (notification) {
661 expect(notification.type).to.not.equal(UserNotificationType.MY_VIDEO_PUBLISHED)
662 }
663 })
664
665 it('Should send a notification even if the video is not transcoded in other resolutions', async function () {
666 this.timeout(50000)
667
668 const { name, uuid } = await uploadVideoByRemoteAccount(servers, { waitTranscoding: true, fixture: 'video_short_240p.mp4' })
669 await waitJobs(servers)
670
671 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
672 })
673
674 it('Should send a notification with a transcoded video', async function () {
675 this.timeout(50000)
676
677 const { name, uuid } = await uploadVideoByRemoteAccount(servers, { waitTranscoding: true })
678 await waitJobs(servers)
679
680 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
681 })
682
683 it('Should send a notification when an imported video is transcoded', async function () {
684 this.timeout(50000)
685
686 const name = 'video import ' + uuidv4()
687
688 const attributes = {
689 name,
690 channelId,
691 privacy: VideoPrivacy.PUBLIC,
692 targetUrl: getYoutubeVideoUrl(),
693 waitTranscoding: true
694 }
695 const res = await importVideo(servers[1].url, servers[1].accessToken, attributes)
696 const uuid = res.body.video.uuid
697
698 await waitJobs(servers)
699 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
700 })
701
702 it('Should send a notification when the scheduled update has been proceeded', async function () {
703 this.timeout(70000)
704
705 // In 2 seconds
706 let updateAt = new Date(new Date().getTime() + 2000)
707
708 const data = {
709 privacy: VideoPrivacy.PRIVATE,
710 scheduleUpdate: {
711 updateAt: updateAt.toISOString(),
712 privacy: VideoPrivacy.PUBLIC
713 }
714 }
715 const { name, uuid } = await uploadVideoByRemoteAccount(servers, data)
716
717 await wait(6000)
718 await checkVideoIsPublished(baseParams, name, uuid, 'presence')
719 })
720 })
721
722 describe('My video is imported', function () {
723 let baseParams: CheckerBaseParams
724
725 before(() => {
726 baseParams = {
727 server: servers[0],
728 emails,
729 socketNotifications: adminNotifications,
730 token: servers[0].accessToken
731 }
732 })
733
734 it('Should send a notification when the video import failed', async function () {
735 this.timeout(70000)
736
737 const name = 'video import ' + uuidv4()
738
739 const attributes = {
740 name,
741 channelId,
742 privacy: VideoPrivacy.PRIVATE,
743 targetUrl: getBadVideoUrl()
744 }
745 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
746 const uuid = res.body.video.uuid
747
748 await waitJobs(servers)
749 await checkMyVideoImportIsFinished(baseParams, name, uuid, getBadVideoUrl(), false, 'presence')
750 })
751
752 it('Should send a notification when the video import succeeded', async function () {
753 this.timeout(70000)
754
755 const name = 'video import ' + uuidv4()
756
757 const attributes = {
758 name,
759 channelId,
760 privacy: VideoPrivacy.PRIVATE,
761 targetUrl: getYoutubeVideoUrl()
762 }
763 const res = await importVideo(servers[0].url, servers[0].accessToken, attributes)
764 const uuid = res.body.video.uuid
765
766 await waitJobs(servers)
767 await checkMyVideoImportIsFinished(baseParams, name, uuid, getYoutubeVideoUrl(), true, 'presence')
768 })
769 })
770
771 describe('New registration', function () {
772 let baseParams: CheckerBaseParams
773
774 before(() => {
775 baseParams = {
776 server: servers[0],
777 emails,
778 socketNotifications: adminNotifications,
779 token: servers[0].accessToken
780 }
781 })
782
783 it('Should send a notification only to moderators when a user registers on the instance', async function () {
784 await registerUser(servers[0].url, 'user_45', 'password')
785
786 await waitJobs(servers)
787
788 await checkUserRegistered(baseParams, 'user_45', 'presence')
789
790 const userOverride = { socketNotifications: userNotifications, token: userAccessToken, check: { web: true, mail: false } }
791 await checkUserRegistered(immutableAssign(baseParams, userOverride), 'user_45', 'absence')
792 })
793 })
794
795 describe('New actor follow', function () {
796 let baseParams: CheckerBaseParams
797 let myChannelName = 'super channel name'
798 let myUserName = 'super user name'
799
800 before(async () => {
801 baseParams = {
802 server: servers[0],
803 emails,
804 socketNotifications: userNotifications,
805 token: userAccessToken
806 }
807
808 await updateMyUser({
809 url: servers[0].url,
810 accessToken: servers[0].accessToken,
811 displayName: 'super root name'
812 })
813
814 await updateMyUser({
815 url: servers[0].url,
816 accessToken: userAccessToken,
817 displayName: myUserName
818 })
819
820 await updateMyUser({
821 url: servers[1].url,
822 accessToken: servers[1].accessToken,
823 displayName: 'super root 2 name'
824 })
825
826 await updateVideoChannel(servers[0].url, userAccessToken, 'user_1_channel', { displayName: myChannelName })
827 })
828
829 it('Should notify when a local channel is following one of our channel', async function () {
830 this.timeout(10000)
831
832 await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:9001')
833 await waitJobs(servers)
834
835 await checkNewActorFollow(baseParams, 'channel', 'root', 'super root name', myChannelName, 'presence')
836
837 await removeUserSubscription(servers[0].url, servers[0].accessToken, 'user_1_channel@localhost:9001')
838 })
839
840 it('Should notify when a remote channel is following one of our channel', async function () {
841 this.timeout(10000)
842
843 await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:9001')
844 await waitJobs(servers)
845
846 await checkNewActorFollow(baseParams, 'channel', 'root', 'super root 2 name', myChannelName, 'presence')
847
848 await removeUserSubscription(servers[1].url, servers[1].accessToken, 'user_1_channel@localhost:9001')
849 })
850
851 it('Should notify when a local account is following one of our channel', async function () {
852 await addUserSubscription(servers[0].url, servers[0].accessToken, 'user_1@localhost:9001')
853
854 await waitJobs(servers)
855
856 await checkNewActorFollow(baseParams, 'account', 'root', 'super root name', myUserName, 'presence')
857 })
858
859 it('Should notify when a remote account is following one of our channel', async function () {
860 await addUserSubscription(servers[1].url, servers[1].accessToken, 'user_1@localhost:9001')
861
862 await waitJobs(servers)
863
864 await checkNewActorFollow(baseParams, 'account', 'root', 'super root 2 name', myUserName, 'presence')
865 })
866 })
867
868 describe('Mark as read', function () {
869 it('Should mark as read some notifications', async function () {
870 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 2, 3)
871 const ids = res.body.data.map(n => n.id)
872
873 await markAsReadNotifications(servers[ 0 ].url, userAccessToken, ids)
874 })
875
876 it('Should have the notifications marked as read', async function () {
877 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10)
878
879 const notifications = res.body.data as UserNotification[]
880 expect(notifications[ 0 ].read).to.be.false
881 expect(notifications[ 1 ].read).to.be.false
882 expect(notifications[ 2 ].read).to.be.true
883 expect(notifications[ 3 ].read).to.be.true
884 expect(notifications[ 4 ].read).to.be.true
885 expect(notifications[ 5 ].read).to.be.false
886 })
887
888 it('Should only list read notifications', async function () {
889 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, false)
890
891 const notifications = res.body.data as UserNotification[]
892 for (const notification of notifications) {
893 expect(notification.read).to.be.true
894 }
895 })
896
897 it('Should only list unread notifications', async function () {
898 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true)
899
900 const notifications = res.body.data as UserNotification[]
901 for (const notification of notifications) {
902 expect(notification.read).to.be.false
903 }
904 })
905
906 it('Should mark as read all notifications', async function () {
907 await markAsReadAllNotifications(servers[ 0 ].url, userAccessToken)
908
909 const res = await getUserNotifications(servers[ 0 ].url, userAccessToken, 0, 10, true)
910
911 expect(res.body.total).to.equal(0)
912 expect(res.body.data).to.have.lengthOf(0)
913 })
914 })
915
916 describe('Notification settings', function () {
917 let baseParams: CheckerBaseParams
918
919 before(() => {
920 baseParams = {
921 server: servers[0],
922 emails,
923 socketNotifications: userNotifications,
924 token: userAccessToken
925 }
926 })
927
928 it('Should not have notifications', async function () {
929 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
930 newVideoFromSubscription: UserNotificationSettingValue.NONE
931 }))
932
933 {
934 const res = await getMyUserInformation(servers[0].url, userAccessToken)
935 const info = res.body as User
936 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.NONE)
937 }
938
939 const { name, uuid } = await uploadVideoByLocalAccount(servers)
940
941 const check = { web: true, mail: true }
942 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
943 })
944
945 it('Should only have web notifications', async function () {
946 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
947 newVideoFromSubscription: UserNotificationSettingValue.WEB
948 }))
949
950 {
951 const res = await getMyUserInformation(servers[0].url, userAccessToken)
952 const info = res.body as User
953 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.WEB)
954 }
955
956 const { name, uuid } = await uploadVideoByLocalAccount(servers)
957
958 {
959 const check = { mail: true, web: false }
960 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
961 }
962
963 {
964 const check = { mail: false, web: true }
965 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'presence')
966 }
967 })
968
969 it('Should only have mail notifications', async function () {
970 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
971 newVideoFromSubscription: UserNotificationSettingValue.EMAIL
972 }))
973
974 {
975 const res = await getMyUserInformation(servers[0].url, userAccessToken)
976 const info = res.body as User
977 expect(info.notificationSettings.newVideoFromSubscription).to.equal(UserNotificationSettingValue.EMAIL)
978 }
979
980 const { name, uuid } = await uploadVideoByLocalAccount(servers)
981
982 {
983 const check = { mail: false, web: true }
984 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'absence')
985 }
986
987 {
988 const check = { mail: true, web: false }
989 await checkNewVideoFromSubscription(immutableAssign(baseParams, { check }), name, uuid, 'presence')
990 }
991 })
992
993 it('Should have email and web notifications', async function () {
994 await updateMyNotificationSettings(servers[0].url, userAccessToken, immutableAssign(allNotificationSettings, {
995 newVideoFromSubscription: UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
996 }))
997
998 {
999 const res = await getMyUserInformation(servers[0].url, userAccessToken)
1000 const info = res.body as User
1001 expect(info.notificationSettings.newVideoFromSubscription).to.equal(
1002 UserNotificationSettingValue.WEB | UserNotificationSettingValue.EMAIL
1003 )
1004 }
1005
1006 const { name, uuid } = await uploadVideoByLocalAccount(servers)
1007
1008 await checkNewVideoFromSubscription(baseParams, name, uuid, 'presence')
1009 })
1010 })
1011
1012 after(async function () {
1013 MockSmtpServer.Instance.kill()
1014
1015 killallServers(servers)
1016 })
1017})
diff --git a/server/tests/api/users/user-subscriptions.ts b/server/tests/api/users/user-subscriptions.ts
index 65b80540c..88a7187d6 100644
--- a/server/tests/api/users/user-subscriptions.ts
+++ b/server/tests/api/users/user-subscriptions.ts
@@ -2,18 +2,27 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { createUser, doubleFollow, flushAndRunMultipleServers, follow, getVideosList, unfollow, updateVideo, userLogin } from '../../utils' 5import {
6import { killallServers, ServerInfo, uploadVideo } from '../../utils/index' 6 createUser,
7import { setAccessTokensToServers } from '../../utils/users/login' 7 doubleFollow,
8 flushAndRunMultipleServers,
9 follow,
10 getVideosList,
11 unfollow,
12 updateVideo,
13 userLogin
14} from '../../../../shared/utils'
15import { killallServers, ServerInfo, uploadVideo } from '../../../../shared/utils/index'
16import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
8import { Video, VideoChannel } from '../../../../shared/models/videos' 17import { Video, VideoChannel } from '../../../../shared/models/videos'
9import { waitJobs } from '../../utils/server/jobs' 18import { waitJobs } from '../../../../shared/utils/server/jobs'
10import { 19import {
11 addUserSubscription, 20 addUserSubscription,
12 listUserSubscriptions, 21 listUserSubscriptions,
13 listUserSubscriptionVideos, 22 listUserSubscriptionVideos,
14 removeUserSubscription, 23 removeUserSubscription,
15 getUserSubscription, areSubscriptionsExist 24 getUserSubscription, areSubscriptionsExist
16} from '../../utils/users/user-subscriptions' 25} from '../../../../shared/utils/users/user-subscriptions'
17 26
18const expect = chai.expect 27const expect = chai.expect
19 28
diff --git a/server/tests/api/users/users-multiple-servers.ts b/server/tests/api/users/users-multiple-servers.ts
index d8699db17..006d6cdf0 100644
--- a/server/tests/api/users/users-multiple-servers.ts
+++ b/server/tests/api/users/users-multiple-servers.ts
@@ -13,13 +13,13 @@ import {
13 removeUser, 13 removeUser,
14 updateMyUser, 14 updateMyUser,
15 userLogin 15 userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { getMyUserInformation, killallServers, ServerInfo, testImage, updateMyAvatar, uploadVideo } from '../../utils/index' 17import { getMyUserInformation, killallServers, ServerInfo, testImage, updateMyAvatar, uploadVideo } from '../../../../shared/utils/index'
18import { checkActorFilesWereRemoved, getAccount, getAccountsList } from '../../utils/users/accounts' 18import { checkActorFilesWereRemoved, getAccount, getAccountsList } from '../../../../shared/utils/users/accounts'
19import { setAccessTokensToServers } from '../../utils/users/login' 19import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
20import { User } from '../../../../shared/models/users' 20import { User } from '../../../../shared/models/users'
21import { VideoChannel } from '../../../../shared/models/videos' 21import { VideoChannel } from '../../../../shared/models/videos'
22import { waitJobs } from '../../utils/server/jobs' 22import { waitJobs } from '../../../../shared/utils/server/jobs'
23 23
24const expect = chai.expect 24const expect = chai.expect
25 25
diff --git a/server/tests/api/users/users-verification.ts b/server/tests/api/users/users-verification.ts
index fa5f5e371..babeda2b8 100644
--- a/server/tests/api/users/users-verification.ts
+++ b/server/tests/api/users/users-verification.ts
@@ -4,11 +4,11 @@ import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { 5import {
6 registerUser, flushTests, getUserInformation, getMyUserInformation, killallServers, 6 registerUser, flushTests, getUserInformation, getMyUserInformation, killallServers,
7 userLogin, login, runServer, ServerInfo, verifyEmail, updateCustomSubConfig 7 userLogin, login, runServer, ServerInfo, verifyEmail, updateCustomSubConfig, wait
8} from '../../utils' 8} from '../../../../shared/utils'
9import { setAccessTokensToServers } from '../../utils/users/login' 9import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
10import { mockSmtpServer } from '../../utils/miscs/email' 10import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
11import { waitJobs } from '../../utils/server/jobs' 11import { waitJobs } from '../../../../shared/utils/server/jobs'
12 12
13const expect = chai.expect 13const expect = chai.expect
14 14
@@ -30,7 +30,7 @@ describe('Test users account verification', function () {
30 before(async function () { 30 before(async function () {
31 this.timeout(30000) 31 this.timeout(30000)
32 32
33 await mockSmtpServer(emails) 33 await MockSmtpServer.Instance.collectEmails(emails)
34 34
35 await flushTests() 35 await flushTests()
36 36
@@ -123,6 +123,7 @@ describe('Test users account verification', function () {
123 }) 123 })
124 124
125 after(async function () { 125 after(async function () {
126 MockSmtpServer.Instance.kill()
126 killallServers([ server ]) 127 killallServers([ server ])
127 128
128 // Keep the logs if the test failed 129 // Keep the logs if the test failed
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts
index e7bb845b9..ad98ab1c7 100644
--- a/server/tests/api/users/users.ts
+++ b/server/tests/api/users/users.ts
@@ -32,10 +32,10 @@ import {
32 updateUser, 32 updateUser,
33 uploadVideo, 33 uploadVideo,
34 userLogin 34 userLogin
35} from '../../utils/index' 35} from '../../../../shared/utils/index'
36import { follow } from '../../utils/server/follows' 36import { follow } from '../../../../shared/utils/server/follows'
37import { setAccessTokensToServers } from '../../utils/users/login' 37import { setAccessTokensToServers } from '../../../../shared/utils/users/login'
38import { getMyVideos } from '../../utils/videos/videos' 38import { getMyVideos } from '../../../../shared/utils/videos/videos'
39 39
40const expect = chai.expect 40const expect = chai.expect
41 41
@@ -501,10 +501,6 @@ describe('Test users', function () {
501 accessTokenUser = await userLogin(server, user) 501 accessTokenUser = await userLogin(server, user)
502 }) 502 })
503 503
504 it('Should not be able to delete a user by a moderator', async function () {
505 await removeUser(server.url, 2, accessTokenUser, 403)
506 })
507
508 it('Should be able to list video blacklist by a moderator', async function () { 504 it('Should be able to list video blacklist by a moderator', async function () {
509 await getBlacklistedVideosList(server.url, accessTokenUser) 505 await getBlacklistedVideosList(server.url, accessTokenUser)
510 }) 506 })
diff --git a/server/tests/api/videos/index.ts b/server/tests/api/videos/index.ts
index 9bdb78491..97f467aae 100644
--- a/server/tests/api/videos/index.ts
+++ b/server/tests/api/videos/index.ts
@@ -3,7 +3,6 @@ import './services'
3import './single-server' 3import './single-server'
4import './video-abuse' 4import './video-abuse'
5import './video-blacklist' 5import './video-blacklist'
6import './video-blacklist-management'
7import './video-captions' 6import './video-captions'
8import './video-change-ownership' 7import './video-change-ownership'
9import './video-channels' 8import './video-channels'
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts
index b9ace2885..6c281e49e 100644
--- a/server/tests/api/videos/multiple-servers.ts
+++ b/server/tests/api/videos/multiple-servers.ts
@@ -8,6 +8,7 @@ import { VideoPrivacy } from '../../../../shared/models/videos'
8import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 8import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
9import { 9import {
10 addVideoChannel, 10 addVideoChannel,
11 checkTmpIsEmpty,
11 checkVideoFilesWereRemoved, 12 checkVideoFilesWereRemoved,
12 completeVideoCheck, 13 completeVideoCheck,
13 createUser, 14 createUser,
@@ -31,15 +32,15 @@ import {
31 viewVideo, 32 viewVideo,
32 wait, 33 wait,
33 webtorrentAdd 34 webtorrentAdd
34} from '../../utils' 35} from '../../../../shared/utils'
35import { 36import {
36 addVideoCommentReply, 37 addVideoCommentReply,
37 addVideoCommentThread, 38 addVideoCommentThread,
38 deleteVideoComment, 39 deleteVideoComment,
39 getVideoCommentThreads, 40 getVideoCommentThreads,
40 getVideoThreadComments 41 getVideoThreadComments
41} from '../../utils/videos/video-comments' 42} from '../../../../shared/utils/videos/video-comments'
42import { waitJobs } from '../../utils/server/jobs' 43import { waitJobs } from '../../../../shared/utils/server/jobs'
43 44
44const expect = chai.expect 45const expect = chai.expect
45 46
@@ -1008,6 +1009,14 @@ describe('Test multiple servers', function () {
1008 }) 1009 })
1009 }) 1010 })
1010 1011
1012 describe('TMP directory', function () {
1013 it('Should have an empty tmp directory', async function () {
1014 for (const server of servers) {
1015 await checkTmpIsEmpty(server)
1016 }
1017 })
1018 })
1019
1011 after(async function () { 1020 after(async function () {
1012 killallServers(servers) 1021 killallServers(servers)
1013 1022
diff --git a/server/tests/api/videos/services.ts b/server/tests/api/videos/services.ts
index 2f1424292..2da86964f 100644
--- a/server/tests/api/videos/services.ts
+++ b/server/tests/api/videos/services.ts
@@ -2,8 +2,16 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { flushTests, getOEmbed, getVideosList, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils/index' 5import {
6import { runServer } from '../../utils/server/servers' 6 flushTests,
7 getOEmbed,
8 getVideosList,
9 killallServers,
10 ServerInfo,
11 setAccessTokensToServers,
12 uploadVideo
13} from '../../../../shared/utils/index'
14import { runServer } from '../../../../shared/utils/server/servers'
7 15
8const expect = chai.expect 16const expect = chai.expect
9 17
diff --git a/server/tests/api/videos/single-server.ts b/server/tests/api/videos/single-server.ts
index 089c3df25..069dec67c 100644
--- a/server/tests/api/videos/single-server.ts
+++ b/server/tests/api/videos/single-server.ts
@@ -28,7 +28,7 @@ import {
28 uploadVideo, 28 uploadVideo,
29 viewVideo, 29 viewVideo,
30 wait 30 wait
31} from '../../utils' 31} from '../../../../shared/utils'
32 32
33const expect = chai.expect 33const expect = chai.expect
34 34
diff --git a/server/tests/api/videos/video-abuse.ts b/server/tests/api/videos/video-abuse.ts
index a17f3c8de..3a7b623da 100644
--- a/server/tests/api/videos/video-abuse.ts
+++ b/server/tests/api/videos/video-abuse.ts
@@ -14,9 +14,9 @@ import {
14 setAccessTokensToServers, 14 setAccessTokensToServers,
15 updateVideoAbuse, 15 updateVideoAbuse,
16 uploadVideo 16 uploadVideo
17} from '../../utils/index' 17} from '../../../../shared/utils/index'
18import { doubleFollow } from '../../utils/server/follows' 18import { doubleFollow } from '../../../../shared/utils/server/follows'
19import { waitJobs } from '../../utils/server/jobs' 19import { waitJobs } from '../../../../shared/utils/server/jobs'
20 20
21const expect = chai.expect 21const expect = chai.expect
22 22
diff --git a/server/tests/api/videos/video-blacklist-management.ts b/server/tests/api/videos/video-blacklist-management.ts
deleted file mode 100644
index fab577b30..000000000
--- a/server/tests/api/videos/video-blacklist-management.ts
+++ /dev/null
@@ -1,192 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import { orderBy } from 'lodash'
5import 'mocha'
6import {
7 addVideoToBlacklist,
8 flushAndRunMultipleServers,
9 getBlacklistedVideosList,
10 getMyVideos,
11 getSortedBlacklistedVideosList,
12 getVideosList,
13 killallServers,
14 removeVideoFromBlacklist,
15 ServerInfo,
16 setAccessTokensToServers,
17 updateVideoBlacklist,
18 uploadVideo
19} from '../../utils/index'
20import { doubleFollow } from '../../utils/server/follows'
21import { waitJobs } from '../../utils/server/jobs'
22import { VideoAbuse } from '../../../../shared/models/videos'
23
24const expect = chai.expect
25
26describe('Test video blacklist management', function () {
27 let servers: ServerInfo[] = []
28 let videoId: number
29
30 async function blacklistVideosOnServer (server: ServerInfo) {
31 const res = await getVideosList(server.url)
32
33 const videos = res.body.data
34 for (let video of videos) {
35 await addVideoToBlacklist(server.url, server.accessToken, video.id, 'super reason')
36 }
37 }
38
39 before(async function () {
40 this.timeout(50000)
41
42 // Run servers
43 servers = await flushAndRunMultipleServers(2)
44
45 // Get the access tokens
46 await setAccessTokensToServers(servers)
47
48 // Server 1 and server 2 follow each other
49 await doubleFollow(servers[0], servers[1])
50
51 // Upload 2 videos on server 2
52 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 1st video', description: 'A video on server 2' })
53 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 2nd video', description: 'A video on server 2' })
54
55 // Wait videos propagation, server 2 has transcoding enabled
56 await waitJobs(servers)
57
58 // Blacklist the two videos on server 1
59 await blacklistVideosOnServer(servers[0])
60 })
61
62 describe('When listing blacklisted videos', function () {
63 it('Should display all the blacklisted videos', async function () {
64 const res = await getBlacklistedVideosList(servers[0].url, servers[0].accessToken)
65
66 expect(res.body.total).to.equal(2)
67
68 const blacklistedVideos = res.body.data
69 expect(blacklistedVideos).to.be.an('array')
70 expect(blacklistedVideos.length).to.equal(2)
71
72 for (const blacklistedVideo of blacklistedVideos) {
73 expect(blacklistedVideo.reason).to.equal('super reason')
74 videoId = blacklistedVideo.video.id
75 }
76 })
77
78 it('Should get the correct sort when sorting by descending id', async function () {
79 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-id')
80 expect(res.body.total).to.equal(2)
81
82 const blacklistedVideos = res.body.data
83 expect(blacklistedVideos).to.be.an('array')
84 expect(blacklistedVideos.length).to.equal(2)
85
86 const result = orderBy(res.body.data, [ 'id' ], [ 'desc' ])
87
88 expect(blacklistedVideos).to.deep.equal(result)
89 })
90
91 it('Should get the correct sort when sorting by descending video name', async function () {
92 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
93 expect(res.body.total).to.equal(2)
94
95 const blacklistedVideos = res.body.data
96 expect(blacklistedVideos).to.be.an('array')
97 expect(blacklistedVideos.length).to.equal(2)
98
99 const result = orderBy(res.body.data, [ 'name' ], [ 'desc' ])
100
101 expect(blacklistedVideos).to.deep.equal(result)
102 })
103
104 it('Should get the correct sort when sorting by ascending creation date', async function () {
105 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt')
106 expect(res.body.total).to.equal(2)
107
108 const blacklistedVideos = res.body.data
109 expect(blacklistedVideos).to.be.an('array')
110 expect(blacklistedVideos.length).to.equal(2)
111
112 const result = orderBy(res.body.data, [ 'createdAt' ])
113
114 expect(blacklistedVideos).to.deep.equal(result)
115 })
116 })
117
118 describe('When updating blacklisted videos', function () {
119 it('Should change the reason', async function () {
120 await updateVideoBlacklist(servers[0].url, servers[0].accessToken, videoId, 'my super reason updated')
121
122 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
123 const video = res.body.data.find(b => b.video.id === videoId)
124
125 expect(video.reason).to.equal('my super reason updated')
126 })
127 })
128
129 describe('When listing my videos', function () {
130 it('Should display blacklisted videos', async function () {
131 await blacklistVideosOnServer(servers[1])
132
133 const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 5)
134
135 expect(res.body.total).to.equal(2)
136 expect(res.body.data).to.have.lengthOf(2)
137
138 for (const video of res.body.data) {
139 expect(video.blacklisted).to.be.true
140 expect(video.blacklistedReason).to.equal('super reason')
141 }
142 })
143 })
144
145 describe('When removing a blacklisted video', function () {
146 let videoToRemove: VideoAbuse
147 let blacklist = []
148
149 it('Should not have any video in videos list on server 1', async function () {
150 const res = await getVideosList(servers[0].url)
151 expect(res.body.total).to.equal(0)
152 expect(res.body.data).to.be.an('array')
153 expect(res.body.data.length).to.equal(0)
154 })
155
156 it('Should remove a video from the blacklist on server 1', async function () {
157 // Get one video in the blacklist
158 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
159 videoToRemove = res.body.data[0]
160 blacklist = res.body.data.slice(1)
161
162 // Remove it
163 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoToRemove.video.id)
164 })
165
166 it('Should have the ex-blacklisted video in videos list on server 1', async function () {
167 const res = await getVideosList(servers[0].url)
168 expect(res.body.total).to.equal(1)
169
170 const videos = res.body.data
171 expect(videos).to.be.an('array')
172 expect(videos.length).to.equal(1)
173
174 expect(videos[0].name).to.equal(videoToRemove.video.name)
175 expect(videos[0].id).to.equal(videoToRemove.video.id)
176 })
177
178 it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () {
179 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
180 expect(res.body.total).to.equal(1)
181
182 const videos = res.body.data
183 expect(videos).to.be.an('array')
184 expect(videos.length).to.equal(1)
185 expect(videos).to.deep.equal(blacklist)
186 })
187 })
188
189 after(async function () {
190 killallServers(servers)
191 })
192})
diff --git a/server/tests/api/videos/video-blacklist.ts b/server/tests/api/videos/video-blacklist.ts
index de4c68f1d..d39ad63b4 100644
--- a/server/tests/api/videos/video-blacklist.ts
+++ b/server/tests/api/videos/video-blacklist.ts
@@ -1,24 +1,43 @@
1/* tslint:disable:no-unused-expression */ 1/* tslint:disable:no-unused-expression */
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import { orderBy } from 'lodash'
4import 'mocha' 5import 'mocha'
5import { 6import {
6 addVideoToBlacklist, 7 addVideoToBlacklist,
7 flushAndRunMultipleServers, 8 flushAndRunMultipleServers,
9 getBlacklistedVideosList,
10 getMyVideos,
11 getSortedBlacklistedVideosList,
8 getVideosList, 12 getVideosList,
9 killallServers, 13 killallServers,
14 removeVideoFromBlacklist,
10 searchVideo, 15 searchVideo,
11 ServerInfo, 16 ServerInfo,
12 setAccessTokensToServers, 17 setAccessTokensToServers,
13 uploadVideo 18 updateVideo,
14} from '../../utils/index' 19 updateVideoBlacklist,
15import { doubleFollow } from '../../utils/server/follows' 20 uploadVideo,
16import { waitJobs } from '../../utils/server/jobs' 21 viewVideo
22} from '../../../../shared/utils/index'
23import { doubleFollow } from '../../../../shared/utils/server/follows'
24import { waitJobs } from '../../../../shared/utils/server/jobs'
25import { VideoBlacklist } from '../../../../shared/models/videos'
17 26
18const expect = chai.expect 27const expect = chai.expect
19 28
20describe('Test video blacklists', function () { 29describe('Test video blacklist management', function () {
21 let servers: ServerInfo[] = [] 30 let servers: ServerInfo[] = []
31 let videoId: number
32
33 async function blacklistVideosOnServer (server: ServerInfo) {
34 const res = await getVideosList(server.url)
35
36 const videos = res.body.data
37 for (let video of videos) {
38 await addVideoToBlacklist(server.url, server.accessToken, video.id, 'super reason')
39 }
40 }
22 41
23 before(async function () { 42 before(async function () {
24 this.timeout(50000) 43 this.timeout(50000)
@@ -32,58 +51,270 @@ describe('Test video blacklists', function () {
32 // Server 1 and server 2 follow each other 51 // Server 1 and server 2 follow each other
33 await doubleFollow(servers[0], servers[1]) 52 await doubleFollow(servers[0], servers[1])
34 53
35 // Upload a video on server 2 54 // Upload 2 videos on server 2
36 const videoAttributes = { 55 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 1st video', description: 'A video on server 2' })
37 name: 'my super name for server 2', 56 await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'My 2nd video', description: 'A video on server 2' })
38 description: 'my super description for server 2'
39 }
40 await uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes)
41 57
42 // Wait videos propagation, server 2 has transcoding enabled 58 // Wait videos propagation, server 2 has transcoding enabled
43 await waitJobs(servers) 59 await waitJobs(servers)
44 60
45 const res = await getVideosList(servers[0].url) 61 // Blacklist the two videos on server 1
46 const videos = res.body.data 62 await blacklistVideosOnServer(servers[0])
63 })
64
65 describe('When listing/searching videos', function () {
47 66
48 expect(videos.length).to.equal(1) 67 it('Should not have the video blacklisted in videos list/search on server 1', async function () {
68 {
69 const res = await getVideosList(servers[ 0 ].url)
49 70
50 servers[0].remoteVideo = videos.find(video => video.name === 'my super name for server 2') 71 expect(res.body.total).to.equal(0)
72 expect(res.body.data).to.be.an('array')
73 expect(res.body.data.length).to.equal(0)
74 }
75
76 {
77 const res = await searchVideo(servers[ 0 ].url, 'name')
78
79 expect(res.body.total).to.equal(0)
80 expect(res.body.data).to.be.an('array')
81 expect(res.body.data.length).to.equal(0)
82 }
83 })
84
85 it('Should have the blacklisted video in videos list/search on server 2', async function () {
86 {
87 const res = await getVideosList(servers[ 1 ].url)
88
89 expect(res.body.total).to.equal(2)
90 expect(res.body.data).to.be.an('array')
91 expect(res.body.data.length).to.equal(2)
92 }
93
94 {
95 const res = await searchVideo(servers[ 1 ].url, 'video')
96
97 expect(res.body.total).to.equal(2)
98 expect(res.body.data).to.be.an('array')
99 expect(res.body.data.length).to.equal(2)
100 }
101 })
51 }) 102 })
52 103
53 it('Should blacklist a remote video on server 1', async function () { 104 describe('When listing blacklisted videos', function () {
54 await addVideoToBlacklist(servers[0].url, servers[0].accessToken, servers[0].remoteVideo.id) 105 it('Should display all the blacklisted videos', async function () {
106 const res = await getBlacklistedVideosList(servers[0].url, servers[0].accessToken)
107
108 expect(res.body.total).to.equal(2)
109
110 const blacklistedVideos = res.body.data
111 expect(blacklistedVideos).to.be.an('array')
112 expect(blacklistedVideos.length).to.equal(2)
113
114 for (const blacklistedVideo of blacklistedVideos) {
115 expect(blacklistedVideo.reason).to.equal('super reason')
116 videoId = blacklistedVideo.video.id
117 }
118 })
119
120 it('Should get the correct sort when sorting by descending id', async function () {
121 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-id')
122 expect(res.body.total).to.equal(2)
123
124 const blacklistedVideos = res.body.data
125 expect(blacklistedVideos).to.be.an('array')
126 expect(blacklistedVideos.length).to.equal(2)
127
128 const result = orderBy(res.body.data, [ 'id' ], [ 'desc' ])
129
130 expect(blacklistedVideos).to.deep.equal(result)
131 })
132
133 it('Should get the correct sort when sorting by descending video name', async function () {
134 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
135 expect(res.body.total).to.equal(2)
136
137 const blacklistedVideos = res.body.data
138 expect(blacklistedVideos).to.be.an('array')
139 expect(blacklistedVideos.length).to.equal(2)
140
141 const result = orderBy(res.body.data, [ 'name' ], [ 'desc' ])
142
143 expect(blacklistedVideos).to.deep.equal(result)
144 })
145
146 it('Should get the correct sort when sorting by ascending creation date', async function () {
147 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt')
148 expect(res.body.total).to.equal(2)
149
150 const blacklistedVideos = res.body.data
151 expect(blacklistedVideos).to.be.an('array')
152 expect(blacklistedVideos.length).to.equal(2)
153
154 const result = orderBy(res.body.data, [ 'createdAt' ])
155
156 expect(blacklistedVideos).to.deep.equal(result)
157 })
55 }) 158 })
56 159
57 it('Should not have the video blacklisted in videos list on server 1', async function () { 160 describe('When updating blacklisted videos', function () {
58 const res = await getVideosList(servers[0].url) 161 it('Should change the reason', async function () {
162 await updateVideoBlacklist(servers[0].url, servers[0].accessToken, videoId, 'my super reason updated')
163
164 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
165 const video = res.body.data.find(b => b.video.id === videoId)
59 166
60 expect(res.body.total).to.equal(0) 167 expect(video.reason).to.equal('my super reason updated')
61 expect(res.body.data).to.be.an('array') 168 })
62 expect(res.body.data.length).to.equal(0)
63 }) 169 })
64 170
65 it('Should not have the video blacklisted in videos search on server 1', async function () { 171 describe('When listing my videos', function () {
66 const res = await searchVideo(servers[0].url, 'name') 172 it('Should display blacklisted videos', async function () {
173 await blacklistVideosOnServer(servers[1])
174
175 const res = await getMyVideos(servers[1].url, servers[1].accessToken, 0, 5)
67 176
68 expect(res.body.total).to.equal(0) 177 expect(res.body.total).to.equal(2)
69 expect(res.body.data).to.be.an('array') 178 expect(res.body.data).to.have.lengthOf(2)
70 expect(res.body.data.length).to.equal(0) 179
180 for (const video of res.body.data) {
181 expect(video.blacklisted).to.be.true
182 expect(video.blacklistedReason).to.equal('super reason')
183 }
184 })
71 }) 185 })
72 186
73 it('Should have the blacklisted video in videos list on server 2', async function () { 187 describe('When removing a blacklisted video', function () {
74 const res = await getVideosList(servers[1].url) 188 let videoToRemove: VideoBlacklist
189 let blacklist = []
190
191 it('Should not have any video in videos list on server 1', async function () {
192 const res = await getVideosList(servers[0].url)
193 expect(res.body.total).to.equal(0)
194 expect(res.body.data).to.be.an('array')
195 expect(res.body.data.length).to.equal(0)
196 })
197
198 it('Should remove a video from the blacklist on server 1', async function () {
199 // Get one video in the blacklist
200 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
201 videoToRemove = res.body.data[0]
202 blacklist = res.body.data.slice(1)
203
204 // Remove it
205 await removeVideoFromBlacklist(servers[0].url, servers[0].accessToken, videoToRemove.video.id)
206 })
207
208 it('Should have the ex-blacklisted video in videos list on server 1', async function () {
209 const res = await getVideosList(servers[0].url)
210 expect(res.body.total).to.equal(1)
211
212 const videos = res.body.data
213 expect(videos).to.be.an('array')
214 expect(videos.length).to.equal(1)
215
216 expect(videos[0].name).to.equal(videoToRemove.video.name)
217 expect(videos[0].id).to.equal(videoToRemove.video.id)
218 })
219
220 it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () {
221 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name')
222 expect(res.body.total).to.equal(1)
75 223
76 expect(res.body.total).to.equal(1) 224 const videos = res.body.data
77 expect(res.body.data).to.be.an('array') 225 expect(videos).to.be.an('array')
78 expect(res.body.data.length).to.equal(1) 226 expect(videos.length).to.equal(1)
227 expect(videos).to.deep.equal(blacklist)
228 })
79 }) 229 })
80 230
81 it('Should have the video blacklisted in videos search on server 2', async function () { 231 describe('When blacklisting local videos', function () {
82 const res = await searchVideo(servers[1].url, 'name') 232 let video3UUID: string
233 let video4UUID: string
234
235 before(async function () {
236 this.timeout(10000)
237
238 {
239 const res = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'Video 3' })
240 video3UUID = res.body.video.uuid
241 }
242 {
243 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'Video 4' })
244 video4UUID = res.body.video.uuid
245 }
246
247 await waitJobs(servers)
248 })
249
250 it('Should blacklist video 3 and keep it federated', async function () {
251 this.timeout(10000)
252
253 await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video3UUID, 'super reason', false)
254
255 await waitJobs(servers)
256
257 {
258 const res = await getVideosList(servers[ 0 ].url)
259 expect(res.body.data.find(v => v.uuid === video3UUID)).to.be.undefined
260 }
261
262 {
263 const res = await getVideosList(servers[ 1 ].url)
264 expect(res.body.data.find(v => v.uuid === video3UUID)).to.not.be.undefined
265 }
266 })
267
268 it('Should unfederate the video', async function () {
269 this.timeout(10000)
270
271 await addVideoToBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID, 'super reason', true)
272
273 await waitJobs(servers)
274
275 for (const server of servers) {
276 const res = await getVideosList(server.url)
277 expect(res.body.data.find(v => v.uuid === video4UUID)).to.be.undefined
278 }
279 })
280
281 it('Should have the video unfederated even after an Update AP message', async function () {
282 this.timeout(10000)
283
284 await updateVideo(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID, { description: 'super description' })
285
286 await waitJobs(servers)
287
288 for (const server of servers) {
289 const res = await getVideosList(server.url)
290 expect(res.body.data.find(v => v.uuid === video4UUID)).to.be.undefined
291 }
292 })
293
294 it('Should have the correct video blacklist unfederate attribute', async function () {
295 const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt')
296
297 const blacklistedVideos: VideoBlacklist[] = res.body.data
298 const video3Blacklisted = blacklistedVideos.find(b => b.video.uuid === video3UUID)
299 const video4Blacklisted = blacklistedVideos.find(b => b.video.uuid === video4UUID)
300
301 expect(video3Blacklisted.unfederated).to.be.false
302 expect(video4Blacklisted.unfederated).to.be.true
303 })
304
305 it('Should remove the video from blacklist and refederate the video', async function () {
306 this.timeout(10000)
307
308 await removeVideoFromBlacklist(servers[ 0 ].url, servers[ 0 ].accessToken, video4UUID)
309
310 await waitJobs(servers)
311
312 for (const server of servers) {
313 const res = await getVideosList(server.url)
314 expect(res.body.data.find(v => v.uuid === video4UUID)).to.not.be.undefined
315 }
316 })
83 317
84 expect(res.body.total).to.equal(1)
85 expect(res.body.data).to.be.an('array')
86 expect(res.body.data.length).to.equal(1)
87 }) 318 })
88 319
89 after(async function () { 320 after(async function () {
diff --git a/server/tests/api/videos/video-captions.ts b/server/tests/api/videos/video-captions.ts
index 6e441410d..57bee713f 100644
--- a/server/tests/api/videos/video-captions.ts
+++ b/server/tests/api/videos/video-captions.ts
@@ -2,10 +2,17 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { checkVideoFilesWereRemoved, doubleFollow, flushAndRunMultipleServers, removeVideo, uploadVideo, wait } from '../../utils' 5import {
6import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index' 6 checkVideoFilesWereRemoved,
7import { waitJobs } from '../../utils/server/jobs' 7 doubleFollow,
8import { createVideoCaption, deleteVideoCaption, listVideoCaptions, testCaptionFile } from '../../utils/videos/video-captions' 8 flushAndRunMultipleServers,
9 removeVideo,
10 uploadVideo,
11 wait
12} from '../../../../shared/utils'
13import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../../../shared/utils/index'
14import { waitJobs } from '../../../../shared/utils/server/jobs'
15import { createVideoCaption, deleteVideoCaption, listVideoCaptions, testCaptionFile } from '../../../../shared/utils/videos/video-captions'
9import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model' 16import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
10 17
11const expect = chai.expect 18const expect = chai.expect
diff --git a/server/tests/api/videos/video-change-ownership.ts b/server/tests/api/videos/video-change-ownership.ts
index 1578a471d..25675a966 100644
--- a/server/tests/api/videos/video-change-ownership.ts
+++ b/server/tests/api/videos/video-change-ownership.ts
@@ -18,8 +18,8 @@ import {
18 uploadVideo, 18 uploadVideo,
19 userLogin, 19 userLogin,
20 getVideo 20 getVideo
21} from '../../utils' 21} from '../../../../shared/utils'
22import { waitJobs } from '../../utils/server/jobs' 22import { waitJobs } from '../../../../shared/utils/server/jobs'
23import { User } from '../../../../shared/models/users' 23import { User } from '../../../../shared/models/users'
24import { VideoDetails } from '../../../../shared/models/videos' 24import { VideoDetails } from '../../../../shared/models/videos'
25 25
diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts
index 41429a3d8..63514d69c 100644
--- a/server/tests/api/videos/video-channels.ts
+++ b/server/tests/api/videos/video-channels.ts
@@ -13,7 +13,7 @@ import {
13 updateVideoChannelAvatar, 13 updateVideoChannelAvatar,
14 uploadVideo, 14 uploadVideo,
15 userLogin 15 userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { 17import {
18 addVideoChannel, 18 addVideoChannel,
19 deleteVideoChannel, 19 deleteVideoChannel,
@@ -26,8 +26,8 @@ import {
26 ServerInfo, 26 ServerInfo,
27 setAccessTokensToServers, 27 setAccessTokensToServers,
28 updateVideoChannel 28 updateVideoChannel
29} from '../../utils/index' 29} from '../../../../shared/utils/index'
30import { waitJobs } from '../../utils/server/jobs' 30import { waitJobs } from '../../../../shared/utils/server/jobs'
31 31
32const expect = chai.expect 32const expect = chai.expect
33 33
diff --git a/server/tests/api/videos/video-comments.ts b/server/tests/api/videos/video-comments.ts
index d6e07c5b3..ce1b17e35 100644
--- a/server/tests/api/videos/video-comments.ts
+++ b/server/tests/api/videos/video-comments.ts
@@ -3,7 +3,7 @@
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 5import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
6import { testImage } from '../../utils' 6import { testImage } from '../../../../shared/utils'
7import { 7import {
8 dateIsValid, 8 dateIsValid,
9 flushTests, 9 flushTests,
@@ -13,14 +13,14 @@ import {
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 updateMyAvatar, 14 updateMyAvatar,
15 uploadVideo 15 uploadVideo
16} from '../../utils/index' 16} from '../../../../shared/utils/index'
17import { 17import {
18 addVideoCommentReply, 18 addVideoCommentReply,
19 addVideoCommentThread, 19 addVideoCommentThread,
20 deleteVideoComment, 20 deleteVideoComment,
21 getVideoCommentThreads, 21 getVideoCommentThreads,
22 getVideoThreadComments 22 getVideoThreadComments
23} from '../../utils/videos/video-comments' 23} from '../../../../shared/utils/videos/video-comments'
24 24
25const expect = chai.expect 25const expect = chai.expect
26 26
diff --git a/server/tests/api/videos/video-description.ts b/server/tests/api/videos/video-description.ts
index dd5cd78c0..cbda0b9a6 100644
--- a/server/tests/api/videos/video-description.ts
+++ b/server/tests/api/videos/video-description.ts
@@ -12,9 +12,9 @@ import {
12 setAccessTokensToServers, 12 setAccessTokensToServers,
13 updateVideo, 13 updateVideo,
14 uploadVideo 14 uploadVideo
15} from '../../utils/index' 15} from '../../../../shared/utils/index'
16import { doubleFollow } from '../../utils/server/follows' 16import { doubleFollow } from '../../../../shared/utils/server/follows'
17import { waitJobs } from '../../utils/server/jobs' 17import { waitJobs } from '../../../../shared/utils/server/jobs'
18 18
19const expect = chai.expect 19const expect = chai.expect
20 20
diff --git a/server/tests/api/videos/video-imports.ts b/server/tests/api/videos/video-imports.ts
index aaee79a4a..cd4988553 100644
--- a/server/tests/api/videos/video-imports.ts
+++ b/server/tests/api/videos/video-imports.ts
@@ -14,9 +14,9 @@ import {
14 killallServers, 14 killallServers,
15 ServerInfo, 15 ServerInfo,
16 setAccessTokensToServers 16 setAccessTokensToServers
17} from '../../utils' 17} from '../../../../shared/utils'
18import { waitJobs } from '../../utils/server/jobs' 18import { waitJobs } from '../../../../shared/utils/server/jobs'
19import { getMagnetURI, getYoutubeVideoUrl, importVideo, getMyVideoImports } from '../../utils/videos/video-imports' 19import { getMagnetURI, getYoutubeVideoUrl, importVideo, getMyVideoImports } from '../../../../shared/utils/videos/video-imports'
20 20
21const expect = chai.expect 21const expect = chai.expect
22 22
diff --git a/server/tests/api/videos/video-nsfw.ts b/server/tests/api/videos/video-nsfw.ts
index eab7a6991..df1ee2eb9 100644
--- a/server/tests/api/videos/video-nsfw.ts
+++ b/server/tests/api/videos/video-nsfw.ts
@@ -2,10 +2,17 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { flushTests, getVideosList, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils/index' 5import {
6import { userLogin } from '../../utils/users/login' 6 flushTests,
7import { createUser } from '../../utils/users/users' 7 getVideosList,
8import { getMyVideos } from '../../utils/videos/videos' 8 killallServers,
9 ServerInfo,
10 setAccessTokensToServers,
11 uploadVideo
12} from '../../../../shared/utils/index'
13import { userLogin } from '../../../../shared/utils/users/login'
14import { createUser } from '../../../../shared/utils/users/users'
15import { getMyVideos } from '../../../../shared/utils/videos/videos'
9import { 16import {
10 getAccountVideos, 17 getAccountVideos,
11 getConfig, 18 getConfig,
@@ -18,7 +25,7 @@ import {
18 searchVideoWithToken, 25 searchVideoWithToken,
19 updateCustomConfig, 26 updateCustomConfig,
20 updateMyUser 27 updateMyUser
21} from '../../utils' 28} from '../../../../shared/utils'
22import { ServerConfig } from '../../../../shared/models' 29import { ServerConfig } from '../../../../shared/models'
23import { CustomConfig } from '../../../../shared/models/server/custom-config.model' 30import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
24import { User } from '../../../../shared/models/users' 31import { User } from '../../../../shared/models/users'
diff --git a/server/tests/api/videos/video-privacy.ts b/server/tests/api/videos/video-privacy.ts
index 9fefca7e3..0b4e66369 100644
--- a/server/tests/api/videos/video-privacy.ts
+++ b/server/tests/api/videos/video-privacy.ts
@@ -10,12 +10,12 @@ import {
10 ServerInfo, 10 ServerInfo,
11 setAccessTokensToServers, 11 setAccessTokensToServers,
12 uploadVideo 12 uploadVideo
13} from '../../utils/index' 13} from '../../../../shared/utils/index'
14import { doubleFollow } from '../../utils/server/follows' 14import { doubleFollow } from '../../../../shared/utils/server/follows'
15import { userLogin } from '../../utils/users/login' 15import { userLogin } from '../../../../shared/utils/users/login'
16import { createUser } from '../../utils/users/users' 16import { createUser } from '../../../../shared/utils/users/users'
17import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../utils/videos/videos' 17import { getMyVideos, getVideo, getVideoWithToken, updateVideo } from '../../../../shared/utils/videos/videos'
18import { waitJobs } from '../../utils/server/jobs' 18import { waitJobs } from '../../../../shared/utils/server/jobs'
19 19
20const expect = chai.expect 20const expect = chai.expect
21 21
diff --git a/server/tests/api/videos/video-schedule-update.ts b/server/tests/api/videos/video-schedule-update.ts
index b226a9d50..632c4244c 100644
--- a/server/tests/api/videos/video-schedule-update.ts
+++ b/server/tests/api/videos/video-schedule-update.ts
@@ -15,8 +15,8 @@ import {
15 updateVideo, 15 updateVideo,
16 uploadVideo, 16 uploadVideo,
17 wait 17 wait
18} from '../../utils' 18} from '../../../../shared/utils'
19import { waitJobs } from '../../utils/server/jobs' 19import { waitJobs } from '../../../../shared/utils/server/jobs'
20 20
21const expect = chai.expect 21const expect = chai.expect
22 22
diff --git a/server/tests/api/videos/video-transcoder.ts b/server/tests/api/videos/video-transcoder.ts
index 23920d452..eefd32ef8 100644
--- a/server/tests/api/videos/video-transcoder.ts
+++ b/server/tests/api/videos/video-transcoder.ts
@@ -19,9 +19,9 @@ import {
19 setAccessTokensToServers, 19 setAccessTokensToServers,
20 uploadVideo, 20 uploadVideo,
21 webtorrentAdd 21 webtorrentAdd
22} from '../../utils' 22} from '../../../../shared/utils'
23import { join } from 'path' 23import { extname, join } from 'path'
24import { waitJobs } from '../../utils/server/jobs' 24import { waitJobs } from '../../../../shared/utils/server/jobs'
25import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants' 25import { VIDEO_TRANSCODING_FPS } from '../../../../server/initializers/constants'
26 26
27const expect = chai.expect 27const expect = chai.expect
@@ -321,6 +321,34 @@ describe('Test video transcoding', function () {
321 } 321 }
322 }) 322 })
323 323
324 it('Should accept and transcode additional extensions', async function () {
325 this.timeout(300000)
326
327 for (const fixture of [ 'video_short.mkv', 'video_short.avi' ]) {
328 const videoAttributes = {
329 name: fixture,
330 fixture
331 }
332
333 await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, videoAttributes)
334
335 await waitJobs(servers)
336
337 for (const server of servers) {
338 const res = await getVideosList(server.url)
339
340 const video = res.body.data.find(v => v.name === videoAttributes.name)
341 const res2 = await getVideo(server.url, video.id)
342 const videoDetails = res2.body
343
344 expect(videoDetails.files).to.have.lengthOf(4)
345
346 const magnetUri = videoDetails.files[ 0 ].magnetUri
347 expect(magnetUri).to.contain('.mp4')
348 }
349 }
350 })
351
324 after(async function () { 352 after(async function () {
325 killallServers(servers) 353 killallServers(servers)
326 }) 354 })
diff --git a/server/tests/api/videos/videos-filter.ts b/server/tests/api/videos/videos-filter.ts
index a7588129f..59e37ad86 100644
--- a/server/tests/api/videos/videos-filter.ts
+++ b/server/tests/api/videos/videos-filter.ts
@@ -13,7 +13,7 @@ import {
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 uploadVideo, 14 uploadVideo,
15 userLogin 15 userLogin
16} from '../../utils' 16} from '../../../../shared/utils'
17import { Video, VideoPrivacy } from '../../../../shared/models/videos' 17import { Video, VideoPrivacy } from '../../../../shared/models/videos'
18import { UserRole } from '../../../../shared/models/users' 18import { UserRole } from '../../../../shared/models/users'
19 19
diff --git a/server/tests/api/videos/videos-history.ts b/server/tests/api/videos/videos-history.ts
index 6d289b288..f654a422b 100644
--- a/server/tests/api/videos/videos-history.ts
+++ b/server/tests/api/videos/videos-history.ts
@@ -3,17 +3,21 @@
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { 5import {
6 createUser,
6 flushTests, 7 flushTests,
7 getVideosListWithToken, 8 getVideosListWithToken,
8 getVideoWithToken, 9 getVideoWithToken,
9 killallServers, makePutBodyRequest, 10 killallServers,
10 runServer, searchVideoWithToken, 11 runServer,
12 searchVideoWithToken,
11 ServerInfo, 13 ServerInfo,
12 setAccessTokensToServers, 14 setAccessTokensToServers,
13 uploadVideo 15 updateMyUser,
14} from '../../utils' 16 uploadVideo,
17 userLogin
18} from '../../../../shared/utils'
15import { Video, VideoDetails } from '../../../../shared/models/videos' 19import { Video, VideoDetails } from '../../../../shared/models/videos'
16import { userWatchVideo } from '../../utils/videos/video-history' 20import { listMyVideosHistory, removeMyVideosHistory, userWatchVideo } from '../../../../shared/utils/videos/video-history'
17 21
18const expect = chai.expect 22const expect = chai.expect
19 23
@@ -22,6 +26,8 @@ describe('Test videos history', function () {
22 let video1UUID: string 26 let video1UUID: string
23 let video2UUID: string 27 let video2UUID: string
24 let video3UUID: string 28 let video3UUID: string
29 let video3WatchedDate: Date
30 let userAccessToken: string
25 31
26 before(async function () { 32 before(async function () {
27 this.timeout(30000) 33 this.timeout(30000)
@@ -46,6 +52,13 @@ describe('Test videos history', function () {
46 const res = await uploadVideo(server.url, server.accessToken, { name: 'video 3' }) 52 const res = await uploadVideo(server.url, server.accessToken, { name: 'video 3' })
47 video3UUID = res.body.video.uuid 53 video3UUID = res.body.video.uuid
48 } 54 }
55
56 const user = {
57 username: 'user_1',
58 password: 'super password'
59 }
60 await createUser(server.url, server.accessToken, user.username, user.password)
61 userAccessToken = await userLogin(server, user)
49 }) 62 })
50 63
51 it('Should get videos, without watching history', async function () { 64 it('Should get videos, without watching history', async function () {
@@ -62,8 +75,8 @@ describe('Test videos history', function () {
62 }) 75 })
63 76
64 it('Should watch the first and second video', async function () { 77 it('Should watch the first and second video', async function () {
65 await userWatchVideo(server.url, server.accessToken, video1UUID, 3)
66 await userWatchVideo(server.url, server.accessToken, video2UUID, 8) 78 await userWatchVideo(server.url, server.accessToken, video2UUID, 8)
79 await userWatchVideo(server.url, server.accessToken, video1UUID, 3)
67 }) 80 })
68 81
69 it('Should return the correct history when listing, searching and getting videos', async function () { 82 it('Should return the correct history when listing, searching and getting videos', async function () {
@@ -117,6 +130,68 @@ describe('Test videos history', function () {
117 } 130 }
118 }) 131 })
119 132
133 it('Should have these videos when listing my history', async function () {
134 video3WatchedDate = new Date()
135 await userWatchVideo(server.url, server.accessToken, video3UUID, 2)
136
137 const res = await listMyVideosHistory(server.url, server.accessToken)
138
139 expect(res.body.total).to.equal(3)
140
141 const videos: Video[] = res.body.data
142 expect(videos[0].name).to.equal('video 3')
143 expect(videos[1].name).to.equal('video 1')
144 expect(videos[2].name).to.equal('video 2')
145 })
146
147 it('Should not have videos history on another user', async function () {
148 const res = await listMyVideosHistory(server.url, userAccessToken)
149
150 expect(res.body.total).to.equal(0)
151 expect(res.body.data).to.have.lengthOf(0)
152 })
153
154 it('Should clear my history', async function () {
155 await removeMyVideosHistory(server.url, server.accessToken, video3WatchedDate.toISOString())
156 })
157
158 it('Should have my history cleared', async function () {
159 const res = await listMyVideosHistory(server.url, server.accessToken)
160
161 expect(res.body.total).to.equal(1)
162
163 const videos: Video[] = res.body.data
164 expect(videos[0].name).to.equal('video 3')
165 })
166
167 it('Should disable videos history', async function () {
168 await updateMyUser({
169 url: server.url,
170 accessToken: server.accessToken,
171 videosHistoryEnabled: false
172 })
173
174 await userWatchVideo(server.url, server.accessToken, video2UUID, 8, 409)
175 })
176
177 it('Should re-enable videos history', async function () {
178 await updateMyUser({
179 url: server.url,
180 accessToken: server.accessToken,
181 videosHistoryEnabled: true
182 })
183
184 await userWatchVideo(server.url, server.accessToken, video1UUID, 8)
185
186 const res = await listMyVideosHistory(server.url, server.accessToken)
187
188 expect(res.body.total).to.equal(2)
189
190 const videos: Video[] = res.body.data
191 expect(videos[0].name).to.equal('video 1')
192 expect(videos[1].name).to.equal('video 3')
193 })
194
120 after(async function () { 195 after(async function () {
121 killallServers([ server ]) 196 killallServers([ server ])
122 197
diff --git a/server/tests/api/videos/videos-overview.ts b/server/tests/api/videos/videos-overview.ts
index 7d1f29c92..7221bcae6 100644
--- a/server/tests/api/videos/videos-overview.ts
+++ b/server/tests/api/videos/videos-overview.ts
@@ -2,8 +2,8 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../utils' 5import { flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, uploadVideo } from '../../../../shared/utils'
6import { getVideosOverview } from '../../utils/overviews/overviews' 6import { getVideosOverview } from '../../../../shared/utils/overviews/overviews'
7import { VideosOverview } from '../../../../shared/models/overviews' 7import { VideosOverview } from '../../../../shared/models/overviews'
8 8
9const expect = chai.expect 9const expect = chai.expect
diff --git a/server/tests/cli/create-import-video-file-job.ts b/server/tests/cli/create-import-video-file-job.ts
index 13bcfd209..4acda47b1 100644
--- a/server/tests/cli/create-import-video-file-job.ts
+++ b/server/tests/cli/create-import-video-file-job.ts
@@ -15,8 +15,8 @@ import {
15 ServerInfo, 15 ServerInfo,
16 setAccessTokensToServers, 16 setAccessTokensToServers,
17 uploadVideo 17 uploadVideo
18} from '../utils' 18} from '../../../shared/utils'
19import { waitJobs } from '../utils/server/jobs' 19import { waitJobs } from '../../../shared/utils/server/jobs'
20 20
21const expect = chai.expect 21const expect = chai.expect
22 22
diff --git a/server/tests/cli/create-transcoding-job.ts b/server/tests/cli/create-transcoding-job.ts
index c2e3840c5..50be5fa19 100644
--- a/server/tests/cli/create-transcoding-job.ts
+++ b/server/tests/cli/create-transcoding-job.ts
@@ -15,8 +15,8 @@ import {
15 ServerInfo, 15 ServerInfo,
16 setAccessTokensToServers, 16 setAccessTokensToServers,
17 uploadVideo, wait 17 uploadVideo, wait
18} from '../utils' 18} from '../../../shared/utils'
19import { waitJobs } from '../utils/server/jobs' 19import { waitJobs } from '../../../shared/utils/server/jobs'
20 20
21const expect = chai.expect 21const expect = chai.expect
22 22
diff --git a/server/tests/cli/index.ts b/server/tests/cli/index.ts
index 6201314ce..c6b7ec078 100644
--- a/server/tests/cli/index.ts
+++ b/server/tests/cli/index.ts
@@ -1,6 +1,7 @@
1// Order of the tests we want to execute 1// Order of the tests we want to execute
2import './create-import-video-file-job' 2import './create-import-video-file-job'
3import './create-transcoding-job' 3import './create-transcoding-job'
4import './optimize-old-videos'
4import './peertube' 5import './peertube'
5import './reset-password' 6import './reset-password'
6import './update-host' 7import './update-host'
diff --git a/server/tests/cli/optimize-old-videos.ts b/server/tests/cli/optimize-old-videos.ts
index 66dd39cce..6f6bc25a6 100644
--- a/server/tests/cli/optimize-old-videos.ts
+++ b/server/tests/cli/optimize-old-videos.ts
@@ -15,8 +15,8 @@ import {
15 ServerInfo, 15 ServerInfo,
16 setAccessTokensToServers, 16 setAccessTokensToServers,
17 uploadVideo, viewVideo, wait 17 uploadVideo, viewVideo, wait
18} from '../utils' 18} from '../../../shared/utils'
19import { waitJobs } from '../utils/server/jobs' 19import { waitJobs } from '../../../shared/utils/server/jobs'
20import { getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../helpers/ffmpeg-utils' 20import { getVideoFileBitrate, getVideoFileFPS, getVideoFileResolution } from '../../helpers/ffmpeg-utils'
21import { VIDEO_TRANSCODING_FPS } from '../../initializers' 21import { VIDEO_TRANSCODING_FPS } from '../../initializers'
22import { join } from 'path' 22import { join } from 'path'
diff --git a/server/tests/cli/peertube.ts b/server/tests/cli/peertube.ts
index 7a712bc4e..e2836d0c3 100644
--- a/server/tests/cli/peertube.ts
+++ b/server/tests/cli/peertube.ts
@@ -11,7 +11,7 @@ import {
11 runServer, 11 runServer,
12 ServerInfo, 12 ServerInfo,
13 setAccessTokensToServers 13 setAccessTokensToServers
14} from '../utils' 14} from '../../../shared/utils'
15 15
16describe('Test CLI wrapper', function () { 16describe('Test CLI wrapper', function () {
17 let server: ServerInfo 17 let server: ServerInfo
diff --git a/server/tests/cli/reset-password.ts b/server/tests/cli/reset-password.ts
index bf937d1c0..1b65f7e39 100644
--- a/server/tests/cli/reset-password.ts
+++ b/server/tests/cli/reset-password.ts
@@ -10,7 +10,7 @@ import {
10 runServer, 10 runServer,
11 ServerInfo, 11 ServerInfo,
12 setAccessTokensToServers 12 setAccessTokensToServers
13} from '../utils' 13} from '../../../shared/utils'
14 14
15describe('Test reset password scripts', function () { 15describe('Test reset password scripts', function () {
16 let server: ServerInfo 16 let server: ServerInfo
diff --git a/server/tests/cli/update-host.ts b/server/tests/cli/update-host.ts
index b89e72ab7..811ea6a9f 100644
--- a/server/tests/cli/update-host.ts
+++ b/server/tests/cli/update-host.ts
@@ -3,8 +3,8 @@
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { VideoDetails } from '../../../shared/models/videos' 5import { VideoDetails } from '../../../shared/models/videos'
6import { waitJobs } from '../utils/server/jobs' 6import { waitJobs } from '../../../shared/utils/server/jobs'
7import { addVideoCommentThread } from '../utils/videos/video-comments' 7import { addVideoCommentThread } from '../../../shared/utils/videos/video-comments'
8import { 8import {
9 addVideoChannel, 9 addVideoChannel,
10 createUser, 10 createUser,
@@ -21,8 +21,8 @@ import {
21 ServerInfo, 21 ServerInfo,
22 setAccessTokensToServers, 22 setAccessTokensToServers,
23 uploadVideo 23 uploadVideo
24} from '../utils' 24} from '../../../shared/utils'
25import { getAccountsList } from '../utils/users/accounts' 25import { getAccountsList } from '../../../shared/utils/users/accounts'
26 26
27const expect = chai.expect 27const expect = chai.expect
28 28
diff --git a/server/tests/client.ts b/server/tests/client.ts
index b33a653b1..06b4a9c5a 100644
--- a/server/tests/client.ts
+++ b/server/tests/client.ts
@@ -15,7 +15,7 @@ import {
15 updateCustomConfig, 15 updateCustomConfig,
16 updateCustomSubConfig, 16 updateCustomSubConfig,
17 uploadVideo 17 uploadVideo
18} from './utils' 18} from '../../shared/utils'
19 19
20const expect = chai.expect 20const expect = chai.expect
21 21
diff --git a/server/tests/feeds/feeds.ts b/server/tests/feeds/feeds.ts
index 28fe3493b..a771474bc 100644
--- a/server/tests/feeds/feeds.ts
+++ b/server/tests/feeds/feeds.ts
@@ -13,10 +13,10 @@ import {
13 ServerInfo, 13 ServerInfo,
14 setAccessTokensToServers, 14 setAccessTokensToServers,
15 uploadVideo, userLogin 15 uploadVideo, userLogin
16} from '../utils' 16} from '../../../shared/utils'
17import * as libxmljs from 'libxmljs' 17import * as libxmljs from 'libxmljs'
18import { addVideoCommentThread } from '../utils/videos/video-comments' 18import { addVideoCommentThread } from '../../../shared/utils/videos/video-comments'
19import { waitJobs } from '../utils/server/jobs' 19import { waitJobs } from '../../../shared/utils/server/jobs'
20import { User } from '../../../shared/models/users' 20import { User } from '../../../shared/models/users'
21 21
22chai.use(require('chai-xml')) 22chai.use(require('chai-xml'))
diff --git a/server/tests/fixtures/video_short.avi b/server/tests/fixtures/video_short.avi
new file mode 100644
index 000000000..88979cab2
--- /dev/null
+++ b/server/tests/fixtures/video_short.avi
Binary files differ
diff --git a/server/tests/fixtures/video_short.mkv b/server/tests/fixtures/video_short.mkv
new file mode 100644
index 000000000..a67f4f806
--- /dev/null
+++ b/server/tests/fixtures/video_short.mkv
Binary files differ
diff --git a/server/tests/fixtures/video_short_240p.mp4 b/server/tests/fixtures/video_short_240p.mp4
new file mode 100644
index 000000000..db074940b
--- /dev/null
+++ b/server/tests/fixtures/video_short_240p.mp4
Binary files differ
diff --git a/server/tests/helpers/comment-model.ts b/server/tests/helpers/comment-model.ts
new file mode 100644
index 000000000..76bb0f212
--- /dev/null
+++ b/server/tests/helpers/comment-model.ts
@@ -0,0 +1,25 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import { VideoCommentModel } from '../../models/video/video-comment'
6
7const expect = chai.expect
8
9class CommentMock {
10 text: string
11
12 extractMentions = VideoCommentModel.prototype.extractMentions
13}
14
15describe('Comment model', function () {
16 it('Should correctly extract mentions', async function () {
17 const comment = new CommentMock()
18
19 comment.text = '@florian @jean@localhost:9000 @flo @another@localhost:9000 @flo2@jean.com hello ' +
20 'email@localhost:9000 coucou.com no? @chocobozzz @chocobozzz @end'
21 const result = comment.extractMentions().sort()
22
23 expect(result).to.deep.equal([ 'another', 'chocobozzz', 'end', 'flo', 'florian', 'jean' ])
24 })
25})
diff --git a/server/tests/helpers/core-utils.ts b/server/tests/helpers/core-utils.ts
index a6d829a9f..e604cf7e3 100644
--- a/server/tests/helpers/core-utils.ts
+++ b/server/tests/helpers/core-utils.ts
@@ -2,13 +2,16 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { snakeCase, isNumber } from 'lodash'
5import { 6import {
6 parseBytes 7 parseBytes, objectConverter
7} from '../../helpers/core-utils' 8} from '../../helpers/core-utils'
9import { isNumeric } from 'validator'
8 10
9const expect = chai.expect 11const expect = chai.expect
10 12
11describe('Parse Bytes', function () { 13describe('Parse Bytes', function () {
14
12 it('Should pass when given valid value', async function () { 15 it('Should pass when given valid value', async function () {
13 // just return it 16 // just return it
14 expect(parseBytes(1024)).to.be.eq(1024) 17 expect(parseBytes(1024)).to.be.eq(1024)
@@ -45,4 +48,51 @@ describe('Parse Bytes', function () {
45 it('Should be invalid when given invalid value', async function () { 48 it('Should be invalid when given invalid value', async function () {
46 expect(parseBytes('6GB 1GB')).to.be.eq(6) 49 expect(parseBytes('6GB 1GB')).to.be.eq(6)
47 }) 50 })
51
52 it('Should convert an object', async function () {
53 function keyConverter (k: string) {
54 return snakeCase(k)
55 }
56
57 function valueConverter (v: any) {
58 if (isNumeric(v + '')) return parseInt('' + v, 10)
59
60 return v
61 }
62
63 const obj = {
64 mySuperKey: 'hello',
65 mySuper2Key: '45',
66 mySuper3Key: {
67 mySuperSubKey: '15',
68 mySuperSub2Key: 'hello',
69 mySuperSub3Key: [ '1', 'hello', 2 ],
70 mySuperSub4Key: 4
71 },
72 mySuper4Key: 45,
73 toto: {
74 super_key: '15',
75 superKey2: 'hello'
76 },
77 super_key: {
78 superKey4: 15
79 }
80 }
81
82 const res = objectConverter(obj, keyConverter, valueConverter)
83
84 expect(res.my_super_key).to.equal('hello')
85 expect(res.my_super_2_key).to.equal(45)
86 expect(res.my_super_3_key.my_super_sub_key).to.equal(15)
87 expect(res.my_super_3_key.my_super_sub_2_key).to.equal('hello')
88 expect(res.my_super_3_key.my_super_sub_3_key).to.deep.equal([ 1, 'hello', 2 ])
89 expect(res.my_super_3_key.my_super_sub_4_key).to.equal(4)
90 expect(res.toto.super_key).to.equal(15)
91 expect(res.toto.super_key_2).to.equal('hello')
92 expect(res.super_key.super_key_4).to.equal(15)
93
94 // Immutable
95 expect(res.mySuperKey).to.be.undefined
96 expect(obj['my_super_key']).to.be.undefined
97 })
48}) 98})
diff --git a/server/tests/helpers/index.ts b/server/tests/helpers/index.ts
index 40c7dc70e..551208245 100644
--- a/server/tests/helpers/index.ts
+++ b/server/tests/helpers/index.ts
@@ -1 +1,2 @@
1import './core-utils' 1import './core-utils'
2import './comment-model'
diff --git a/server/tests/misc-endpoints.ts b/server/tests/misc-endpoints.ts
index 8fab20971..5f82719da 100644
--- a/server/tests/misc-endpoints.ts
+++ b/server/tests/misc-endpoints.ts
@@ -2,7 +2,18 @@
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { flushTests, killallServers, makeGetRequest, runServer, ServerInfo } from './utils' 5import {
6 addVideoChannel,
7 createUser,
8 flushTests,
9 killallServers,
10 makeGetRequest,
11 runServer,
12 ServerInfo,
13 setAccessTokensToServers,
14 uploadVideo
15} from '../../shared/utils'
16import { VideoPrivacy } from '../../shared/models/videos'
6 17
7const expect = chai.expect 18const expect = chai.expect
8 19
@@ -15,6 +26,7 @@ describe('Test misc endpoints', function () {
15 await flushTests() 26 await flushTests()
16 27
17 server = await runServer(1) 28 server = await runServer(1)
29 await setAccessTokensToServers([ server ])
18 }) 30 })
19 31
20 describe('Test a well known endpoints', function () { 32 describe('Test a well known endpoints', function () {
@@ -60,6 +72,16 @@ describe('Test misc endpoints', function () {
60 72
61 expect(res.body.tracking).to.equal('N') 73 expect(res.body.tracking).to.equal('N')
62 }) 74 })
75
76 it('Should get change-password location', async function () {
77 const res = await makeGetRequest({
78 url: server.url,
79 path: '/.well-known/change-password',
80 statusCodeExpected: 302
81 })
82
83 expect(res.header.location).to.equal('/my-account/settings')
84 })
63 }) 85 })
64 86
65 describe('Test classic static endpoints', function () { 87 describe('Test classic static endpoints', function () {
@@ -93,6 +115,64 @@ describe('Test misc endpoints', function () {
93 }) 115 })
94 }) 116 })
95 117
118 describe('Test bots endpoints', function () {
119
120 it('Should get the empty sitemap', async function () {
121 const res = await makeGetRequest({
122 url: server.url,
123 path: '/sitemap.xml',
124 statusCodeExpected: 200
125 })
126
127 expect(res.text).to.contain('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"')
128 expect(res.text).to.contain('<url><loc>http://localhost:9001/about/instance</loc></url>')
129 })
130
131 it('Should get the empty cached sitemap', async function () {
132 const res = await makeGetRequest({
133 url: server.url,
134 path: '/sitemap.xml',
135 statusCodeExpected: 200
136 })
137
138 expect(res.text).to.contain('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"')
139 expect(res.text).to.contain('<url><loc>http://localhost:9001/about/instance</loc></url>')
140 })
141
142 it('Should add videos, channel and accounts and get sitemap', async function () {
143 this.timeout(35000)
144
145 await uploadVideo(server.url, server.accessToken, { name: 'video 1', nsfw: false })
146 await uploadVideo(server.url, server.accessToken, { name: 'video 2', nsfw: false })
147 await uploadVideo(server.url, server.accessToken, { name: 'video 3', privacy: VideoPrivacy.PRIVATE })
148
149 await addVideoChannel(server.url, server.accessToken, { name: 'channel1', displayName: 'channel 1' })
150 await addVideoChannel(server.url, server.accessToken, { name: 'channel2', displayName: 'channel 2' })
151
152 await createUser(server.url, server.accessToken, 'user1', 'password')
153 await createUser(server.url, server.accessToken, 'user2', 'password')
154
155 const res = await makeGetRequest({
156 url: server.url,
157 path: '/sitemap.xml?t=1', // avoid using cache
158 statusCodeExpected: 200
159 })
160
161 expect(res.text).to.contain('xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"')
162 expect(res.text).to.contain('<url><loc>http://localhost:9001/about/instance</loc></url>')
163
164 expect(res.text).to.contain('<video:title><![CDATA[video 1]]></video:title>')
165 expect(res.text).to.contain('<video:title><![CDATA[video 2]]></video:title>')
166 expect(res.text).to.not.contain('<video:title><![CDATA[video 3]]></video:title>')
167
168 expect(res.text).to.contain('<url><loc>http://localhost:9001/video-channels/channel1</loc></url>')
169 expect(res.text).to.contain('<url><loc>http://localhost:9001/video-channels/channel2</loc></url>')
170
171 expect(res.text).to.contain('<url><loc>http://localhost:9001/accounts/user1</loc></url>')
172 expect(res.text).to.contain('<url><loc>http://localhost:9001/accounts/user2</loc></url>')
173 })
174 })
175
96 after(async function () { 176 after(async function () {
97 killallServers([ server ]) 177 killallServers([ server ])
98 }) 178 })
diff --git a/server/tests/real-world/populate-database.ts b/server/tests/real-world/populate-database.ts
index a7fdbd1dc..016503498 100644
--- a/server/tests/real-world/populate-database.ts
+++ b/server/tests/real-world/populate-database.ts
@@ -10,7 +10,7 @@ import {
10 ServerInfo, 10 ServerInfo,
11 setAccessTokensToServers, 11 setAccessTokensToServers,
12 uploadVideo 12 uploadVideo
13} from '../utils' 13} from '../../../shared/utils'
14import * as Bluebird from 'bluebird' 14import * as Bluebird from 'bluebird'
15 15
16start() 16start()
diff --git a/server/tests/real-world/real-world.ts b/server/tests/real-world/real-world.ts
index a96469b11..ac3baaf9a 100644
--- a/server/tests/real-world/real-world.ts
+++ b/server/tests/real-world/real-world.ts
@@ -16,8 +16,8 @@ import {
16 updateVideo, 16 updateVideo,
17 uploadVideo, viewVideo, 17 uploadVideo, viewVideo,
18 wait 18 wait
19} from '../utils' 19} from '../../../shared/utils'
20import { getJobsListPaginationAndSort } from '../utils/server/jobs' 20import { getJobsListPaginationAndSort } from '../../../shared/utils/server/jobs'
21 21
22interface ServerInfo extends DefaultServerInfo { 22interface ServerInfo extends DefaultServerInfo {
23 requestsNumber: number 23 requestsNumber: number
diff --git a/server/tests/utils/miscs/email.ts b/server/tests/utils/miscs/email.ts
deleted file mode 100644
index 21accd09d..000000000
--- a/server/tests/utils/miscs/email.ts
+++ /dev/null
@@ -1,25 +0,0 @@
1import * as MailDev from 'maildev'
2
3function mockSmtpServer (emailsCollection: object[]) {
4 const maildev = new MailDev({
5 ip: '127.0.0.1',
6 smtp: 1025,
7 disableWeb: true,
8 silent: true
9 })
10 maildev.on('new', email => emailsCollection.push(email))
11
12 return new Promise((res, rej) => {
13 maildev.listen(err => {
14 if (err) return rej(err)
15
16 return res()
17 })
18 })
19}
20
21// ---------------------------------------------------------------------------
22
23export {
24 mockSmtpServer
25}
diff --git a/server/tests/utils/videos/video-history.ts b/server/tests/utils/videos/video-history.ts
deleted file mode 100644
index 7635478f7..000000000
--- a/server/tests/utils/videos/video-history.ts
+++ /dev/null
@@ -1,14 +0,0 @@
1import { makePutBodyRequest } from '../requests/requests'
2
3function userWatchVideo (url: string, token: string, videoId: number | string, currentTime: number) {
4 const path = '/api/v1/videos/' + videoId + '/watching'
5 const fields = { currentTime }
6
7 return makePutBodyRequest({ url, path, token, fields, statusCodeExpected: 204 })
8}
9
10// ---------------------------------------------------------------------------
11
12export {
13 userWatchVideo
14}
diff --git a/server/tools/peertube-get-access-token.ts b/server/tools/peertube-get-access-token.ts
index eb2571a03..a68665f5b 100644
--- a/server/tools/peertube-get-access-token.ts
+++ b/server/tools/peertube-get-access-token.ts
@@ -6,7 +6,7 @@ import {
6 Server, 6 Server,
7 Client, 7 Client,
8 User 8 User
9} from '../tests/utils/index' 9} from '../../shared/utils'
10 10
11program 11program
12 .option('-u, --url <url>', 'Server url') 12 .option('-u, --url <url>', 'Server url')
diff --git a/server/tools/peertube-import-videos.ts b/server/tools/peertube-import-videos.ts
index 21505b79d..f50aafc35 100644
--- a/server/tools/peertube-import-videos.ts
+++ b/server/tools/peertube-import-videos.ts
@@ -6,7 +6,7 @@ import { join } from 'path'
6import { VideoPrivacy } from '../../shared/models/videos' 6import { VideoPrivacy } from '../../shared/models/videos'
7import { doRequestAndSaveToFile } from '../helpers/requests' 7import { doRequestAndSaveToFile } from '../helpers/requests'
8import { CONSTRAINTS_FIELDS } from '../initializers' 8import { CONSTRAINTS_FIELDS } from '../initializers'
9import { getClient, getVideoCategories, login, searchVideoWithSort, uploadVideo } from '../tests/utils' 9import { getClient, getVideoCategories, login, searchVideoWithSort, uploadVideo } from '../../shared/utils/index'
10import { truncate } from 'lodash' 10import { truncate } from 'lodash'
11import * as prompt from 'prompt' 11import * as prompt from 'prompt'
12import { remove } from 'fs-extra' 12import { remove } from 'fs-extra'
@@ -58,6 +58,7 @@ getSettings()
58 settings.remotes[settings.default] : 58 settings.remotes[settings.default] :
59 settings.remotes[0] 59 settings.remotes[0]
60 } 60 }
61
61 if (!program['username']) program['username'] = netrc.machines[program['url']].login 62 if (!program['username']) program['username'] = netrc.machines[program['url']].login
62 if (!program['password']) program['password'] = netrc.machines[program['url']].password 63 if (!program['password']) program['password'] = netrc.machines[program['url']].password
63 } 64 }
@@ -69,12 +70,19 @@ getSettings()
69 process.exit(-1) 70 process.exit(-1)
70 } 71 }
71 72
73 removeEndSlashes(program['url'])
74 removeEndSlashes(program['targetUrl'])
75
72 const user = { 76 const user = {
73 username: program['username'], 77 username: program['username'],
74 password: program['password'] 78 password: program['password']
75 } 79 }
76 80
77 run(user, program['url']).catch(err => console.error(err)) 81 run(user, program['url'])
82 .catch(err => {
83 console.error(err)
84 process.exit(-1)
85 })
78}) 86})
79 87
80async function promptPassword () { 88async function promptPassword () {
@@ -108,8 +116,12 @@ async function run (user, url: string) {
108 secret: res.body.client_secret 116 secret: res.body.client_secret
109 } 117 }
110 118
111 const res2 = await login(url, client, user) 119 try {
112 accessToken = res2.body.access_token 120 const res = await login(program[ 'url' ], client, user)
121 accessToken = res.body.access_token
122 } catch (err) {
123 throw new Error('Cannot authenticate. Please check your username/password.')
124 }
113 125
114 const youtubeDL = await safeGetYoutubeDL() 126 const youtubeDL = await safeGetYoutubeDL()
115 127
@@ -321,3 +333,9 @@ function isNSFW (info: any) {
321 333
322 return false 334 return false
323} 335}
336
337function removeEndSlashes (url: string) {
338 while (url.endsWith('/')) {
339 url.slice(0, -1)
340 }
341}
diff --git a/server/tools/peertube-upload.ts b/server/tools/peertube-upload.ts
index 6248fb47d..cc7bd9b4c 100644
--- a/server/tools/peertube-upload.ts
+++ b/server/tools/peertube-upload.ts
@@ -1,8 +1,8 @@
1import * as program from 'commander' 1import * as program from 'commander'
2import { access, constants } from 'fs-extra' 2import { access, constants } from 'fs-extra'
3import { isAbsolute } from 'path' 3import { isAbsolute } from 'path'
4import { getClient, login } from '../tests/utils' 4import { getClient, login } from '../../shared/utils'
5import { uploadVideo } from '../tests/utils/index' 5import { uploadVideo } from '../../shared/utils/'
6import { VideoPrivacy } from '../../shared/models/videos' 6import { VideoPrivacy } from '../../shared/models/videos'
7import { netrc, getSettings } from './cli' 7import { netrc, getSettings } from './cli'
8 8
diff --git a/shared/models/activitypub/activity.ts b/shared/models/activitypub/activity.ts
index 44cb99efb..89994f665 100644
--- a/shared/models/activitypub/activity.ts
+++ b/shared/models/activitypub/activity.ts
@@ -5,12 +5,14 @@ import { DislikeObject } from './objects/dislike-object'
5import { VideoAbuseObject } from './objects/video-abuse-object' 5import { VideoAbuseObject } from './objects/video-abuse-object'
6import { VideoCommentObject } from './objects/video-comment-object' 6import { VideoCommentObject } from './objects/video-comment-object'
7import { ViewObject } from './objects/view-object' 7import { ViewObject } from './objects/view-object'
8import { APObject } from './objects/object.model'
8 9
9export type Activity = ActivityCreate | ActivityUpdate | 10export type Activity = ActivityCreate | ActivityUpdate |
10 ActivityDelete | ActivityFollow | ActivityAccept | ActivityAnnounce | 11 ActivityDelete | ActivityFollow | ActivityAccept | ActivityAnnounce |
11 ActivityUndo | ActivityLike | ActivityReject 12 ActivityUndo | ActivityLike | ActivityReject | ActivityView | ActivityDislike | ActivityFlag
12 13
13export type ActivityType = 'Create' | 'Update' | 'Delete' | 'Follow' | 'Accept' | 'Announce' | 'Undo' | 'Like' | 'Reject' 14export type ActivityType = 'Create' | 'Update' | 'Delete' | 'Follow' | 'Accept' | 'Announce' | 'Undo' | 'Like' | 'Reject' |
15 'View' | 'Dislike' | 'Flag'
14 16
15export interface ActivityAudience { 17export interface ActivityAudience {
16 to: string[] 18 to: string[]
@@ -59,15 +61,34 @@ export interface ActivityReject extends BaseActivity {
59 61
60export interface ActivityAnnounce extends BaseActivity { 62export interface ActivityAnnounce extends BaseActivity {
61 type: 'Announce' 63 type: 'Announce'
62 object: string | { id: string } 64 object: APObject
63} 65}
64 66
65export interface ActivityUndo extends BaseActivity { 67export interface ActivityUndo extends BaseActivity {
66 type: 'Undo', 68 type: 'Undo',
67 object: ActivityFollow | ActivityLike | ActivityCreate | ActivityAnnounce 69 object: ActivityFollow | ActivityLike | ActivityDislike | ActivityCreate | ActivityAnnounce
68} 70}
69 71
70export interface ActivityLike extends BaseActivity { 72export interface ActivityLike extends BaseActivity {
71 type: 'Like', 73 type: 'Like',
72 object: string 74 object: APObject
75}
76
77export interface ActivityView extends BaseActivity {
78 type: 'View',
79 actor: string
80 object: APObject
81}
82
83export interface ActivityDislike extends BaseActivity {
84 id: string
85 type: 'Dislike'
86 actor: string
87 object: APObject
88}
89
90export interface ActivityFlag extends BaseActivity {
91 type: 'Flag',
92 content: string,
93 object: APObject
73} 94}
diff --git a/shared/models/activitypub/objects/object.model.ts b/shared/models/activitypub/objects/object.model.ts
new file mode 100644
index 000000000..3fd33800a
--- /dev/null
+++ b/shared/models/activitypub/objects/object.model.ts
@@ -0,0 +1 @@
export type APObject = string | { id: string }
diff --git a/shared/models/actors/actor.model.ts b/shared/models/actors/actor.model.ts
index 6b3b1b47c..a3953874d 100644
--- a/shared/models/actors/actor.model.ts
+++ b/shared/models/actors/actor.model.ts
@@ -10,5 +10,5 @@ export interface Actor {
10 followersCount: number 10 followersCount: number
11 createdAt: Date | string 11 createdAt: Date | string
12 updatedAt: Date | string 12 updatedAt: Date | string
13 avatar: Avatar 13 avatar?: Avatar
14} 14}
diff --git a/shared/models/i18n/i18n.ts b/shared/models/i18n/i18n.ts
index 5c3249452..d7164b73f 100644
--- a/shared/models/i18n/i18n.ts
+++ b/shared/models/i18n/i18n.ts
@@ -8,12 +8,14 @@ export const I18N_LOCALES = {
8 'cs-CZ': 'Čeština', 8 'cs-CZ': 'Čeština',
9 'eo': 'Esperanto', 9 'eo': 'Esperanto',
10 'de-DE': 'Deutsch', 10 'de-DE': 'Deutsch',
11 'it-IT': 'Italiano',
11 'es-ES': 'Español', 12 'es-ES': 'Español',
12 'oc': 'Occitan', 13 'oc': 'Occitan',
13 'zh-Hant-TW': 'ç¹é«”中文(å°ç£ï¼‰', 14 'zh-Hant-TW': 'ç¹é«”中文(å°ç£ï¼‰',
14 'pt-BR': 'Português (Brasil)', 15 'pt-BR': 'Português (Brasil)',
15 'sv-SE': 'svenska', 16 'sv-SE': 'svenska',
16 // 'pl-PL': 'Polski' 17 'pl-PL': 'Polski',
18 'ru-RU': 'руÑÑкий',
17 'zh-Hans-CN': '简体中文(中国)' 19 'zh-Hans-CN': '简体中文(中国)'
18} 20}
19 21
@@ -26,8 +28,9 @@ const I18N_LOCALE_ALIAS = {
26 'de': 'de-DE', 28 'de': 'de-DE',
27 'es': 'es-ES', 29 'es': 'es-ES',
28 'pt': 'pt-BR', 30 'pt': 'pt-BR',
29 'sv': 'sv-SE' 31 'sv': 'sv-SE',
30 // 'pl': 'pl-PL' 32 'pl': 'pl-PL',
33 'ru': 'ru-RU'
31} 34}
32 35
33export const POSSIBLE_LOCALES = Object.keys(I18N_LOCALES) 36export const POSSIBLE_LOCALES = Object.keys(I18N_LOCALES)
diff --git a/shared/models/server/contact-form.model.ts b/shared/models/server/contact-form.model.ts
new file mode 100644
index 000000000..0696be8b4
--- /dev/null
+++ b/shared/models/server/contact-form.model.ts
@@ -0,0 +1,5 @@
1export interface ContactForm {
2 fromEmail: string
3 fromName: string
4 body: string
5}
diff --git a/shared/models/server/custom-config.model.ts b/shared/models/server/custom-config.model.ts
index 3afd36fcd..7a3eaa33f 100644
--- a/shared/models/server/custom-config.model.ts
+++ b/shared/models/server/custom-config.model.ts
@@ -41,6 +41,10 @@ export interface CustomConfig {
41 email: string 41 email: string
42 } 42 }
43 43
44 contactForm: {
45 enabled: boolean
46 }
47
44 user: { 48 user: {
45 videoQuota: number 49 videoQuota: number
46 videoQuotaDaily: number 50 videoQuotaDaily: number
@@ -48,6 +52,7 @@ export interface CustomConfig {
48 52
49 transcoding: { 53 transcoding: {
50 enabled: boolean 54 enabled: boolean
55 allowAdditionalExtensions: boolean
51 threads: number 56 threads: number
52 resolutions: { 57 resolutions: {
53 '240p': boolean 58 '240p': boolean
diff --git a/shared/models/server/index.ts b/shared/models/server/index.ts
new file mode 100644
index 000000000..c42f6f67f
--- /dev/null
+++ b/shared/models/server/index.ts
@@ -0,0 +1,6 @@
1export * from './about.model'
2export * from './contact-form.model'
3export * from './custom-config.model'
4export * from './job.model'
5export * from './server-config.model'
6export * from './server-stats.model'
diff --git a/shared/models/server/server-config.model.ts b/shared/models/server/server-config.model.ts
index 91196c1eb..f4245ed4d 100644
--- a/shared/models/server/server-config.model.ts
+++ b/shared/models/server/server-config.model.ts
@@ -15,6 +15,14 @@ export interface ServerConfig {
15 } 15 }
16 } 16 }
17 17
18 email: {
19 enabled: boolean
20 }
21
22 contactForm: {
23 enabled: boolean
24 }
25
18 signup: { 26 signup: {
19 allowed: boolean, 27 allowed: boolean,
20 allowedForCurrentIP: boolean, 28 allowedForCurrentIP: boolean,
@@ -70,4 +78,10 @@ export interface ServerConfig {
70 videoQuota: number 78 videoQuota: number
71 videoQuotaDaily: number 79 videoQuotaDaily: number
72 } 80 }
81
82 trending: {
83 videos: {
84 intervalDays: number
85 }
86 }
73} 87}
diff --git a/shared/models/server/server-stats.model.ts b/shared/models/server/server-stats.model.ts
index a6bd2d4d3..74f3de5d3 100644
--- a/shared/models/server/server-stats.model.ts
+++ b/shared/models/server/server-stats.model.ts
@@ -5,6 +5,7 @@ export interface ServerStats {
5 totalLocalVideos: number 5 totalLocalVideos: number
6 totalLocalVideoViews: number 6 totalLocalVideoViews: number
7 totalLocalVideoComments: number 7 totalLocalVideoComments: number
8 totalLocalVideoFilesSize: number
8 9
9 totalVideos: number 10 totalVideos: number
10 totalVideoComments: number 11 totalVideoComments: number
diff --git a/shared/models/users/index.ts b/shared/models/users/index.ts
index 7114741e0..cd07cf320 100644
--- a/shared/models/users/index.ts
+++ b/shared/models/users/index.ts
@@ -1,6 +1,8 @@
1export * from './user.model' 1export * from './user.model'
2export * from './user-create.model' 2export * from './user-create.model'
3export * from './user-login.model' 3export * from './user-login.model'
4export * from './user-notification.model'
5export * from './user-notification-setting.model'
4export * from './user-refresh-token.model' 6export * from './user-refresh-token.model'
5export * from './user-update.model' 7export * from './user-update.model'
6export * from './user-update-me.model' 8export * from './user-update-me.model'
diff --git a/shared/models/users/user-notification-setting.model.ts b/shared/models/users/user-notification-setting.model.ts
new file mode 100644
index 000000000..531e12bba
--- /dev/null
+++ b/shared/models/users/user-notification-setting.model.ts
@@ -0,0 +1,17 @@
1export enum UserNotificationSettingValue {
2 NONE = 0,
3 WEB = 1 << 0,
4 EMAIL = 1 << 1
5}
6
7export interface UserNotificationSetting {
8 newVideoFromSubscription: UserNotificationSettingValue
9 newCommentOnMyVideo: UserNotificationSettingValue
10 videoAbuseAsModerator: UserNotificationSettingValue
11 blacklistOnMyVideo: UserNotificationSettingValue
12 myVideoPublished: UserNotificationSettingValue
13 myVideoImportFinished: UserNotificationSettingValue
14 newUserRegistration: UserNotificationSettingValue
15 newFollow: UserNotificationSettingValue
16 commentMention: UserNotificationSettingValue
17}
diff --git a/shared/models/users/user-notification.model.ts b/shared/models/users/user-notification.model.ts
new file mode 100644
index 000000000..186b62612
--- /dev/null
+++ b/shared/models/users/user-notification.model.ts
@@ -0,0 +1,83 @@
1export enum UserNotificationType {
2 NEW_VIDEO_FROM_SUBSCRIPTION = 1,
3 NEW_COMMENT_ON_MY_VIDEO = 2,
4 NEW_VIDEO_ABUSE_FOR_MODERATORS = 3,
5
6 BLACKLIST_ON_MY_VIDEO = 4,
7 UNBLACKLIST_ON_MY_VIDEO = 5,
8
9 MY_VIDEO_PUBLISHED = 6,
10
11 MY_VIDEO_IMPORT_SUCCESS = 7,
12 MY_VIDEO_IMPORT_ERROR = 8,
13
14 NEW_USER_REGISTRATION = 9,
15 NEW_FOLLOW = 10,
16 COMMENT_MENTION = 11
17}
18
19export interface VideoInfo {
20 id: number
21 uuid: string
22 name: string
23}
24
25export interface ActorInfo {
26 id: number
27 displayName: string
28 name: string
29 host: string
30 avatar?: {
31 path: string
32 }
33}
34
35export interface UserNotification {
36 id: number
37 type: UserNotificationType
38 read: boolean
39
40 video?: VideoInfo & {
41 channel: ActorInfo
42 }
43
44 videoImport?: {
45 id: number
46 video?: VideoInfo
47 torrentName?: string
48 magnetUri?: string
49 targetUrl?: string
50 }
51
52 comment?: {
53 id: number
54 threadId: number
55 account: ActorInfo
56 video: VideoInfo
57 }
58
59 videoAbuse?: {
60 id: number
61 video: VideoInfo
62 }
63
64 videoBlacklist?: {
65 id: number
66 video: VideoInfo
67 }
68
69 account?: ActorInfo
70
71 actorFollow?: {
72 id: number
73 follower: ActorInfo
74 following: {
75 type: 'account' | 'channel'
76 name: string
77 displayName: string
78 }
79 }
80
81 createdAt: string
82 updatedAt: string
83}
diff --git a/shared/models/users/user-right.enum.ts b/shared/models/users/user-right.enum.ts
index 51c59d20a..090256bca 100644
--- a/shared/models/users/user-right.enum.ts
+++ b/shared/models/users/user-right.enum.ts
@@ -2,10 +2,15 @@ export enum UserRight {
2 ALL, 2 ALL,
3 3
4 MANAGE_USERS, 4 MANAGE_USERS,
5
5 MANAGE_SERVER_FOLLOW, 6 MANAGE_SERVER_FOLLOW,
7
6 MANAGE_SERVER_REDUNDANCY, 8 MANAGE_SERVER_REDUNDANCY,
9
7 MANAGE_VIDEO_ABUSES, 10 MANAGE_VIDEO_ABUSES,
11
8 MANAGE_JOBS, 12 MANAGE_JOBS,
13
9 MANAGE_CONFIGURATION, 14 MANAGE_CONFIGURATION,
10 15
11 MANAGE_ACCOUNTS_BLOCKLIST, 16 MANAGE_ACCOUNTS_BLOCKLIST,
diff --git a/shared/models/users/user-role.ts b/shared/models/users/user-role.ts
index adef8fd95..59c2ba106 100644
--- a/shared/models/users/user-role.ts
+++ b/shared/models/users/user-role.ts
@@ -29,7 +29,8 @@ const userRoleRights: { [ id: number ]: UserRight[] } = {
29 UserRight.UPDATE_ANY_VIDEO, 29 UserRight.UPDATE_ANY_VIDEO,
30 UserRight.SEE_ALL_VIDEOS, 30 UserRight.SEE_ALL_VIDEOS,
31 UserRight.MANAGE_ACCOUNTS_BLOCKLIST, 31 UserRight.MANAGE_ACCOUNTS_BLOCKLIST,
32 UserRight.MANAGE_SERVERS_BLOCKLIST 32 UserRight.MANAGE_SERVERS_BLOCKLIST,
33 UserRight.MANAGE_USERS
33 ], 34 ],
34 35
35 [UserRole.USER]: [] 36 [UserRole.USER]: []
diff --git a/shared/models/users/user-update-me.model.ts b/shared/models/users/user-update-me.model.ts
index 10edeee2e..e24afab94 100644
--- a/shared/models/users/user-update-me.model.ts
+++ b/shared/models/users/user-update-me.model.ts
@@ -3,9 +3,12 @@ import { NSFWPolicyType } from '../videos/nsfw-policy.type'
3export interface UserUpdateMe { 3export interface UserUpdateMe {
4 displayName?: string 4 displayName?: string
5 description?: string 5 description?: string
6 nsfwPolicy?: NSFWPolicyType, 6 nsfwPolicy?: NSFWPolicyType
7 webTorrentEnabled?: boolean, 7
8 webTorrentEnabled?: boolean
8 autoPlayVideo?: boolean 9 autoPlayVideo?: boolean
10 videosHistoryEnabled?: boolean
11
9 email?: string 12 email?: string
10 currentPassword?: string 13 currentPassword?: string
11 password?: string 14 password?: string
diff --git a/shared/models/users/user.model.ts b/shared/models/users/user.model.ts
index 82af17516..af783d389 100644
--- a/shared/models/users/user.model.ts
+++ b/shared/models/users/user.model.ts
@@ -2,6 +2,7 @@ import { Account } from '../actors'
2import { VideoChannel } from '../videos/channel/video-channel.model' 2import { VideoChannel } from '../videos/channel/video-channel.model'
3import { UserRole } from './user-role' 3import { UserRole } from './user-role'
4import { NSFWPolicyType } from '../videos/nsfw-policy.type' 4import { NSFWPolicyType } from '../videos/nsfw-policy.type'
5import { UserNotificationSetting } from './user-notification-setting.model'
5 6
6export interface User { 7export interface User {
7 id: number 8 id: number
@@ -9,12 +10,17 @@ export interface User {
9 email: string 10 email: string
10 emailVerified: boolean 11 emailVerified: boolean
11 nsfwPolicy: NSFWPolicyType 12 nsfwPolicy: NSFWPolicyType
13
12 autoPlayVideo: boolean 14 autoPlayVideo: boolean
15 webTorrentEnabled: boolean
16 videosHistoryEnabled: boolean
17
13 role: UserRole 18 role: UserRole
14 videoQuota: number 19 videoQuota: number
15 videoQuotaDaily: number 20 videoQuotaDaily: number
16 createdAt: Date 21 createdAt: Date
17 account: Account 22 account: Account
23 notificationSettings?: UserNotificationSetting
18 videoChannels?: VideoChannel[] 24 videoChannels?: VideoChannel[]
19 25
20 blocked: boolean 26 blocked: boolean
diff --git a/shared/models/videos/blacklist/video-blacklist-create.model.ts b/shared/models/videos/blacklist/video-blacklist-create.model.ts
index 89c69cb56..6e7d36421 100644
--- a/shared/models/videos/blacklist/video-blacklist-create.model.ts
+++ b/shared/models/videos/blacklist/video-blacklist-create.model.ts
@@ -1,3 +1,4 @@
1export interface VideoBlacklistCreate { 1export interface VideoBlacklistCreate {
2 reason?: string 2 reason?: string
3 unfederate?: boolean
3} 4}
diff --git a/shared/models/videos/blacklist/video-blacklist.model.ts b/shared/models/videos/blacklist/video-blacklist.model.ts
index ef4e5e3a2..4bd976190 100644
--- a/shared/models/videos/blacklist/video-blacklist.model.ts
+++ b/shared/models/videos/blacklist/video-blacklist.model.ts
@@ -2,6 +2,7 @@ export interface VideoBlacklist {
2 id: number 2 id: number
3 createdAt: Date 3 createdAt: Date
4 updatedAt: Date 4 updatedAt: Date
5 unfederated: boolean
5 reason?: string 6 reason?: string
6 7
7 video: { 8 video: {
diff --git a/shared/models/videos/video.model.ts b/shared/models/videos/video.model.ts
index 4a9fa58b1..022876a0b 100644
--- a/shared/models/videos/video.model.ts
+++ b/shared/models/videos/video.model.ts
@@ -24,7 +24,7 @@ export interface VideoChannelAttribute {
24 displayName: string 24 displayName: string
25 url: string 25 url: string
26 host: string 26 host: string
27 avatar: Avatar 27 avatar?: Avatar
28} 28}
29 29
30export interface AccountAttribute { 30export interface AccountAttribute {
@@ -34,7 +34,7 @@ export interface AccountAttribute {
34 displayName: string 34 displayName: string
35 url: string 35 url: string
36 host: string 36 host: string
37 avatar: Avatar 37 avatar?: Avatar
38} 38}
39 39
40export interface Video { 40export interface Video {
diff --git a/server/tests/utils/cli/cli.ts b/shared/utils/cli/cli.ts
index 54d05e9c6..54d05e9c6 100644
--- a/server/tests/utils/cli/cli.ts
+++ b/shared/utils/cli/cli.ts
diff --git a/server/tests/utils/feeds/feeds.ts b/shared/utils/feeds/feeds.ts
index af6df2b20..af6df2b20 100644
--- a/server/tests/utils/feeds/feeds.ts
+++ b/shared/utils/feeds/feeds.ts
diff --git a/server/tests/utils/index.ts b/shared/utils/index.ts
index 8349631c9..e08bbfd2a 100644
--- a/server/tests/utils/index.ts
+++ b/shared/utils/index.ts
@@ -2,11 +2,15 @@ export * from './server/activitypub'
2export * from './cli/cli' 2export * from './cli/cli'
3export * from './server/clients' 3export * from './server/clients'
4export * from './server/config' 4export * from './server/config'
5export * from './server/jobs'
5export * from './users/login' 6export * from './users/login'
6export * from './miscs/miscs' 7export * from './miscs/miscs'
7export * from './miscs/stubs' 8export * from './miscs/stubs'
9export * from './miscs/sql'
8export * from './server/follows' 10export * from './server/follows'
11export * from './requests/activitypub'
9export * from './requests/requests' 12export * from './requests/requests'
13export * from './requests/check-api-params'
10export * from './server/servers' 14export * from './server/servers'
11export * from './videos/services' 15export * from './videos/services'
12export * from './users/users' 16export * from './users/users'
diff --git a/shared/utils/miscs/email-child-process.js b/shared/utils/miscs/email-child-process.js
new file mode 100644
index 000000000..40ae37d70
--- /dev/null
+++ b/shared/utils/miscs/email-child-process.js
@@ -0,0 +1,27 @@
1const MailDev = require('maildev')
2
3// must run maildev as forked ChildProcess
4// failed instantiation stops main process with exit code 0
5process.on('message', (msg) => {
6 if (msg.start) {
7 const maildev = new MailDev({
8 ip: '127.0.0.1',
9 smtp: 1025,
10 disableWeb: true,
11 silent: true
12 })
13
14 maildev.on('new', email => {
15 process.send({ email })
16 })
17
18 maildev.listen(err => {
19 if (err) {
20 // cannot send as Error object
21 return process.send({ err: err.message })
22 }
23
24 return process.send({ err: null })
25 })
26 }
27})
diff --git a/shared/utils/miscs/email.ts b/shared/utils/miscs/email.ts
new file mode 100644
index 000000000..f9f1bd95b
--- /dev/null
+++ b/shared/utils/miscs/email.ts
@@ -0,0 +1,64 @@
1import { fork, ChildProcess } from 'child_process'
2
3class MockSmtpServer {
4
5 private static instance: MockSmtpServer
6 private started = false
7 private emailChildProcess: ChildProcess
8 private emails: object[]
9
10 private constructor () {
11 this.emailChildProcess = fork(`${__dirname}/email-child-process`, [])
12
13 this.emailChildProcess.on('message', (msg) => {
14 if (msg.email) {
15 return this.emails.push(msg.email)
16 }
17 })
18
19 process.on('exit', () => this.kill())
20 }
21
22 collectEmails (emailsCollection: object[]) {
23 return new Promise((res, rej) => {
24 if (this.started) {
25 this.emails = emailsCollection
26 return res()
27 }
28
29 // ensure maildev isn't started until
30 // unexpected exit can be reported to test runner
31 this.emailChildProcess.send({ start: true })
32 this.emailChildProcess.on('exit', () => {
33 return rej(new Error('maildev exited unexpectedly, confirm port not in use'))
34 })
35 this.emailChildProcess.on('message', (msg) => {
36 if (msg.err) {
37 return rej(new Error(msg.err))
38 }
39 this.started = true
40 this.emails = emailsCollection
41 return res()
42 })
43 })
44 }
45
46 kill () {
47 if (!this.emailChildProcess) return
48
49 process.kill(this.emailChildProcess.pid)
50
51 this.emailChildProcess = null
52 MockSmtpServer.instance = null
53 }
54
55 static get Instance () {
56 return this.instance || (this.instance = new this())
57 }
58}
59
60// ---------------------------------------------------------------------------
61
62export {
63 MockSmtpServer
64}
diff --git a/server/tests/utils/miscs/miscs.ts b/shared/utils/miscs/miscs.ts
index 589daa420..91a93b631 100644
--- a/server/tests/utils/miscs/miscs.ts
+++ b/shared/utils/miscs/miscs.ts
@@ -33,8 +33,8 @@ function webtorrentAdd (torrent: string, refreshWebTorrent = false) {
33} 33}
34 34
35function root () { 35function root () {
36 // We are in server/tests/utils/miscs 36 // We are in /shared/utils/miscs
37 return join(__dirname, '..', '..', '..', '..') 37 return join(__dirname, '..', '..', '..')
38} 38}
39 39
40async function testImage (url: string, imageName: string, imagePath: string, extension = '.jpg') { 40async function testImage (url: string, imageName: string, imagePath: string, extension = '.jpg') {
@@ -44,7 +44,7 @@ async function testImage (url: string, imageName: string, imagePath: string, ext
44 44
45 const body = res.body 45 const body = res.body
46 46
47 const data = await readFile(join(__dirname, '..', '..', 'fixtures', imageName + extension)) 47 const data = await readFile(join(root(), 'server', 'tests', 'fixtures', imageName + extension))
48 const minLength = body.length - ((20 * body.length) / 100) 48 const minLength = body.length - ((20 * body.length) / 100)
49 const maxLength = body.length + ((20 * body.length) / 100) 49 const maxLength = body.length + ((20 * body.length) / 100)
50 50
@@ -59,7 +59,7 @@ function buildAbsoluteFixturePath (path: string, customTravisPath = false) {
59 59
60 if (customTravisPath && process.env.TRAVIS) return join(process.env.HOME, 'fixtures', path) 60 if (customTravisPath && process.env.TRAVIS) return join(process.env.HOME, 'fixtures', path)
61 61
62 return join(__dirname, '..', '..', 'fixtures', path) 62 return join(root(), 'server', 'tests', 'fixtures', path)
63} 63}
64 64
65async function generateHighBitrateVideo () { 65async function generateHighBitrateVideo () {
diff --git a/server/tests/utils/miscs/sql.ts b/shared/utils/miscs/sql.ts
index 027f78131..027f78131 100644
--- a/server/tests/utils/miscs/sql.ts
+++ b/shared/utils/miscs/sql.ts
diff --git a/server/tests/utils/miscs/stubs.ts b/shared/utils/miscs/stubs.ts
index d1eb0e3b2..d1eb0e3b2 100644
--- a/server/tests/utils/miscs/stubs.ts
+++ b/shared/utils/miscs/stubs.ts
diff --git a/server/tests/utils/overviews/overviews.ts b/shared/utils/overviews/overviews.ts
index 23e3ceb1e..23e3ceb1e 100644
--- a/server/tests/utils/overviews/overviews.ts
+++ b/shared/utils/overviews/overviews.ts
diff --git a/server/tests/utils/requests/activitypub.ts b/shared/utils/requests/activitypub.ts
index 96fee60a8..e2348ace0 100644
--- a/server/tests/utils/requests/activitypub.ts
+++ b/shared/utils/requests/activitypub.ts
@@ -1,7 +1,7 @@
1import { doRequest } from '../../../helpers/requests' 1import { doRequest } from '../../../server/helpers/requests'
2import { HTTP_SIGNATURE } from '../../../initializers' 2import { HTTP_SIGNATURE } from '../../../server/initializers'
3import { buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils' 3import { buildGlobalHeaders } from '../../../server/lib/job-queue/handlers/utils/activitypub-http-utils'
4import { activityPubContextify } from '../../../helpers/activitypub' 4import { activityPubContextify } from '../../../server/helpers/activitypub'
5 5
6function makePOSTAPRequest (url: string, body: any, httpSignature: any, headers: any) { 6function makePOSTAPRequest (url: string, body: any, httpSignature: any, headers: any) {
7 const options = { 7 const options = {
diff --git a/server/tests/utils/requests/check-api-params.ts b/shared/utils/requests/check-api-params.ts
index a2a549682..a2a549682 100644
--- a/server/tests/utils/requests/check-api-params.ts
+++ b/shared/utils/requests/check-api-params.ts
diff --git a/server/tests/utils/requests/requests.ts b/shared/utils/requests/requests.ts
index 5796540f7..77e9f6164 100644
--- a/server/tests/utils/requests/requests.ts
+++ b/shared/utils/requests/requests.ts
@@ -1,5 +1,5 @@
1import * as request from 'supertest' 1import * as request from 'supertest'
2import { buildAbsoluteFixturePath } from '../miscs/miscs' 2import { buildAbsoluteFixturePath, root } from '../miscs/miscs'
3import { isAbsolute, join } from 'path' 3import { isAbsolute, join } from 'path'
4 4
5function makeGetRequest (options: { 5function makeGetRequest (options: {
@@ -142,7 +142,7 @@ function updateAvatarRequest (options: {
142 if (isAbsolute(options.fixture)) { 142 if (isAbsolute(options.fixture)) {
143 filePath = options.fixture 143 filePath = options.fixture
144 } else { 144 } else {
145 filePath = join(__dirname, '..', '..', 'fixtures', options.fixture) 145 filePath = join(root(), 'server', 'tests', 'fixtures', options.fixture)
146 } 146 }
147 147
148 return makeUploadRequest({ 148 return makeUploadRequest({
diff --git a/server/tests/utils/search/video-channels.ts b/shared/utils/search/video-channels.ts
index 0532134ae..0532134ae 100644
--- a/server/tests/utils/search/video-channels.ts
+++ b/shared/utils/search/video-channels.ts
diff --git a/server/tests/utils/search/videos.ts b/shared/utils/search/videos.ts
index 8c0037ccc..ba4627017 100644
--- a/server/tests/utils/search/videos.ts
+++ b/shared/utils/search/videos.ts
@@ -1,7 +1,7 @@
1/* tslint:disable:no-unused-expression */ 1/* tslint:disable:no-unused-expression */
2 2
3import * as request from 'supertest' 3import * as request from 'supertest'
4import { VideosSearchQuery } from '../../../../shared/models/search' 4import { VideosSearchQuery } from '../../models/search'
5import { immutableAssign } from '../miscs/miscs' 5import { immutableAssign } from '../miscs/miscs'
6 6
7function searchVideo (url: string, search: string) { 7function searchVideo (url: string, search: string) {
diff --git a/server/tests/utils/server/activitypub.ts b/shared/utils/server/activitypub.ts
index eccb198ca..eccb198ca 100644
--- a/server/tests/utils/server/activitypub.ts
+++ b/shared/utils/server/activitypub.ts
diff --git a/server/tests/utils/server/clients.ts b/shared/utils/server/clients.ts
index 273aac747..273aac747 100644
--- a/server/tests/utils/server/clients.ts
+++ b/shared/utils/server/clients.ts
diff --git a/server/tests/utils/server/config.ts b/shared/utils/server/config.ts
index aa3100d34..0c5512bab 100644
--- a/server/tests/utils/server/config.ts
+++ b/shared/utils/server/config.ts
@@ -1,5 +1,5 @@
1import { makeDeleteRequest, makeGetRequest, makePutBodyRequest } from '../requests/requests' 1import { makeDeleteRequest, makeGetRequest, makePutBodyRequest } from '../requests/requests'
2import { CustomConfig } from '../../../../shared/models/server/custom-config.model' 2import { CustomConfig } from '../../models/server/custom-config.model'
3 3
4function getConfig (url: string) { 4function getConfig (url: string) {
5 const path = '/api/v1/config' 5 const path = '/api/v1/config'
@@ -80,12 +80,16 @@ function updateCustomSubConfig (url: string, token: string, newConfig: any) {
80 admin: { 80 admin: {
81 email: 'superadmin1@example.com' 81 email: 'superadmin1@example.com'
82 }, 82 },
83 contactForm: {
84 enabled: true
85 },
83 user: { 86 user: {
84 videoQuota: 5242881, 87 videoQuota: 5242881,
85 videoQuotaDaily: 318742 88 videoQuotaDaily: 318742
86 }, 89 },
87 transcoding: { 90 transcoding: {
88 enabled: true, 91 enabled: true,
92 allowAdditionalExtensions: true,
89 threads: 1, 93 threads: 1,
90 resolutions: { 94 resolutions: {
91 '240p': false, 95 '240p': false,
diff --git a/shared/utils/server/contact-form.ts b/shared/utils/server/contact-form.ts
new file mode 100644
index 000000000..80394cf99
--- /dev/null
+++ b/shared/utils/server/contact-form.ts
@@ -0,0 +1,28 @@
1import * as request from 'supertest'
2import { ContactForm } from '../../models/server'
3
4function sendContactForm (options: {
5 url: string,
6 fromEmail: string,
7 fromName: string,
8 body: string,
9 expectedStatus?: number
10}) {
11 const path = '/api/v1/server/contact'
12
13 const body: ContactForm = {
14 fromEmail: options.fromEmail,
15 fromName: options.fromName,
16 body: options.body
17 }
18 return request(options.url)
19 .post(path)
20 .send(body)
21 .expect(options.expectedStatus || 204)
22}
23
24// ---------------------------------------------------------------------------
25
26export {
27 sendContactForm
28}
diff --git a/server/tests/utils/server/follows.ts b/shared/utils/server/follows.ts
index 7741757a6..7741757a6 100644
--- a/server/tests/utils/server/follows.ts
+++ b/shared/utils/server/follows.ts
diff --git a/server/tests/utils/server/jobs.ts b/shared/utils/server/jobs.ts
index 26180ec72..692b5e24d 100644
--- a/server/tests/utils/server/jobs.ts
+++ b/shared/utils/server/jobs.ts
@@ -1,7 +1,7 @@
1import * as request from 'supertest' 1import * as request from 'supertest'
2import { Job, JobState } from '../../../../shared/models' 2import { Job, JobState } from '../../models'
3import { ServerInfo } from './servers'
4import { wait } from '../miscs/miscs' 3import { wait } from '../miscs/miscs'
4import { ServerInfo } from './servers'
5 5
6function getJobsList (url: string, accessToken: string, state: JobState) { 6function getJobsList (url: string, accessToken: string, state: JobState) {
7 const path = '/api/v1/jobs/' + state 7 const path = '/api/v1/jobs/' + state
@@ -29,16 +29,17 @@ function getJobsListPaginationAndSort (url: string, accessToken: string, state:
29} 29}
30 30
31async function waitJobs (serversArg: ServerInfo[] | ServerInfo) { 31async function waitJobs (serversArg: ServerInfo[] | ServerInfo) {
32 const pendingJobWait = process.env.NODE_PENDING_JOB_WAIT ? parseInt(process.env.NODE_PENDING_JOB_WAIT, 10) : 2000
32 let servers: ServerInfo[] 33 let servers: ServerInfo[]
33 34
34 if (Array.isArray(serversArg) === false) servers = [ serversArg as ServerInfo ] 35 if (Array.isArray(serversArg) === false) servers = [ serversArg as ServerInfo ]
35 else servers = serversArg as ServerInfo[] 36 else servers = serversArg as ServerInfo[]
36 37
37 const states: JobState[] = [ 'waiting', 'active', 'delayed' ] 38 const states: JobState[] = [ 'waiting', 'active', 'delayed' ]
38 const tasks: Promise<any>[] = [] 39 let pendingRequests = false
39 let pendingRequests: boolean
40 40
41 do { 41 function tasksBuilder () {
42 const tasks: Promise<any>[] = []
42 pendingRequests = false 43 pendingRequests = false
43 44
44 // Check if each server has pending request 45 // Check if each server has pending request
@@ -54,13 +55,16 @@ async function waitJobs (serversArg: ServerInfo[] | ServerInfo) {
54 } 55 }
55 } 56 }
56 57
57 await Promise.all(tasks) 58 return tasks
59 }
60
61 do {
62 await Promise.all(tasksBuilder())
58 63
59 // Retry, in case of new jobs were created 64 // Retry, in case of new jobs were created
60 if (pendingRequests === false) { 65 if (pendingRequests === false) {
61 await wait(1000) 66 await wait(pendingJobWait)
62 67 await Promise.all(tasksBuilder())
63 await Promise.all(tasks)
64 } 68 }
65 69
66 if (pendingRequests) { 70 if (pendingRequests) {
diff --git a/server/tests/utils/server/redundancy.ts b/shared/utils/server/redundancy.ts
index c39ff2c8b..c39ff2c8b 100644
--- a/server/tests/utils/server/redundancy.ts
+++ b/shared/utils/server/redundancy.ts
diff --git a/server/tests/utils/server/servers.ts b/shared/utils/server/servers.ts
index f358a21f1..cb57e0a69 100644
--- a/server/tests/utils/server/servers.ts
+++ b/shared/utils/server/servers.ts
@@ -1,7 +1,11 @@
1/* tslint:disable:no-unused-expression */
2
1import { ChildProcess, exec, fork } from 'child_process' 3import { ChildProcess, exec, fork } from 'child_process'
2import { join } from 'path' 4import { join } from 'path'
3import { root, wait } from '../miscs/miscs' 5import { root, wait } from '../miscs/miscs'
4import { readFile } from 'fs-extra' 6import { readdir, readFile } from 'fs-extra'
7import { existsSync } from 'fs'
8import { expect } from 'chai'
5 9
6interface ServerInfo { 10interface ServerInfo {
7 app: ChildProcess, 11 app: ChildProcess,
@@ -115,7 +119,7 @@ function runServer (serverNumber: number, configOverride?: Object, args = []) {
115 } 119 }
116 120
117 return new Promise<ServerInfo>(res => { 121 return new Promise<ServerInfo>(res => {
118 server.app = fork(join(__dirname, '..', '..', '..', '..', 'dist', 'server.js'), args, options) 122 server.app = fork(join(root(), 'dist', 'server.js'), args, options)
119 server.app.stdout.on('data', function onStdout (data) { 123 server.app.stdout.on('data', function onStdout (data) {
120 let dontContinue = false 124 let dontContinue = false
121 125
@@ -141,8 +145,16 @@ function runServer (serverNumber: number, configOverride?: Object, args = []) {
141 if (dontContinue === true) return 145 if (dontContinue === true) return
142 146
143 server.app.stdout.removeListener('data', onStdout) 147 server.app.stdout.removeListener('data', onStdout)
148
149 process.on('exit', () => {
150 try {
151 process.kill(server.app.pid)
152 } catch { /* empty */ }
153 })
154
144 res(server) 155 res(server)
145 }) 156 })
157
146 }) 158 })
147} 159}
148 160
@@ -153,6 +165,18 @@ async function reRunServer (server: ServerInfo, configOverride?: any) {
153 return server 165 return server
154} 166}
155 167
168async function checkTmpIsEmpty (server: ServerInfo) {
169 const testDirectory = 'test' + server.serverNumber
170
171 const directoryPath = join(root(), testDirectory, 'tmp')
172
173 const directoryExists = existsSync(directoryPath)
174 expect(directoryExists).to.be.true
175
176 const files = await readdir(directoryPath)
177 expect(files).to.have.lengthOf(0)
178}
179
156function killallServers (servers: ServerInfo[]) { 180function killallServers (servers: ServerInfo[]) {
157 for (const server of servers) { 181 for (const server of servers) {
158 process.kill(-server.app.pid) 182 process.kill(-server.app.pid)
@@ -175,6 +199,7 @@ async function waitUntilLog (server: ServerInfo, str: string, count = 1) {
175// --------------------------------------------------------------------------- 199// ---------------------------------------------------------------------------
176 200
177export { 201export {
202 checkTmpIsEmpty,
178 ServerInfo, 203 ServerInfo,
179 flushAndRunMultipleServers, 204 flushAndRunMultipleServers,
180 flushTests, 205 flushTests,
diff --git a/server/tests/utils/server/stats.ts b/shared/utils/server/stats.ts
index 6f079ad18..6f079ad18 100644
--- a/server/tests/utils/server/stats.ts
+++ b/shared/utils/server/stats.ts
diff --git a/shared/utils/socket/socket-io.ts b/shared/utils/socket/socket-io.ts
new file mode 100644
index 000000000..854ab71af
--- /dev/null
+++ b/shared/utils/socket/socket-io.ts
@@ -0,0 +1,13 @@
1import * as io from 'socket.io-client'
2
3function getUserNotificationSocket (serverUrl: string, accessToken: string) {
4 return io(serverUrl + '/user-notifications', {
5 query: { accessToken }
6 })
7}
8
9// ---------------------------------------------------------------------------
10
11export {
12 getUserNotificationSocket
13}
diff --git a/server/tests/utils/users/accounts.ts b/shared/utils/users/accounts.ts
index 257fa5b27..388eb6973 100644
--- a/server/tests/utils/users/accounts.ts
+++ b/shared/utils/users/accounts.ts
@@ -3,7 +3,7 @@
3import { expect } from 'chai' 3import { expect } from 'chai'
4import { existsSync, readdir } from 'fs-extra' 4import { existsSync, readdir } from 'fs-extra'
5import { join } from 'path' 5import { join } from 'path'
6import { Account } from '../../../../shared/models/actors' 6import { Account } from '../../models/actors'
7import { root } from '../miscs/miscs' 7import { root } from '../miscs/miscs'
8import { makeGetRequest } from '../requests/requests' 8import { makeGetRequest } from '../requests/requests'
9 9
diff --git a/server/tests/utils/users/blocklist.ts b/shared/utils/users/blocklist.ts
index 5feb84179..5feb84179 100644
--- a/server/tests/utils/users/blocklist.ts
+++ b/shared/utils/users/blocklist.ts
diff --git a/server/tests/utils/users/login.ts b/shared/utils/users/login.ts
index ddeb9df2a..ddeb9df2a 100644
--- a/server/tests/utils/users/login.ts
+++ b/shared/utils/users/login.ts
diff --git a/shared/utils/users/user-notifications.ts b/shared/utils/users/user-notifications.ts
new file mode 100644
index 000000000..c8ed7df30
--- /dev/null
+++ b/shared/utils/users/user-notifications.ts
@@ -0,0 +1,437 @@
1/* tslint:disable:no-unused-expression */
2
3import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests'
4import { UserNotification, UserNotificationSetting, UserNotificationType } from '../../models/users'
5import { ServerInfo } from '..'
6import { expect } from 'chai'
7import { inspect } from 'util'
8
9function updateMyNotificationSettings (url: string, token: string, settings: UserNotificationSetting, statusCodeExpected = 204) {
10 const path = '/api/v1/users/me/notification-settings'
11
12 return makePutBodyRequest({
13 url,
14 path,
15 token,
16 fields: settings,
17 statusCodeExpected
18 })
19}
20
21function getUserNotifications (
22 url: string,
23 token: string,
24 start: number,
25 count: number,
26 unread?: boolean,
27 sort = '-createdAt',
28 statusCodeExpected = 200
29) {
30 const path = '/api/v1/users/me/notifications'
31
32 return makeGetRequest({
33 url,
34 path,
35 token,
36 query: {
37 start,
38 count,
39 sort,
40 unread
41 },
42 statusCodeExpected
43 })
44}
45
46function markAsReadNotifications (url: string, token: string, ids: number[], statusCodeExpected = 204) {
47 const path = '/api/v1/users/me/notifications/read'
48
49 return makePostBodyRequest({
50 url,
51 path,
52 token,
53 fields: { ids },
54 statusCodeExpected
55 })
56}
57function markAsReadAllNotifications (url: string, token: string, statusCodeExpected = 204) {
58 const path = '/api/v1/users/me/notifications/read-all'
59
60 return makePostBodyRequest({
61 url,
62 path,
63 token,
64 statusCodeExpected
65 })
66}
67
68async function getLastNotification (serverUrl: string, accessToken: string) {
69 const res = await getUserNotifications(serverUrl, accessToken, 0, 1, undefined, '-createdAt')
70
71 if (res.body.total === 0) return undefined
72
73 return res.body.data[0] as UserNotification
74}
75
76type CheckerBaseParams = {
77 server: ServerInfo
78 emails: object[]
79 socketNotifications: UserNotification[]
80 token: string,
81 check?: { web: boolean, mail: boolean }
82}
83
84type CheckerType = 'presence' | 'absence'
85
86async function checkNotification (
87 base: CheckerBaseParams,
88 notificationChecker: (notification: UserNotification, type: CheckerType) => void,
89 emailNotificationFinder: (email: object) => boolean,
90 checkType: CheckerType
91) {
92 const check = base.check || { web: true, mail: true }
93
94 if (check.web) {
95 const notification = await getLastNotification(base.server.url, base.token)
96
97 if (notification || checkType !== 'absence') {
98 notificationChecker(notification, checkType)
99 }
100
101 const socketNotification = base.socketNotifications.find(n => {
102 try {
103 notificationChecker(n, 'presence')
104 return true
105 } catch {
106 return false
107 }
108 })
109
110 if (checkType === 'presence') {
111 const obj = inspect(base.socketNotifications, { depth: 5 })
112 expect(socketNotification, 'The socket notification is absent. ' + obj).to.not.be.undefined
113 } else {
114 const obj = inspect(socketNotification, { depth: 5 })
115 expect(socketNotification, 'The socket notification is present. ' + obj).to.be.undefined
116 }
117 }
118
119 if (check.mail) {
120 // Last email
121 const email = base.emails
122 .slice()
123 .reverse()
124 .find(e => emailNotificationFinder(e))
125
126 if (checkType === 'presence') {
127 expect(email, 'The email is absent. ' + inspect(base.emails)).to.not.be.undefined
128 } else {
129 expect(email, 'The email is present. ' + inspect(email)).to.be.undefined
130 }
131 }
132}
133
134function checkVideo (video: any, videoName?: string, videoUUID?: string) {
135 expect(video.name).to.be.a('string')
136 expect(video.name).to.not.be.empty
137 if (videoName) expect(video.name).to.equal(videoName)
138
139 expect(video.uuid).to.be.a('string')
140 expect(video.uuid).to.not.be.empty
141 if (videoUUID) expect(video.uuid).to.equal(videoUUID)
142
143 expect(video.id).to.be.a('number')
144}
145
146function checkActor (actor: any) {
147 expect(actor.displayName).to.be.a('string')
148 expect(actor.displayName).to.not.be.empty
149 expect(actor.host).to.not.be.undefined
150}
151
152function checkComment (comment: any, commentId: number, threadId: number) {
153 expect(comment.id).to.equal(commentId)
154 expect(comment.threadId).to.equal(threadId)
155}
156
157async function checkNewVideoFromSubscription (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
158 const notificationType = UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION
159
160 function notificationChecker (notification: UserNotification, type: CheckerType) {
161 if (type === 'presence') {
162 expect(notification).to.not.be.undefined
163 expect(notification.type).to.equal(notificationType)
164
165 checkVideo(notification.video, videoName, videoUUID)
166 checkActor(notification.video.channel)
167 } else {
168 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
169 }
170 }
171
172 function emailFinder (email: object) {
173 return email[ 'text' ].indexOf(videoUUID) !== -1
174 }
175
176 await checkNotification(base, notificationChecker, emailFinder, type)
177}
178
179async function checkVideoIsPublished (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
180 const notificationType = UserNotificationType.MY_VIDEO_PUBLISHED
181
182 function notificationChecker (notification: UserNotification, type: CheckerType) {
183 if (type === 'presence') {
184 expect(notification).to.not.be.undefined
185 expect(notification.type).to.equal(notificationType)
186
187 checkVideo(notification.video, videoName, videoUUID)
188 checkActor(notification.video.channel)
189 } else {
190 expect(notification.video).to.satisfy(v => v === undefined || v.name !== videoName)
191 }
192 }
193
194 function emailFinder (email: object) {
195 const text: string = email[ 'text' ]
196 return text.includes(videoUUID) && text.includes('Your video')
197 }
198
199 await checkNotification(base, notificationChecker, emailFinder, type)
200}
201
202async function checkMyVideoImportIsFinished (
203 base: CheckerBaseParams,
204 videoName: string,
205 videoUUID: string,
206 url: string,
207 success: boolean,
208 type: CheckerType
209) {
210 const notificationType = success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR
211
212 function notificationChecker (notification: UserNotification, type: CheckerType) {
213 if (type === 'presence') {
214 expect(notification).to.not.be.undefined
215 expect(notification.type).to.equal(notificationType)
216
217 expect(notification.videoImport.targetUrl).to.equal(url)
218
219 if (success) checkVideo(notification.videoImport.video, videoName, videoUUID)
220 } else {
221 expect(notification.videoImport).to.satisfy(i => i === undefined || i.targetUrl !== url)
222 }
223 }
224
225 function emailFinder (email: object) {
226 const text: string = email[ 'text' ]
227 const toFind = success ? ' finished' : ' error'
228
229 return text.includes(url) && text.includes(toFind)
230 }
231
232 await checkNotification(base, notificationChecker, emailFinder, type)
233}
234
235async function checkUserRegistered (base: CheckerBaseParams, username: string, type: CheckerType) {
236 const notificationType = UserNotificationType.NEW_USER_REGISTRATION
237
238 function notificationChecker (notification: UserNotification, type: CheckerType) {
239 if (type === 'presence') {
240 expect(notification).to.not.be.undefined
241 expect(notification.type).to.equal(notificationType)
242
243 checkActor(notification.account)
244 expect(notification.account.name).to.equal(username)
245 } else {
246 expect(notification).to.satisfy(n => n.type !== notificationType || n.account.name !== username)
247 }
248 }
249
250 function emailFinder (email: object) {
251 const text: string = email[ 'text' ]
252
253 return text.includes(' registered ') && text.includes(username)
254 }
255
256 await checkNotification(base, notificationChecker, emailFinder, type)
257}
258
259async function checkNewActorFollow (
260 base: CheckerBaseParams,
261 followType: 'channel' | 'account',
262 followerName: string,
263 followerDisplayName: string,
264 followingDisplayName: string,
265 type: CheckerType
266) {
267 const notificationType = UserNotificationType.NEW_FOLLOW
268
269 function notificationChecker (notification: UserNotification, type: CheckerType) {
270 if (type === 'presence') {
271 expect(notification).to.not.be.undefined
272 expect(notification.type).to.equal(notificationType)
273
274 checkActor(notification.actorFollow.follower)
275 expect(notification.actorFollow.follower.displayName).to.equal(followerDisplayName)
276 expect(notification.actorFollow.follower.name).to.equal(followerName)
277 expect(notification.actorFollow.follower.host).to.not.be.undefined
278
279 expect(notification.actorFollow.following.displayName).to.equal(followingDisplayName)
280 expect(notification.actorFollow.following.type).to.equal(followType)
281 } else {
282 expect(notification).to.satisfy(n => {
283 return n.type !== notificationType ||
284 (n.actorFollow.follower.name !== followerName && n.actorFollow.following !== followingDisplayName)
285 })
286 }
287 }
288
289 function emailFinder (email: object) {
290 const text: string = email[ 'text' ]
291
292 return text.includes('Your ' + followType) && text.includes(followingDisplayName) && text.includes(followerDisplayName)
293 }
294
295 await checkNotification(base, notificationChecker, emailFinder, type)
296}
297
298async function checkCommentMention (
299 base: CheckerBaseParams,
300 uuid: string,
301 commentId: number,
302 threadId: number,
303 byAccountDisplayName: string,
304 type: CheckerType
305) {
306 const notificationType = UserNotificationType.COMMENT_MENTION
307
308 function notificationChecker (notification: UserNotification, type: CheckerType) {
309 if (type === 'presence') {
310 expect(notification).to.not.be.undefined
311 expect(notification.type).to.equal(notificationType)
312
313 checkComment(notification.comment, commentId, threadId)
314 checkActor(notification.comment.account)
315 expect(notification.comment.account.displayName).to.equal(byAccountDisplayName)
316
317 checkVideo(notification.comment.video, undefined, uuid)
318 } else {
319 expect(notification).to.satisfy(n => n.type !== notificationType || n.comment.id !== commentId)
320 }
321 }
322
323 function emailFinder (email: object) {
324 const text: string = email[ 'text' ]
325
326 return text.includes(' mentioned ') && text.includes(uuid) && text.includes(byAccountDisplayName)
327 }
328
329 await checkNotification(base, notificationChecker, emailFinder, type)
330}
331
332let lastEmailCount = 0
333async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string, commentId: number, threadId: number, type: CheckerType) {
334 const notificationType = UserNotificationType.NEW_COMMENT_ON_MY_VIDEO
335
336 function notificationChecker (notification: UserNotification, type: CheckerType) {
337 if (type === 'presence') {
338 expect(notification).to.not.be.undefined
339 expect(notification.type).to.equal(notificationType)
340
341 checkComment(notification.comment, commentId, threadId)
342 checkActor(notification.comment.account)
343 checkVideo(notification.comment.video, undefined, uuid)
344 } else {
345 expect(notification).to.satisfy((n: UserNotification) => {
346 return n === undefined || n.comment === undefined || n.comment.id !== commentId
347 })
348 }
349 }
350
351 const commentUrl = `http://localhost:9001/videos/watch/${uuid};threadId=${threadId}`
352 function emailFinder (email: object) {
353 return email[ 'text' ].indexOf(commentUrl) !== -1
354 }
355
356 await checkNotification(base, notificationChecker, emailFinder, type)
357
358 if (type === 'presence') {
359 // We cannot detect email duplicates, so check we received another email
360 expect(base.emails).to.have.length.above(lastEmailCount)
361 lastEmailCount = base.emails.length
362 }
363}
364
365async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
366 const notificationType = UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS
367
368 function notificationChecker (notification: UserNotification, type: CheckerType) {
369 if (type === 'presence') {
370 expect(notification).to.not.be.undefined
371 expect(notification.type).to.equal(notificationType)
372
373 expect(notification.videoAbuse.id).to.be.a('number')
374 checkVideo(notification.videoAbuse.video, videoName, videoUUID)
375 } else {
376 expect(notification).to.satisfy((n: UserNotification) => {
377 return n === undefined || n.videoAbuse === undefined || n.videoAbuse.video.uuid !== videoUUID
378 })
379 }
380 }
381
382 function emailFinder (email: object) {
383 const text = email[ 'text' ]
384 return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1
385 }
386
387 await checkNotification(base, notificationChecker, emailFinder, type)
388}
389
390async function checkNewBlacklistOnMyVideo (
391 base: CheckerBaseParams,
392 videoUUID: string,
393 videoName: string,
394 blacklistType: 'blacklist' | 'unblacklist'
395) {
396 const notificationType = blacklistType === 'blacklist'
397 ? UserNotificationType.BLACKLIST_ON_MY_VIDEO
398 : UserNotificationType.UNBLACKLIST_ON_MY_VIDEO
399
400 function notificationChecker (notification: UserNotification) {
401 expect(notification).to.not.be.undefined
402 expect(notification.type).to.equal(notificationType)
403
404 const video = blacklistType === 'blacklist' ? notification.videoBlacklist.video : notification.video
405
406 checkVideo(video, videoName, videoUUID)
407 }
408
409 function emailFinder (email: object) {
410 const text = email[ 'text' ]
411 return text.indexOf(videoUUID) !== -1 && text.indexOf(' ' + blacklistType) !== -1
412 }
413
414 await checkNotification(base, notificationChecker, emailFinder, 'presence')
415}
416
417// ---------------------------------------------------------------------------
418
419export {
420 CheckerBaseParams,
421 CheckerType,
422 checkNotification,
423 markAsReadAllNotifications,
424 checkMyVideoImportIsFinished,
425 checkUserRegistered,
426 checkVideoIsPublished,
427 checkNewVideoFromSubscription,
428 checkNewActorFollow,
429 checkNewCommentOnMyVideo,
430 checkNewBlacklistOnMyVideo,
431 checkCommentMention,
432 updateMyNotificationSettings,
433 checkNewVideoAbuseForModerators,
434 getUserNotifications,
435 markAsReadNotifications,
436 getLastNotification
437}
diff --git a/server/tests/utils/users/user-subscriptions.ts b/shared/utils/users/user-subscriptions.ts
index 7148fbfca..7148fbfca 100644
--- a/server/tests/utils/users/user-subscriptions.ts
+++ b/shared/utils/users/user-subscriptions.ts
diff --git a/server/tests/utils/users/users.ts b/shared/utils/users/users.ts
index f12992315..61a7e3757 100644
--- a/server/tests/utils/users/users.ts
+++ b/shared/utils/users/users.ts
@@ -1,8 +1,8 @@
1import * as request from 'supertest' 1import * as request from 'supertest'
2import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../requests/requests' 2import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '../requests/requests'
3 3
4import { UserRole } from '../../../../shared/index' 4import { UserRole } from '../../index'
5import { NSFWPolicyType } from '../../../../shared/models/videos/nsfw-policy.type' 5import { NSFWPolicyType } from '../../models/videos/nsfw-policy.type'
6 6
7function createUser ( 7function createUser (
8 url: string, 8 url: string,
@@ -162,14 +162,15 @@ function unblockUser (url: string, userId: number | string, accessToken: string,
162 162
163function updateMyUser (options: { 163function updateMyUser (options: {
164 url: string 164 url: string
165 accessToken: string, 165 accessToken: string
166 currentPassword?: string, 166 currentPassword?: string
167 newPassword?: string, 167 newPassword?: string
168 nsfwPolicy?: NSFWPolicyType, 168 nsfwPolicy?: NSFWPolicyType
169 email?: string, 169 email?: string
170 autoPlayVideo?: boolean 170 autoPlayVideo?: boolean
171 displayName?: string, 171 displayName?: string
172 description?: string 172 description?: string
173 videosHistoryEnabled?: boolean
173}) { 174}) {
174 const path = '/api/v1/users/me' 175 const path = '/api/v1/users/me'
175 176
@@ -181,6 +182,9 @@ function updateMyUser (options: {
181 if (options.email !== undefined && options.email !== null) toSend['email'] = options.email 182 if (options.email !== undefined && options.email !== null) toSend['email'] = options.email
182 if (options.description !== undefined && options.description !== null) toSend['description'] = options.description 183 if (options.description !== undefined && options.description !== null) toSend['description'] = options.description
183 if (options.displayName !== undefined && options.displayName !== null) toSend['displayName'] = options.displayName 184 if (options.displayName !== undefined && options.displayName !== null) toSend['displayName'] = options.displayName
185 if (options.videosHistoryEnabled !== undefined && options.videosHistoryEnabled !== null) {
186 toSend['videosHistoryEnabled'] = options.videosHistoryEnabled
187 }
184 188
185 return makePutBodyRequest({ 189 return makePutBodyRequest({
186 url: options.url, 190 url: options.url,
diff --git a/server/tests/utils/videos/services.ts b/shared/utils/videos/services.ts
index 1a53dd4cf..1a53dd4cf 100644
--- a/server/tests/utils/videos/services.ts
+++ b/shared/utils/videos/services.ts
diff --git a/server/tests/utils/videos/video-abuses.ts b/shared/utils/videos/video-abuses.ts
index 4ad82ad8c..7f011ec0f 100644
--- a/server/tests/utils/videos/video-abuses.ts
+++ b/shared/utils/videos/video-abuses.ts
@@ -1,5 +1,5 @@
1import * as request from 'supertest' 1import * as request from 'supertest'
2import { VideoAbuseUpdate } from '../../../../shared/models/videos/abuse/video-abuse-update.model' 2import { VideoAbuseUpdate } from '../../models/videos/abuse/video-abuse-update.model'
3import { makeDeleteRequest, makePutBodyRequest } from '../requests/requests' 3import { makeDeleteRequest, makePutBodyRequest } from '../requests/requests'
4 4
5function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) { 5function reportVideoAbuse (url: string, token: string, videoId: number | string, reason: string, specialStatus = 200) {
diff --git a/server/tests/utils/videos/video-blacklist.ts b/shared/utils/videos/video-blacklist.ts
index 2c176fde0..f2ae0ed26 100644
--- a/server/tests/utils/videos/video-blacklist.ts
+++ b/shared/utils/videos/video-blacklist.ts
@@ -1,11 +1,18 @@
1import * as request from 'supertest' 1import * as request from 'supertest'
2 2
3function addVideoToBlacklist (url: string, token: string, videoId: number | string, reason?: string, specialStatus = 204) { 3function addVideoToBlacklist (
4 url: string,
5 token: string,
6 videoId: number | string,
7 reason?: string,
8 unfederate?: boolean,
9 specialStatus = 204
10) {
4 const path = '/api/v1/videos/' + videoId + '/blacklist' 11 const path = '/api/v1/videos/' + videoId + '/blacklist'
5 12
6 return request(url) 13 return request(url)
7 .post(path) 14 .post(path)
8 .send({ reason }) 15 .send({ reason, unfederate })
9 .set('Accept', 'application/json') 16 .set('Accept', 'application/json')
10 .set('Authorization', 'Bearer ' + token) 17 .set('Authorization', 'Bearer ' + token)
11 .expect(specialStatus) 18 .expect(specialStatus)
diff --git a/server/tests/utils/videos/video-captions.ts b/shared/utils/videos/video-captions.ts
index 8d67f617b..8d67f617b 100644
--- a/server/tests/utils/videos/video-captions.ts
+++ b/shared/utils/videos/video-captions.ts
diff --git a/server/tests/utils/videos/video-change-ownership.ts b/shared/utils/videos/video-change-ownership.ts
index f288692ea..f288692ea 100644
--- a/server/tests/utils/videos/video-change-ownership.ts
+++ b/shared/utils/videos/video-change-ownership.ts
diff --git a/server/tests/utils/videos/video-channels.ts b/shared/utils/videos/video-channels.ts
index 70e8d1a6b..3935c261e 100644
--- a/server/tests/utils/videos/video-channels.ts
+++ b/shared/utils/videos/video-channels.ts
@@ -1,5 +1,5 @@
1import * as request from 'supertest' 1import * as request from 'supertest'
2import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared/models/videos' 2import { VideoChannelCreate, VideoChannelUpdate } from '../../models/videos'
3import { updateAvatarRequest } from '../requests/requests' 3import { updateAvatarRequest } from '../requests/requests'
4 4
5function getVideoChannelsList (url: string, start: number, count: number, sort?: string) { 5function getVideoChannelsList (url: string, start: number, count: number, sort?: string) {
diff --git a/server/tests/utils/videos/video-comments.ts b/shared/utils/videos/video-comments.ts
index 0ebf69ced..0ebf69ced 100644
--- a/server/tests/utils/videos/video-comments.ts
+++ b/shared/utils/videos/video-comments.ts
diff --git a/shared/utils/videos/video-history.ts b/shared/utils/videos/video-history.ts
new file mode 100644
index 000000000..dc7095b4d
--- /dev/null
+++ b/shared/utils/videos/video-history.ts
@@ -0,0 +1,39 @@
1import { makeGetRequest, makePostBodyRequest, makePutBodyRequest } from '../requests/requests'
2
3function userWatchVideo (url: string, token: string, videoId: number | string, currentTime: number, statusCodeExpected = 204) {
4 const path = '/api/v1/videos/' + videoId + '/watching'
5 const fields = { currentTime }
6
7 return makePutBodyRequest({ url, path, token, fields, statusCodeExpected })
8}
9
10function listMyVideosHistory (url: string, token: string) {
11 const path = '/api/v1/users/me/history/videos'
12
13 return makeGetRequest({
14 url,
15 path,
16 token,
17 statusCodeExpected: 200
18 })
19}
20
21function removeMyVideosHistory (url: string, token: string, beforeDate?: string) {
22 const path = '/api/v1/users/me/history/videos/remove'
23
24 return makePostBodyRequest({
25 url,
26 path,
27 token,
28 fields: beforeDate ? { beforeDate } : {},
29 statusCodeExpected: 204
30 })
31}
32
33// ---------------------------------------------------------------------------
34
35export {
36 userWatchVideo,
37 listMyVideosHistory,
38 removeMyVideosHistory
39}
diff --git a/server/tests/utils/videos/video-imports.ts b/shared/utils/videos/video-imports.ts
index eb985a5b1..ec77cdcda 100644
--- a/server/tests/utils/videos/video-imports.ts
+++ b/shared/utils/videos/video-imports.ts
@@ -1,4 +1,5 @@
1import { VideoImportCreate } from '../../../../shared/models/videos' 1
2import { VideoImportCreate } from '../../models/videos'
2import { makeGetRequest, makeUploadRequest } from '../requests/requests' 3import { makeGetRequest, makeUploadRequest } from '../requests/requests'
3 4
4function getYoutubeVideoUrl () { 5function getYoutubeVideoUrl () {
@@ -10,6 +11,10 @@ function getMagnetURI () {
10 return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4' 11 return 'magnet:?xs=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Ftorrents%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.torrent&xt=urn:btih:0f498834733e8057ed5c6f2ee2b4efd8d84a76ee&dn=super+peertube2+video&tr=wss%3A%2F%2Fpeertube2.cpy.re%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube2.cpy.re%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube2.cpy.re%2Fstatic%2Fwebseed%2Fb209ca00-c8bb-4b2b-b421-1ede169f3dbc-720.mp4'
11} 12}
12 13
14function getBadVideoUrl () {
15 return 'https://download.cpy.re/peertube/bad_video.mp4'
16}
17
13function importVideo (url: string, token: string, attributes: VideoImportCreate) { 18function importVideo (url: string, token: string, attributes: VideoImportCreate) {
14 const path = '/api/v1/videos/imports' 19 const path = '/api/v1/videos/imports'
15 20
@@ -44,6 +49,7 @@ function getMyVideoImports (url: string, token: string, sort?: string) {
44// --------------------------------------------------------------------------- 49// ---------------------------------------------------------------------------
45 50
46export { 51export {
52 getBadVideoUrl,
47 getYoutubeVideoUrl, 53 getYoutubeVideoUrl,
48 importVideo, 54 importVideo,
49 getMagnetURI, 55 getMagnetURI,
diff --git a/server/tests/utils/videos/videos.ts b/shared/utils/videos/videos.ts
index d6c3e5dac..0cf6e7c4f 100644
--- a/server/tests/utils/videos/videos.ts
+++ b/shared/utils/videos/videos.ts
@@ -16,8 +16,9 @@ import {
16 ServerInfo, 16 ServerInfo,
17 testImage 17 testImage
18} from '../' 18} from '../'
19import { VideoDetails, VideoPrivacy } from '../../../../shared/models/videos' 19
20import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../initializers/constants' 20import { VideoDetails, VideoPrivacy } from '../../models/videos'
21import { VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants'
21import { dateIsValid, webtorrentAdd } from '../miscs/miscs' 22import { dateIsValid, webtorrentAdd } from '../miscs/miscs'
22 23
23type VideoAttributes = { 24type VideoAttributes = {
@@ -270,7 +271,7 @@ function removeVideo (url: string, token: string, id: number | string, expectedS
270async function checkVideoFilesWereRemoved ( 271async function checkVideoFilesWereRemoved (
271 videoUUID: string, 272 videoUUID: string,
272 serverNumber: number, 273 serverNumber: number,
273 directories = [ 'videos', 'thumbnails', 'torrents', 'previews', 'captions' ] 274 directories = [ 'redundancy', 'videos', 'thumbnails', 'torrents', 'previews', 'captions' ]
274) { 275) {
275 const testDirectory = 'test' + serverNumber 276 const testDirectory = 'test' + serverNumber
276 277
@@ -416,7 +417,7 @@ function rateVideo (url: string, accessToken: string, id: number, rating: string
416function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) { 417function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) {
417 return new Promise<any>((res, rej) => { 418 return new Promise<any>((res, rej) => {
418 const torrentName = videoUUID + '-' + resolution + '.torrent' 419 const torrentName = videoUUID + '-' + resolution + '.torrent'
419 const torrentPath = join(__dirname, '..', '..', '..', '..', 'test' + server.serverNumber, 'torrents', torrentName) 420 const torrentPath = join(root(), 'test' + server.serverNumber, 'torrents', torrentName)
420 readFile(torrentPath, (err, data) => { 421 readFile(torrentPath, (err, data) => {
421 if (err) return rej(err) 422 if (err) return rej(err)
422 423
diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml
index 9848c93ee..f2bb945f9 100644
--- a/support/doc/api/openapi.yaml
+++ b/support/doc/api/openapi.yaml
@@ -1,7 +1,7 @@
1openapi: 3.0.0 1openapi: 3.0.0
2info: 2info:
3 title: PeerTube 3 title: PeerTube
4 version: 1.1.0 4 version: 1.2.0
5 contact: 5 contact:
6 name: PeerTube Community 6 name: PeerTube Community
7 url: 'https://joinpeertube.org' 7 url: 'https://joinpeertube.org'
@@ -23,7 +23,7 @@ info:
23 23
24 # Authentication 24 # Authentication
25 When you sign up for an account, you are given the possibility to generate 25 When you sign up for an account, you are given the possibility to generate
26 sessions, and authenticate using this session token. One session token can 26 sessions, and authenticate using this session token. One session token can
27 currently be used at a time. 27 currently be used at a time.
28 28
29 # Errors 29 # Errors
@@ -61,7 +61,7 @@ tags:
61 description: > 61 description: >
62 Managing servers which the instance interacts with is crucial to the 62 Managing servers which the instance interacts with is crucial to the
63 concept of federation in PeerTube and external video indexation. The PeerTube 63 concept of federation in PeerTube and external video indexation. The PeerTube
64 server then deals with inter-server ActivityPub operations and propagates 64 server then deals with inter-server ActivityPub operations and propagates
65 information across its social graph by posting activities to actors' inbox 65 information across its social graph by posting activities to actors' inbox
66 endpoints. 66 endpoints.
67 - name: Video Abuse 67 - name: Video Abuse
@@ -492,7 +492,8 @@ paths:
492 get: 492 get:
493 summary: Get current user information 493 summary: Get current user information
494 security: 494 security:
495 - OAuth2: [] 495 - OAuth2:
496 - user
496 tags: 497 tags:
497 - User 498 - User
498 responses: 499 responses:
@@ -507,7 +508,8 @@ paths:
507 put: 508 put:
508 summary: Update current user information 509 summary: Update current user information
509 security: 510 security:
510 - OAuth2: [] 511 - OAuth2:
512 - user
511 tags: 513 tags:
512 - User 514 - User
513 responses: 515 responses:
@@ -523,7 +525,8 @@ paths:
523 get: 525 get:
524 summary: Get current user used quota 526 summary: Get current user used quota
525 security: 527 security:
526 - OAuth2: [] 528 - OAuth2:
529 - user
527 tags: 530 tags:
528 - User 531 - User
529 responses: 532 responses:
@@ -558,7 +561,71 @@ paths:
558 get: 561 get:
559 summary: Get videos of the current user 562 summary: Get videos of the current user
560 security: 563 security:
561 - OAuth2: [] 564 - OAuth2:
565 - user
566 tags:
567 - User
568 parameters:
569 - $ref: '#/components/parameters/start'
570 - $ref: '#/components/parameters/count'
571 - $ref: '#/components/parameters/sort'
572 responses:
573 '200':
574 description: successful operation
575 content:
576 application/json:
577 schema:
578 type: array
579 items:
580 $ref: '#/components/schemas/Video'
581 /users/me/subscriptions:
582 get:
583 summary: Get subscriptions of the current user
584 security:
585 - OAuth2:
586 - user
587 tags:
588 - User
589 parameters:
590 - $ref: '#/components/parameters/start'
591 - $ref: '#/components/parameters/count'
592 - $ref: '#/components/parameters/sort'
593 responses:
594 '200':
595 description: successful operation
596 post:
597 summary: Add subscription to the current user
598 security:
599 - OAuth2:
600 - user
601 tags:
602 - User
603 responses:
604 '200':
605 description: successful operation
606 /users/me/subscriptions/exist:
607 get:
608 summary: Get if subscriptions exist for the current user
609 security:
610 - OAuth2:
611 - user
612 tags:
613 - User
614 parameters:
615 - $ref: '#/components/parameters/subscriptionsUris'
616 responses:
617 '200':
618 description: successful operation
619 content:
620 application/json:
621 schema:
622 type: object
623 /users/me/subscriptions/videos:
624 get:
625 summary: Get videos of subscriptions of the current user
626 security:
627 - OAuth2:
628 - user
562 tags: 629 tags:
563 - User 630 - User
564 parameters: 631 parameters:
@@ -574,6 +641,31 @@ paths:
574 type: array 641 type: array
575 items: 642 items:
576 $ref: '#/components/schemas/Video' 643 $ref: '#/components/schemas/Video'
644 '/users/me/subscriptions/{uri}':
645 get:
646 summary: Get subscription of the current user for a given uri
647 security:
648 - OAuth2:
649 - user
650 tags:
651 - User
652 responses:
653 '200':
654 description: successful operation
655 content:
656 application/json:
657 schema:
658 $ref: '#/components/schemas/VideoChannel'
659 delete:
660 summary: Delete subscription of the current user for a given uri
661 security:
662 - OAuth2:
663 - user
664 tags:
665 - User
666 responses:
667 '200':
668 description: successful operation
577 /users/register: 669 /users/register:
578 post: 670 post:
579 summary: Register a user 671 summary: Register a user
@@ -751,7 +843,9 @@ paths:
751 type: string 843 type: string
752 tags: 844 tags:
753 description: Video tags 845 description: Video tags
754 type: string 846 type: array
847 items:
848 type: string
755 commentsEnabled: 849 commentsEnabled:
756 description: Enable or disable comments for this video 850 description: Enable or disable comments for this video
757 type: string 851 type: string
@@ -820,7 +914,7 @@ paths:
820 $ref: '#/paths/~1users~1me/put/responses/204' 914 $ref: '#/paths/~1users~1me/put/responses/204'
821 '/videos/{id}/watching': 915 '/videos/{id}/watching':
822 put: 916 put:
823 summary: Indicate progress of in watching the video by its id for a user 917 summary: Set watching progress of a video by its id for a user
824 tags: 918 tags:
825 - Video 919 - Video
826 security: 920 security:
@@ -958,7 +1052,9 @@ paths:
958 type: string 1052 type: string
959 tags: 1053 tags:
960 description: Video tags 1054 description: Video tags
961 type: string 1055 type: array
1056 items:
1057 type: string
962 commentsEnabled: 1058 commentsEnabled:
963 description: Enable or disable comments for this video 1059 description: Enable or disable comments for this video
964 type: string 1060 type: string
@@ -1434,6 +1530,8 @@ components:
1434 - type: array 1530 - type: array
1435 items: 1531 items:
1436 type: number 1532 type: number
1533 style: form
1534 explode: false
1437 tagsOneOf: 1535 tagsOneOf:
1438 name: tagsOneOf 1536 name: tagsOneOf
1439 in: query 1537 in: query
@@ -1445,6 +1543,8 @@ components:
1445 - type: array 1543 - type: array
1446 items: 1544 items:
1447 type: string 1545 type: string
1546 style: form
1547 explode: false
1448 tagsAllOf: 1548 tagsAllOf:
1449 name: tagsAllOf 1549 name: tagsAllOf
1450 in: query 1550 in: query
@@ -1456,6 +1556,8 @@ components:
1456 - type: array 1556 - type: array
1457 items: 1557 items:
1458 type: string 1558 type: string
1559 style: form
1560 explode: false
1459 languageOneOf: 1561 languageOneOf:
1460 name: languageOneOf 1562 name: languageOneOf
1461 in: query 1563 in: query
@@ -1463,10 +1565,12 @@ components:
1463 description: language id of the video 1565 description: language id of the video
1464 schema: 1566 schema:
1465 oneOf: 1567 oneOf:
1466 - type: number 1568 - type: string
1467 - type: array 1569 - type: array
1468 items: 1570 items:
1469 type: number 1571 type: string
1572 style: form
1573 explode: false
1470 licenceOneOf: 1574 licenceOneOf:
1471 name: licenceOneOf 1575 name: licenceOneOf
1472 in: query 1576 in: query
@@ -1478,6 +1582,8 @@ components:
1478 - type: array 1582 - type: array
1479 items: 1583 items:
1480 type: number 1584 type: number
1585 style: form
1586 explode: false
1481 nsfw: 1587 nsfw:
1482 name: nsfw 1588 name: nsfw
1483 in: query 1589 in: query
@@ -1501,6 +1607,15 @@ components:
1501 enum: 1607 enum:
1502 - local 1608 - local
1503 - all-local 1609 - all-local
1610 subscriptionsUris:
1611 name: uris
1612 in: query
1613 required: true
1614 description: list of uris to check if each is part of the user subscriptions
1615 schema:
1616 type: array
1617 items:
1618 type: string
1504 requestBodies: 1619 requestBodies:
1505 VideoChannelInput: 1620 VideoChannelInput:
1506 content: 1621 content:
diff --git a/support/doc/tools.md b/support/doc/tools.md
index 1c7739525..1a9ba7d2b 100644
--- a/support/doc/tools.md
+++ b/support/doc/tools.md
@@ -4,13 +4,13 @@
4<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> 4<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
5**Table of Contents** 5**Table of Contents**
6 6
7- [CLI wrapper](#cli-wrapper)
8- [Remote Tools](#remote-tools) 7- [Remote Tools](#remote-tools)
9 - [Dependencies](#dependencies) 8 - [Dependencies](#dependencies)
10 - [Installation](#installation) 9 - [Installation](#installation)
11 - [peertube-import-videos.js](#peertube-import-videosjs) 10 - [CLI wrapper](#cli-wrapper)
12 - [peertube-upload.js](#peertube-uploadjs) 11 - [peertube-import-videos.js](#peertube-import-videosjs)
13 - [peertube-watch.js](#peertube-watchjs) 12 - [peertube-upload.js](#peertube-uploadjs)
13 - [peertube-watch.js](#peertube-watchjs)
14- [Server tools](#server-tools) 14- [Server tools](#server-tools)
15 - [parse-log](#parse-log) 15 - [parse-log](#parse-log)
16 - [create-transcoding-job.js](#create-transcoding-jobjs) 16 - [create-transcoding-job.js](#create-transcoding-jobjs)
@@ -26,9 +26,41 @@
26 26
27<!-- END doctoc generated TOC please keep comment here to allow auto update --> 27<!-- END doctoc generated TOC please keep comment here to allow auto update -->
28 28
29## CLI wrapper 29## Remote Tools
30
31You need at least 512MB RAM to run the script.
32Scripts can be launched directly from a PeerTube server, or from a separate server, even a desktop PC.
33You need to follow all the following steps even if you are on a PeerTube server (including cloning the git repository in a different directory than your production installation because the scripts utilize non-production dependencies).
34
35### Dependencies
36
37Install the [PeerTube dependencies](dependencies.md).
38
39### Installation
40
41Clone the PeerTube repo to get the latest version (even if you are on your PeerTube server):
42
43```
44$ git clone https://github.com/Chocobozzz/PeerTube.git
45$ CLONE="$(pwd)/PeerTube"
46```
47
48Run ``yarn install --pure-lockfile``
49```
50$ cd ${CLONE}
51$ yarn install --pure-lockfile
52```
53
54Build server tools:
55```
56$ cd ${CLONE}
57$ npm run build:server
58```
59
60### CLI wrapper
30 61
31The wrapper provides a convenient interface to most scripts, and requires the [same dependencies](#dependencies). You can access it as `peertube` via an alias in your `.bashrc` like `alias peertube="node ${PEERTUBE_PATH}/dist/server/tools/peertube.js"`: 62The wrapper provides a convenient interface to the following scripts.
63You can access it as `peertube` via an alias in your `.bashrc` like `alias peertube="cd /your/peertube/directory/ && node ./dist/server/tools/peertube.js"` (you have to keep the `cd` command):
32 64
33``` 65```
34 Usage: peertube [command] [options] 66 Usage: peertube [command] [options]
@@ -51,12 +83,12 @@ The wrapper provides a convenient interface to most scripts, and requires the [s
51The wrapper can keep track of instances you have an account on. We limit to one account per instance for now. 83The wrapper can keep track of instances you have an account on. We limit to one account per instance for now.
52 84
53```bash 85```bash
54$ peertube auth add -u "PEERTUBE_URL" -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD" 86$ peertube auth add -u 'PEERTUBE_URL' -U 'PEERTUBE_USER' --password 'PEERTUBE_PASSWORD'
55$ peertube auth list 87$ peertube auth list
56┌──────────────────────────────┬──────────────────────────────┠88┌──────────────────────────────┬──────────────────────────────â”
57│ instance │ login │ 89│ instance │ login │
58├──────────────────────────────┼──────────────────────────────┤ 90├──────────────────────────────┼──────────────────────────────┤
59│ "PEERTUBE_URL" │ "PEERTUBE_USER" │ 91│ 'PEERTUBE_URL' │ 'PEERTUBE_USER' │
60└──────────────────────────────┴──────────────────────────────┘ 92└──────────────────────────────┴──────────────────────────────┘
61``` 93```
62 94
@@ -72,53 +104,22 @@ And now that your video is online, you can watch it from the confort of your ter
72$ peertube watch https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10 104$ peertube watch https://peertube.cpy.re/videos/watch/e8a1af4e-414a-4d58-bfe6-2146eed06d10
73``` 105```
74 106
75## Remote Tools 107#### peertube-import-videos.js
76
77You need at least 512MB RAM to run the script.
78Scripts can be launched directly from a PeerTube server, or from a separate server, even a desktop PC.
79You need to follow all the following steps even if you are on a PeerTube server (including cloning the git repository in a different directory than your production installation because the scripts utilize non-production dependencies).
80
81### Dependencies
82
83Install the [PeerTube dependencies](dependencies.md).
84
85### Installation
86
87Clone the PeerTube repo to get the latest version (even if you are on your PeerTube server):
88
89```
90$ git clone https://github.com/Chocobozzz/PeerTube.git
91$ CLONE="$(pwd)/PeerTube"
92```
93
94Run ``yarn install``
95```
96$ cd ${CLONE}
97$ yarn install
98```
99
100Build server tools:
101```
102$ cd ${CLONE}
103$ npm run build:server
104```
105
106### peertube-import-videos.js
107 108
108You can use this script to import videos from all [supported sites of youtube-dl](https://rg3.github.io/youtube-dl/supportedsites.html) into PeerTube. 109You can use this script to import videos from all [supported sites of youtube-dl](https://rg3.github.io/youtube-dl/supportedsites.html) into PeerTube.
109Be sure you own the videos or have the author's authorization to do so. 110Be sure you own the videos or have the author's authorization to do so.
110 111
111```sh 112```sh
112$ node dist/server/tools/peertube-import-videos.js \ 113$ node dist/server/tools/peertube-import-videos.js \
113 -u "PEERTUBE_URL" \ 114 -u 'PEERTUBE_URL' \
114 -U "PEERTUBE_USER" \ 115 -U 'PEERTUBE_USER' \
115 --password "PEERTUBE_PASSWORD" \ 116 --password 'PEERTUBE_PASSWORD' \
116 -t "TARGET_URL" 117 -t 'TARGET_URL'
117``` 118```
118 119
119* `PEERTUBE_URL` : the full URL of your PeerTube server where you want to import, eg: https://peertube.cpy.re 120* `PEERTUBE_URL` : the full URL of your PeerTube server where you want to import, eg: https://peertube.cpy.re
120* `PEERTUBE_USER` : your PeerTube account where videos will be uploaded 121* `PEERTUBE_USER` : your PeerTube account where videos will be uploaded
121* `PEERTUBE_PASSWORD` : password of your PeerTube account (if omitted, you will be prompted for it) 122* `PEERTUBE_PASSWORD` : password of your PeerTube account (if `PEERTUBE_PASSWORD` is omitted, you will be prompted for it)
122* `TARGET_URL` : the target url you want to import. Examples: 123* `TARGET_URL` : the target url you want to import. Examples:
123 * YouTube: 124 * YouTube:
124 * Channel: https://www.youtube.com/channel/ChannelId 125 * Channel: https://www.youtube.com/channel/ChannelId
@@ -133,7 +134,7 @@ Already downloaded videos will not be uploaded twice, so you can run and re-run
133Videos will be publicly available after transcoding (you can see them before that in your account on the web interface). 134Videos will be publicly available after transcoding (you can see them before that in your account on the web interface).
134 135
135 136
136### peertube-upload.js 137#### peertube-upload.js
137 138
138You can use this script to import videos directly from the CLI. 139You can use this script to import videos directly from the CLI.
139 140
@@ -144,7 +145,7 @@ $ cd ${CLONE}
144$ node dist/server/tools/peertube-upload.js --help 145$ node dist/server/tools/peertube-upload.js --help
145``` 146```
146 147
147### peertube-watch.js 148#### peertube-watch.js
148 149
149You can use this script to play videos directly from the CLI. 150You can use this script to play videos directly from the CLI.
150 151
@@ -198,10 +199,10 @@ $ sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production
198### prune-storage.js 199### prune-storage.js
199 200
200Some transcoded videos or shutdown at a bad time can leave some unused files on your storage. 201Some transcoded videos or shutdown at a bad time can leave some unused files on your storage.
201To delete them (a confirmation will be demanded first): 202Stop PeerTube and delete these files (a confirmation will be demanded first):
202 203
203``` 204```
204$ sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run prune-storage 205$ sudo systemctl stop peertube && sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run prune-storage
205``` 206```
206 207
207### optimize-old-videos.js 208### optimize-old-videos.js
diff --git a/support/docker/production/.env b/support/docker/production/.env
index f27def3b4..802d6b2ca 100644
--- a/support/docker/production/.env
+++ b/support/docker/production/.env
@@ -18,3 +18,4 @@ PEERTUBE_ADMIN_EMAIL=admin@domain.tld
18# /!\ Prefer to use the PeerTube admin interface to set the following configurations /!\ 18# /!\ Prefer to use the PeerTube admin interface to set the following configurations /!\
19#PEERTUBE_SIGNUP_ENABLED=true 19#PEERTUBE_SIGNUP_ENABLED=true
20#PEERTUBE_TRANSCODING_ENABLED=true 20#PEERTUBE_TRANSCODING_ENABLED=true
21#PEERTUBE_CONTACT_FORM_ENABLED=true
diff --git a/support/docker/production/config/custom-environment-variables.yaml b/support/docker/production/config/custom-environment-variables.yaml
index cfc30632c..8604939aa 100644
--- a/support/docker/production/config/custom-environment-variables.yaml
+++ b/support/docker/production/config/custom-environment-variables.yaml
@@ -50,6 +50,11 @@ user:
50admin: 50admin:
51 email: "PEERTUBE_ADMIN_EMAIL" 51 email: "PEERTUBE_ADMIN_EMAIL"
52 52
53contact_form:
54 enabled:
55 __name: "PEERTUBE_CONTACT_FORM_ENABLED"
56 __format: "json"
57
53signup: 58signup:
54 enabled: 59 enabled:
55 __name: "PEERTUBE_SIGNUP_ENABLED" 60 __name: "PEERTUBE_SIGNUP_ENABLED"
@@ -101,9 +106,11 @@ transcoding:
101 1080: 106 1080:
102 __name: "PEERTUBE_TRANSCODING_1080P" 107 __name: "PEERTUBE_TRANSCODING_1080P"
103 __format: "json" 108 __format: "json"
104
105 109
106instance: 110instance:
107 name: "PEERTUBE_INSTANCE_NAME" 111 name: "PEERTUBE_INSTANCE_NAME"
108 description: "PEERTUBE_INSTANCE_DESCRIPTION" 112 description: "PEERTUBE_INSTANCE_DESCRIPTION"
109 terms: "PEERTUBE_INSTANCE_TERMS" 113 terms: "PEERTUBE_INSTANCE_TERMS"
114
115services:
116 csp-logger: "PEERTUBE_SERVICES_CSPLOGGER"
diff --git a/support/docker/production/config/production.yaml b/support/docker/production/config/production.yaml
index 4970bbcca..846c838e8 100644
--- a/support/docker/production/config/production.yaml
+++ b/support/docker/production/config/production.yaml
@@ -32,8 +32,10 @@ redis:
32 32
33# From the project root directory 33# From the project root directory
34storage: 34storage:
35 tmp: '../data/tmp/'
35 avatars: '../data/avatars/' 36 avatars: '../data/avatars/'
36 videos: '../data/videos/' 37 videos: '../data/videos/'
38 redundancy: '../data/redundancy/'
37 logs: '../data/logs/' 39 logs: '../data/logs/'
38 previews: '../data/previews/' 40 previews: '../data/previews/'
39 thumbnails: '../data/thumbnails/' 41 thumbnails: '../data/thumbnails/'
diff --git a/support/docker/production/docker-entrypoint.sh b/support/docker/production/docker-entrypoint.sh
index 6dbbfddf6..7dd626b9f 100755
--- a/support/docker/production/docker-entrypoint.sh
+++ b/support/docker/production/docker-entrypoint.sh
@@ -9,7 +9,7 @@ fi
9# Always copy default and custom env configuration file, in cases where new keys were added 9# Always copy default and custom env configuration file, in cases where new keys were added
10cp /app/config/default.yaml /config 10cp /app/config/default.yaml /config
11cp /app/support/docker/production/config/custom-environment-variables.yaml /config 11cp /app/support/docker/production/config/custom-environment-variables.yaml /config
12chown -R peertube:peertube /config 12find /config ! -user peertube -exec chown peertube:peertube {} \;
13 13
14# first arg is `-f` or `--some-option` 14# first arg is `-f` or `--some-option`
15# or first arg is `something.conf` 15# or first arg is `something.conf`
@@ -19,7 +19,7 @@ fi
19 19
20# allow the container to be started with `--user` 20# allow the container to be started with `--user`
21if [ "$1" = 'npm' -a "$(id -u)" = '0' ]; then 21if [ "$1" = 'npm' -a "$(id -u)" = '0' ]; then
22 chown -R peertube:peertube /data 22 find /data ! -user peertube -exec chown peertube:peertube {} \;
23 exec gosu peertube "$0" "$@" 23 exec gosu peertube "$0" "$@"
24fi 24fi
25 25
diff --git a/support/freebsd/peertube b/support/freebsd/peertube
index 78fdf5848..5d14c58ae 100755
--- a/support/freebsd/peertube
+++ b/support/freebsd/peertube
@@ -16,6 +16,7 @@ load_rc_config $name
16 16
17: ${peertube_enable:=NO} 17: ${peertube_enable:=NO}
18 18
19sig_stop=-KILL
19peertube_chdir="/var/www/peertube/peertube-latest" 20peertube_chdir="/var/www/peertube/peertube-latest"
20peertube_env="HOME=/var/www/peertube \ 21peertube_env="HOME=/var/www/peertube \
21NODE_ENV=production \ 22NODE_ENV=production \
@@ -23,7 +24,7 @@ NODE_CONFIG_DIR=/var/www/peertube/config \
23USER=peertube" 24USER=peertube"
24peertube_user=peertube 25peertube_user=peertube
25 26
26command="/usr/local/bin/npm" 27command="/usr/local/bin/node"
27command_args="start >> /var/log/peertube/${name}.log 2>&1 &" 28command_args="dist/server >> /var/log/peertube/${name}.log 2>&1 &"
28 29
29run_rc_command "$1" 30run_rc_command "$1"
diff --git a/support/nginx/peertube b/support/nginx/peertube
index b00031133..54ffdcc32 100644
--- a/support/nginx/peertube
+++ b/support/nginx/peertube
@@ -96,8 +96,18 @@ server {
96 proxy_set_header Host $host; 96 proxy_set_header Host $host;
97 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 97 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
98 98
99 # Hard limit, PeerTube does not support videos > 8GB 99 # This is the maximum upload size, which roughly matches the maximum size of a video file
100 # you can send via the API or the web interface. By default this is 8GB, but administrators
101 # can increase or decrease the limit. Currently there's no way to communicate this limit
102 # to users automatically, so you may want to leave a note in your instance 'about' page if
103 # you change this.
104 #
105 # Note that temporary space is needed equal to the total size of all concurrent uploads.
106 # This data gets stored in /var/lib/nginx by default, so you may want to put this directory
107 # on a dedicated filesystem.
108 #
100 client_max_body_size 8G; 109 client_max_body_size 8G;
110
101 proxy_connect_timeout 600; 111 proxy_connect_timeout 600;
102 proxy_send_timeout 600; 112 proxy_send_timeout 600;
103 proxy_read_timeout 600; 113 proxy_read_timeout 600;
@@ -105,7 +115,7 @@ server {
105 } 115 }
106 116
107 # Bypass PeerTube for performance reasons. Could be removed 117 # Bypass PeerTube for performance reasons. Could be removed
108 location /static/webseed { 118 location ~ ^/static/(webseed|redundancy)/ {
109 # Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client 119 # Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client
110 limit_rate 800k; 120 limit_rate 800k;
111 121
@@ -128,7 +138,12 @@ server {
128 access_log off; 138 access_log off;
129 } 139 }
130 140
131 alias /var/www/peertube/storage/videos; 141 root /var/www/peertube/storage;
142
143 rewrite ^/static/webseed/(.*)$ /videos/$1 break;
144 rewrite ^/static/redundancy/(.*)$ /redundancy/$1 break;
145
146 try_files $uri /;
132 } 147 }
133 148
134 # Websocket tracker 149 # Websocket tracker
@@ -143,4 +158,16 @@ server {
143 proxy_set_header Host $host; 158 proxy_set_header Host $host;
144 proxy_pass http://localhost:9000; 159 proxy_pass http://localhost:9000;
145 } 160 }
161
162 location /socket.io {
163 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
164 proxy_set_header Host $host;
165
166 proxy_pass http://localhost:9000;
167
168 # enable WebSockets
169 proxy_http_version 1.1;
170 proxy_set_header Upgrade $http_upgrade;
171 proxy_set_header Connection "upgrade";
172 }
146} 173}
diff --git a/support/systemd/peertube.service b/support/systemd/peertube.service
index 88856385c..fba644788 100644
--- a/support/systemd/peertube.service
+++ b/support/systemd/peertube.service
@@ -15,5 +15,24 @@ StandardError=syslog
15SyslogIdentifier=peertube 15SyslogIdentifier=peertube
16Restart=always 16Restart=always
17 17
18; Some security directives.
19; Use private /tmp and /var/tmp folders inside a new file system namespace,
20; which are discarded after the process stops.
21PrivateTmp=true
22; Mount /usr, /boot, and /etc as read-only for processes invoked by this service.
23ProtectSystem=full
24; Sets up a new /dev mount for the process and only adds API pseudo devices
25; like /dev/null, /dev/zero or /dev/random but not physical devices. Disabled
26; by default because it may not work on devices like the Raspberry Pi.
27PrivateDevices=false
28; Ensures that the service process and all its children can never gain new
29; privileges through execve().
30NoNewPrivileges=true
31; This makes /home, /root, and /run/user inaccessible and empty for processes invoked
32; by this unit. Make sure that you do not depend on data inside these folders.
33ProtectHome=true
34; Drops the sys admin capability from the daemon.
35CapabilityBoundingSet=~CAP_SYS_ADMIN
36
18[Install] 37[Install]
19WantedBy=multi-user.target 38WantedBy=multi-user.target
diff --git a/yarn.lock b/yarn.lock
index b961fb5cc..1e759af1b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,6 +2,20 @@
2# yarn lockfile v1 2# yarn lockfile v1
3 3
4 4
5"@iamstarkov/listr-update-renderer@0.4.1":
6 version "0.4.1"
7 resolved "https://registry.yarnpkg.com/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz#d7c48092a2dcf90fd672b6c8b458649cb350c77e"
8 integrity sha512-IJyxQWsYDEkf8C8QthBn5N8tIUR9V9je6j3sMIpAkonaadjbvxmRC6RAhpa3RKxndhNnU2M6iNbtJwd7usQYIA==
9 dependencies:
10 chalk "^1.1.3"
11 cli-truncate "^0.2.1"
12 elegant-spinner "^1.0.1"
13 figures "^1.7.0"
14 indent-string "^3.0.0"
15 log-symbols "^1.0.2"
16 log-update "^2.3.0"
17 strip-ansi "^3.0.1"
18
5"@samverschueren/stream-to-observable@^0.3.0": 19"@samverschueren/stream-to-observable@^0.3.0":
6 version "0.3.0" 20 version "0.3.0"
7 resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" 21 resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
@@ -44,7 +58,7 @@
44 "@types/connect" "*" 58 "@types/connect" "*"
45 "@types/node" "*" 59 "@types/node" "*"
46 60
47"@types/bull@^3.3.12": 61"@types/bull@3.4.0":
48 version "3.4.0" 62 version "3.4.0"
49 resolved "https://registry.yarnpkg.com/@types/bull/-/bull-3.4.0.tgz#18ffefefa4dd1cfbdbdc8ca7df56c934459f6b9d" 63 resolved "https://registry.yarnpkg.com/@types/bull/-/bull-3.4.0.tgz#18ffefefa4dd1cfbdbdc8ca7df56c934459f6b9d"
50 integrity sha512-NVD2X+cUu1qNv6blsOfCr2fVsD3+O13U19dFuy9Du7PWfn1/gjFZEDk220uBuRSH5JyaP4nV6S8BLjsT5/bXUg== 64 integrity sha512-NVD2X+cUu1qNv6blsOfCr2fVsD3+O13U19dFuy9Du7PWfn1/gjFZEDk220uBuRSH5JyaP4nV6S8BLjsT5/bXUg==
@@ -233,9 +247,9 @@
233 "@types/express" "*" 247 "@types/express" "*"
234 248
235"@types/node@*", "@types/node@^10.0.8": 249"@types/node@*", "@types/node@^10.0.8":
236 version "10.12.8" 250 version "10.12.12"
237 resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.8.tgz#d0a3ab5a6e61458c492304e2776ac136b81db927" 251 resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.12.tgz#e15a9d034d9210f00320ef718a50c4a799417c47"
238 integrity sha512-INamyRZG4rW3lDCUmwVd5Xho/bXvQm/v1yP8V0UN1RuInU7RoWoaO570b+yLX4Ia/0szsx1wa8VzcsVlsvbWLA== 252 integrity sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A==
239 253
240"@types/node@6.0.41": 254"@types/node@6.0.41":
241 version "6.0.41" 255 version "6.0.41"
@@ -251,9 +265,9 @@
251 "@types/node" "*" 265 "@types/node" "*"
252 266
253"@types/oauth2-server@^3.0.8": 267"@types/oauth2-server@^3.0.8":
254 version "3.0.9" 268 version "3.0.10"
255 resolved "https://registry.yarnpkg.com/@types/oauth2-server/-/oauth2-server-3.0.9.tgz#e3f32011862f03f399635c5916d5a383bca26fe2" 269 resolved "https://registry.yarnpkg.com/@types/oauth2-server/-/oauth2-server-3.0.10.tgz#ea671a6ad3d02062aac5f7c1ba1fb9c468314db0"
256 integrity sha512-NixZjyKS4TCM1mMr6QViK0rxR8iMHiE1utYje+ZGne1SgJQzLT3OOAjCrnRp70G+L8W1BXnzIPPaIxj1kYJHNg== 270 integrity sha512-1XYQdBrBuGimRhGLk9XavjGY2h5IYmT0rTi3pDAWzq6xRWZp+LCAwNm8YNYdDwQxBp//eogtZePe8mS7QPDiNg==
257 dependencies: 271 dependencies:
258 "@types/express" "*" 272 "@types/express" "*"
259 273
@@ -284,9 +298,9 @@
284 integrity sha512-HtKGu+qG1NPvYe1z7ezLsyIaXYyi8SoAVqWDZgDQ8dLrsZvSzUNCwZyfX33uhWxL/SU0ZDQZ3nwZ0nimt507Kw== 298 integrity sha512-HtKGu+qG1NPvYe1z7ezLsyIaXYyi8SoAVqWDZgDQ8dLrsZvSzUNCwZyfX33uhWxL/SU0ZDQZ3nwZ0nimt507Kw==
285 299
286"@types/redis@^2.8.5": 300"@types/redis@^2.8.5":
287 version "2.8.7" 301 version "2.8.8"
288 resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.7.tgz#e0825093fb1af9d5b4a7246c6d7d1163cc842c35" 302 resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.8.tgz#70855e79a6020080cca3cb5f1f5ee7f11b49a979"
289 integrity sha512-ZMW8M5LRxU0D4u2GhnCEqJ1/mUJKSudlCWxeP1FRxfZQqr0Pb4tonPLzDEyRpC50uvEfAP3xOLjDuUOWi0QHCQ== 303 integrity sha512-o/1ufNVPA92uum9HFbEiXXIHBuLywSwHQtAZoACMc1FhPXS5YftybBC1EI0zjdbUb273VVWF0Ivll/bq4g+gyw==
290 dependencies: 304 dependencies:
291 "@types/node" "*" 305 "@types/node" "*"
292 306
@@ -332,6 +346,13 @@
332 dependencies: 346 dependencies:
333 "@types/node" "*" 347 "@types/node" "*"
334 348
349"@types/socket.io@^2.1.2":
350 version "2.1.2"
351 resolved "https://registry.yarnpkg.com/@types/socket.io/-/socket.io-2.1.2.tgz#7165c2587cc3b86b44aa78e2a0060140551de211"
352 integrity sha512-Ind+4qMNfQ62llyB4IMs1D8znMEBsMKohZBPqfBUIXqLQ9bdtWIbNTBWwtdcBWJKnokMZGcmWOOKslatni5vtA==
353 dependencies:
354 "@types/node" "*"
355
335"@types/superagent@*": 356"@types/superagent@*":
336 version "3.8.4" 357 version "3.8.4"
337 resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-3.8.4.tgz#24a5973c7d1a9c024b4bbda742a79267c33fb86a" 358 resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-3.8.4.tgz#24a5973c7d1a9c024b4bbda742a79267c33fb86a"
@@ -341,9 +362,9 @@
341 "@types/node" "*" 362 "@types/node" "*"
342 363
343"@types/supertest@^2.0.3": 364"@types/supertest@^2.0.3":
344 version "2.0.6" 365 version "2.0.7"
345 resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-2.0.6.tgz#a0665350c0e36315e1bccdf4785f2b76fcb71b6b" 366 resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-2.0.7.tgz#46ff6508075cd4519736be060f0d6331a5c8ca7b"
346 integrity sha512-qRvPP8dO7IBqJz8LaQ7/Lw2oo/geiDUPAMx/L+CQCkR9sN622O30XCH7RSyUmilyCSyjxyhJ7cEtd3hmwPwvhw== 367 integrity sha512-GibTh4OTkal71btYe2fpZP/rVHIPnnUsYphEaoywVHo+mo2a/LhlOFkIm5wdN0H0DA0Hx8x+tKgCYMD9elHu5w==
347 dependencies: 368 dependencies:
348 "@types/superagent" "*" 369 "@types/superagent" "*"
349 370
@@ -409,7 +430,7 @@ accepts@~1.2.12:
409 mime-types "~2.1.6" 430 mime-types "~2.1.6"
410 negotiator "0.5.3" 431 negotiator "0.5.3"
411 432
412accepts@~1.3.5: 433accepts@~1.3.4, accepts@~1.3.5:
413 version "1.3.5" 434 version "1.3.5"
414 resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" 435 resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
415 integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= 436 integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I=
@@ -477,9 +498,9 @@ ajv@^4.7.0:
477 json-stable-stringify "^1.0.1" 498 json-stable-stringify "^1.0.1"
478 499
479ajv@^6.5.5: 500ajv@^6.5.5:
480 version "6.5.5" 501 version "6.6.1"
481 resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" 502 resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61"
482 integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== 503 integrity sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==
483 dependencies: 504 dependencies:
484 fast-deep-equal "^2.0.1" 505 fast-deep-equal "^2.0.1"
485 fast-json-stable-stringify "^2.0.0" 506 fast-json-stable-stringify "^2.0.0"
@@ -638,6 +659,11 @@ arraybuffer.slice@0.0.6:
638 resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca" 659 resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz#f33b2159f0532a3f3107a272c0ccfbd1ad2979ca"
639 integrity sha1-8zshWfBTKj8xB6JywMz70a0peco= 660 integrity sha1-8zshWfBTKj8xB6JywMz70a0peco=
640 661
662arraybuffer.slice@~0.0.7:
663 version "0.0.7"
664 resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
665 integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
666
641arrify@^1.0.0, arrify@^1.0.1: 667arrify@^1.0.0, arrify@^1.0.1:
642 version "1.0.1" 668 version "1.0.1"
643 resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 669 resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
@@ -844,9 +870,9 @@ binary-search@^1.3.4:
844 integrity sha512-dPxU/vZLnH0tEVjVPgi015oSwqu6oLfCeHywuFRhBE0yM0mYocvleTl8qsdM1YFhRzTRhM1+VzS8XLDVrHPopg== 870 integrity sha512-dPxU/vZLnH0tEVjVPgi015oSwqu6oLfCeHywuFRhBE0yM0mYocvleTl8qsdM1YFhRzTRhM1+VzS8XLDVrHPopg==
845 871
846bindings@^1.3.0, bindings@~1.3.0: 872bindings@^1.3.0, bindings@~1.3.0:
847 version "1.3.0" 873 version "1.3.1"
848 resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" 874 resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.1.tgz#21fc7c6d67c18516ec5aaa2815b145ff77b26ea5"
849 integrity sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw== 875 integrity sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew==
850 876
851bindings@~1.2.1: 877bindings@~1.2.1:
852 version "1.2.1" 878 version "1.2.1"
@@ -963,6 +989,11 @@ blob@0.0.4:
963 resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921" 989 resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.4.tgz#bcf13052ca54463f30f9fc7e95b9a47630a94921"
964 integrity sha1-vPEwUspURj8w+fx+lbmkdjCpSSE= 990 integrity sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=
965 991
992blob@0.0.5:
993 version "0.0.5"
994 resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683"
995 integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==
996
966block-stream2@^1.0.0: 997block-stream2@^1.0.0:
967 version "1.1.0" 998 version "1.1.0"
968 resolved "https://registry.yarnpkg.com/block-stream2/-/block-stream2-1.1.0.tgz#c738e3a91ba977ebb5e1fef431e13ca11d8639e2" 999 resolved "https://registry.yarnpkg.com/block-stream2/-/block-stream2-1.1.0.tgz#c738e3a91ba977ebb5e1fef431e13ca11d8639e2"
@@ -1143,9 +1174,9 @@ builtins@^1.0.3:
1143 integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= 1174 integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og=
1144 1175
1145bull@^3.4.2: 1176bull@^3.4.2:
1146 version "3.5.1" 1177 version "3.5.2"
1147 resolved "https://registry.yarnpkg.com/bull/-/bull-3.5.1.tgz#b936a1306cb7e9dc1ac9c23a0dcaf41a1370effc" 1178 resolved "https://registry.yarnpkg.com/bull/-/bull-3.5.2.tgz#9c85f205b17686efab2ee28aaa4388887360de32"
1148 integrity sha512-stbptND5+uRmzd6gIUJlC93fikXKyrJl53HGxzyqD0ahCMeyFRlaD5kN1i+PqfZSkcHKx/kK3HOJ8knum/Yi7A== 1179 integrity sha512-tuL4Uj0kUeaQ7Cow3POkca20fk+VSsR8AiTFeNkyMmuicBnE1ZMwvF1NRDY7vIH43pD9PiMCSEP4Li/934Pw1w==
1149 dependencies: 1180 dependencies:
1150 bluebird "^3.5.3" 1181 bluebird "^3.5.3"
1151 cron-parser "^2.5.0" 1182 cron-parser "^2.5.0"
@@ -1283,6 +1314,11 @@ camelcase@^4.0.0, camelcase@^4.1.0:
1283 resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" 1314 resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
1284 integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= 1315 integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
1285 1316
1317camelcase@^5.0.0:
1318 version "5.0.0"
1319 resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42"
1320 integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==
1321
1286camelize@1.0.0: 1322camelize@1.0.0:
1287 version "1.0.0" 1323 version "1.0.0"
1288 resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" 1324 resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b"
@@ -1447,14 +1483,14 @@ cli-columns@^3.1.2:
1447 string-width "^2.0.0" 1483 string-width "^2.0.0"
1448 strip-ansi "^3.0.1" 1484 strip-ansi "^3.0.1"
1449 1485
1450cli-cursor@^1.0.1, cli-cursor@^1.0.2: 1486cli-cursor@^1.0.1:
1451 version "1.0.2" 1487 version "1.0.2"
1452 resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" 1488 resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
1453 integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc= 1489 integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=
1454 dependencies: 1490 dependencies:
1455 restore-cursor "^1.0.1" 1491 restore-cursor "^1.0.1"
1456 1492
1457cli-cursor@^2.0.0: 1493cli-cursor@^2.0.0, cli-cursor@^2.1.0:
1458 version "2.1.0" 1494 version "2.1.0"
1459 resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" 1495 resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
1460 integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= 1496 integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=
@@ -1701,15 +1737,15 @@ concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@^1.5.2:
1701 typedarray "^0.0.6" 1737 typedarray "^0.0.6"
1702 1738
1703concurrently@^4.0.1: 1739concurrently@^4.0.1:
1704 version "4.0.1" 1740 version "4.1.0"
1705 resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-4.0.1.tgz#f6310fbadf2f476dd95df952edb5c0ab789f672c" 1741 resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-4.1.0.tgz#17fdf067da71210685d9ea554423ef239da30d33"
1706 integrity sha512-D8UI+mlI/bfvrA57SeKOht6sEpb01dKk+8Yee4fbnkk1Ue8r3S+JXoEdFZIpzQlXJGtnxo47Wvvg/kG4ba3U6Q== 1742 integrity sha512-pwzXCE7qtOB346LyO9eFWpkFJVO3JQZ/qU/feGeaAHiX1M3Rw3zgXKc5cZ8vSH5DGygkjzLFDzA/pwoQDkRNGg==
1707 dependencies: 1743 dependencies:
1708 chalk "^2.4.1" 1744 chalk "^2.4.1"
1709 date-fns "^1.23.0" 1745 date-fns "^1.23.0"
1710 lodash "^4.17.10" 1746 lodash "^4.17.10"
1711 read-pkg "^4.0.1" 1747 read-pkg "^4.0.1"
1712 rxjs "6.2.2" 1748 rxjs "^6.3.3"
1713 spawn-command "^0.0.2-1" 1749 spawn-command "^0.0.2-1"
1714 supports-color "^4.5.0" 1750 supports-color "^4.5.0"
1715 tree-kill "^1.1.0" 1751 tree-kill "^1.1.0"
@@ -1723,10 +1759,10 @@ config-chain@~1.1.11:
1723 ini "^1.3.4" 1759 ini "^1.3.4"
1724 proto-list "~1.2.1" 1760 proto-list "~1.2.1"
1725 1761
1726config@^2.0.1: 1762config@^3.0.0:
1727 version "2.0.1" 1763 version "3.0.0"
1728 resolved "https://registry.yarnpkg.com/config/-/config-2.0.1.tgz#995ccc8175460578d646ac0a2e4018ffa44ca046" 1764 resolved "https://registry.yarnpkg.com/config/-/config-3.0.0.tgz#a71cdbb22d225df9eff20b95178d65a63c452367"
1729 integrity sha512-aTaviJnC8ZjQYx8kQf4u6tWqIxWolyQQ3LqXgnCLAsIb78JrUshHG0YuzIarzTaVVe1Pazms3TXImfYra8UsyQ== 1765 integrity sha512-QMr3BCOcHdgXx8t8cLfBhWtHcIAAMikaxUc2XASuH2A93g9kOIRch7sXFQdSvdMxhQobnctWm2y68YJYRttJlw==
1730 dependencies: 1766 dependencies:
1731 json5 "^1.0.1" 1767 json5 "^1.0.1"
1732 1768
@@ -1830,7 +1866,16 @@ cors@^2.8.1:
1830 object-assign "^4" 1866 object-assign "^4"
1831 vary "^1" 1867 vary "^1"
1832 1868
1833cosmiconfig@^5.0.2, cosmiconfig@^5.0.6: 1869cosmiconfig@5.0.6:
1870 version "5.0.6"
1871 resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39"
1872 integrity sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ==
1873 dependencies:
1874 is-directory "^0.3.1"
1875 js-yaml "^3.9.0"
1876 parse-json "^4.0.0"
1877
1878cosmiconfig@^5.0.6:
1834 version "5.0.7" 1879 version "5.0.7"
1835 resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" 1880 resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04"
1836 integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== 1881 integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA==
@@ -1867,9 +1912,9 @@ create-torrent@^3.24.5, create-torrent@^3.33.0:
1867 simple-sha1 "^2.0.0" 1912 simple-sha1 "^2.0.0"
1868 1913
1869cron-parser@^2.5.0: 1914cron-parser@^2.5.0:
1870 version "2.7.1" 1915 version "2.7.3"
1871 resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-2.7.1.tgz#d08c00b1e220db564fd1cecb5019c8dd450f84d1" 1916 resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-2.7.3.tgz#12603f89f5375af353a9357be2543d3172eac651"
1872 integrity sha512-gupE4KsGEVtp5X4YbUlQx6NiFt3e+VOhREPI4ZXS9FT5JcOjfw2ey1EUv3J6XWrxHR1aKYrk4uJDmdRjG39bgA== 1917 integrity sha512-t9Kc7HWBWPndBzvbdQ1YG9rpPRB37Tb/tTviziUOh1qs3TARGh3b1p+tnkOHNe1K5iI3oheBPgLqwotMM7+lpg==
1873 dependencies: 1918 dependencies:
1874 is-nan "^1.2.1" 1919 is-nan "^1.2.1"
1875 moment-timezone "^0.5.23" 1920 moment-timezone "^0.5.23"
@@ -1967,7 +2012,7 @@ debug@2.6.9, debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.
1967 dependencies: 2012 dependencies:
1968 ms "2.0.0" 2013 ms "2.0.0"
1969 2014
1970debug@3.1.0: 2015debug@3.1.0, debug@~3.1.0:
1971 version "3.1.0" 2016 version "3.1.0"
1972 resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 2017 resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
1973 integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 2018 integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
@@ -1988,23 +2033,23 @@ debug@^4.0.1:
1988 dependencies: 2033 dependencies:
1989 ms "^2.1.1" 2034 ms "^2.1.1"
1990 2035
2036debug@~4.1.0:
2037 version "4.1.1"
2038 resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
2039 integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
2040 dependencies:
2041 ms "^2.1.1"
2042
1991debuglog@^1.0.0, debuglog@^1.0.1: 2043debuglog@^1.0.0, debuglog@^1.0.1:
1992 version "1.0.1" 2044 version "1.0.1"
1993 resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" 2045 resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
1994 integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= 2046 integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
1995 2047
1996decamelize@^1.1.1: 2048decamelize@^1.1.1, decamelize@^1.2.0:
1997 version "1.2.0" 2049 version "1.2.0"
1998 resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 2050 resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
1999 integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 2051 integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
2000 2052
2001decamelize@^2.0.0:
2002 version "2.0.0"
2003 resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7"
2004 integrity sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==
2005 dependencies:
2006 xregexp "4.0.0"
2007
2008decode-uri-component@^0.2.0: 2053decode-uri-component@^0.2.0:
2009 version "0.2.0" 2054 version "0.2.0"
2010 resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" 2055 resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
@@ -2346,6 +2391,23 @@ engine.io-client@1.8.3:
2346 xmlhttprequest-ssl "1.5.3" 2391 xmlhttprequest-ssl "1.5.3"
2347 yeast "0.1.2" 2392 yeast "0.1.2"
2348 2393
2394engine.io-client@~3.3.1:
2395 version "3.3.1"
2396 resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.3.1.tgz#afedb4a07b2ea48b7190c3136bfea98fdd4f0f03"
2397 integrity sha512-q66JBFuQcy7CSlfAz9L3jH+v7DTT3i6ZEadYcVj2pOs8/0uJHLxKX3WBkGTvULJMdz0tUCyJag0aKT/dpXL9BQ==
2398 dependencies:
2399 component-emitter "1.2.1"
2400 component-inherit "0.0.3"
2401 debug "~3.1.0"
2402 engine.io-parser "~2.1.1"
2403 has-cors "1.1.0"
2404 indexof "0.0.1"
2405 parseqs "0.0.5"
2406 parseuri "0.0.5"
2407 ws "~6.1.0"
2408 xmlhttprequest-ssl "~1.5.4"
2409 yeast "0.1.2"
2410
2349engine.io-parser@1.3.2: 2411engine.io-parser@1.3.2:
2350 version "1.3.2" 2412 version "1.3.2"
2351 resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.2.tgz#937b079f0007d0893ec56d46cb220b8cb435220a" 2413 resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.2.tgz#937b079f0007d0893ec56d46cb220b8cb435220a"
@@ -2358,6 +2420,17 @@ engine.io-parser@1.3.2:
2358 has-binary "0.1.7" 2420 has-binary "0.1.7"
2359 wtf-8 "1.0.0" 2421 wtf-8 "1.0.0"
2360 2422
2423engine.io-parser@~2.1.0, engine.io-parser@~2.1.1:
2424 version "2.1.3"
2425 resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.1.3.tgz#757ab970fbf2dfb32c7b74b033216d5739ef79a6"
2426 integrity sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==
2427 dependencies:
2428 after "0.8.2"
2429 arraybuffer.slice "~0.0.7"
2430 base64-arraybuffer "0.1.5"
2431 blob "0.0.5"
2432 has-binary2 "~1.0.2"
2433
2361engine.io@1.8.3: 2434engine.io@1.8.3:
2362 version "1.8.3" 2435 version "1.8.3"
2363 resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.3.tgz#8de7f97895d20d39b85f88eeee777b2bd42b13d4" 2436 resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.3.tgz#8de7f97895d20d39b85f88eeee777b2bd42b13d4"
@@ -2370,6 +2443,18 @@ engine.io@1.8.3:
2370 engine.io-parser "1.3.2" 2443 engine.io-parser "1.3.2"
2371 ws "1.1.2" 2444 ws "1.1.2"
2372 2445
2446engine.io@~3.3.1:
2447 version "3.3.2"
2448 resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.3.2.tgz#18cbc8b6f36e9461c5c0f81df2b830de16058a59"
2449 integrity sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==
2450 dependencies:
2451 accepts "~1.3.4"
2452 base64id "1.0.0"
2453 cookie "0.3.1"
2454 debug "~3.1.0"
2455 engine.io-parser "~2.1.0"
2456 ws "~6.1.0"
2457
2373env-variable@0.0.x: 2458env-variable@0.0.x:
2374 version "0.0.5" 2459 version "0.0.5"
2375 resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88" 2460 resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88"
@@ -2644,10 +2729,10 @@ expand-brackets@^2.1.4:
2644 snapdragon "^0.8.1" 2729 snapdragon "^0.8.1"
2645 to-regex "^3.0.1" 2730 to-regex "^3.0.1"
2646 2731
2647expand-template@^1.0.2: 2732expand-template@^2.0.3:
2648 version "1.1.1" 2733 version "2.0.3"
2649 resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-1.1.1.tgz#981f188c0c3a87d2e28f559bc541426ff94f21dd" 2734 resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
2650 integrity sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg== 2735 integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
2651 2736
2652expect-ct@0.1.1: 2737expect-ct@0.1.1:
2653 version "0.1.1" 2738 version "0.1.1"
@@ -2837,6 +2922,13 @@ figures@^1.3.5, figures@^1.7.0:
2837 escape-string-regexp "^1.0.5" 2922 escape-string-regexp "^1.0.5"
2838 object-assign "^4.1.0" 2923 object-assign "^4.1.0"
2839 2924
2925figures@^2.0.0:
2926 version "2.0.0"
2927 resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
2928 integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=
2929 dependencies:
2930 escape-string-regexp "^1.0.5"
2931
2840file-entry-cache@^1.1.1: 2932file-entry-cache@^1.1.1:
2841 version "1.3.1" 2933 version "1.3.1"
2842 resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-1.3.1.tgz#44c61ea607ae4be9c1402f41f44270cbfe334ff8" 2934 resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-1.3.1.tgz#44c61ea607ae4be9c1402f41f44270cbfe334ff8"
@@ -3361,6 +3453,13 @@ has-ansi@^2.0.0:
3361 dependencies: 3453 dependencies:
3362 ansi-regex "^2.0.0" 3454 ansi-regex "^2.0.0"
3363 3455
3456has-binary2@~1.0.2:
3457 version "1.0.3"
3458 resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d"
3459 integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==
3460 dependencies:
3461 isarray "2.0.1"
3462
3364has-binary@0.1.7: 3463has-binary@0.1.7:
3365 version "0.1.7" 3464 version "0.1.7"
3366 resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.7.tgz#68e61eb16210c9545a0a5cce06a873912fe1e68c" 3465 resolved "https://registry.yarnpkg.com/has-binary/-/has-binary-0.1.7.tgz#68e61eb16210c9545a0a5cce06a873912fe1e68c"
@@ -3420,9 +3519,9 @@ has-values@^1.0.0:
3420 kind-of "^4.0.0" 3519 kind-of "^4.0.0"
3421 3520
3422hash.js@^1.0.0: 3521hash.js@^1.0.0:
3423 version "1.1.5" 3522 version "1.1.7"
3424 resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" 3523 resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
3425 integrity sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA== 3524 integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
3426 dependencies: 3525 dependencies:
3427 inherits "^2.0.3" 3526 inherits "^2.0.3"
3428 minimalistic-assert "^1.0.1" 3527 minimalistic-assert "^1.0.1"
@@ -3557,9 +3656,9 @@ humanize-ms@^1.2.1:
3557 ms "^2.0.0" 3656 ms "^2.0.0"
3558 3657
3559husky@^1.0.0-rc.4: 3658husky@^1.0.0-rc.4:
3560 version "1.1.4" 3659 version "1.2.0"
3561 resolved "https://registry.yarnpkg.com/husky/-/husky-1.1.4.tgz#92f61383527d2571e9586234e5864356bfaceaa9" 3660 resolved "https://registry.yarnpkg.com/husky/-/husky-1.2.0.tgz#d631dda1e4a9ee8ba69a10b0c51a0e2c66e711e5"
3562 integrity sha512-cZjGpS7qsaBSo3fOMUuR7erQloX3l5XzL1v/RkIqU6zrQImDdU70z5Re9fGDp7+kbYlM2EtS4aYMlahBeiCUGw== 3661 integrity sha512-/ib3+iycykXC0tYIxsyqierikVa9DA2DrT32UEirqNEFVqOj1bFMTgP3jAz8HM7FgC/C8pc/BTUa9MV2GEkZaA==
3563 dependencies: 3662 dependencies:
3564 cosmiconfig "^5.0.6" 3663 cosmiconfig "^5.0.6"
3565 execa "^1.0.0" 3664 execa "^1.0.0"
@@ -4103,6 +4202,11 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
4103 resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 4202 resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
4104 integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 4203 integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
4105 4204
4205isarray@2.0.1:
4206 version "2.0.1"
4207 resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e"
4208 integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=
4209
4106isexe@^2.0.0: 4210isexe@^2.0.0:
4107 version "2.0.0" 4211 version "2.0.0"
4108 resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 4212 resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -4483,13 +4587,14 @@ libxmljs@0.19.5:
4483 node-pre-gyp "~0.11.0" 4587 node-pre-gyp "~0.11.0"
4484 4588
4485lint-staged@^8.0.4: 4589lint-staged@^8.0.4:
4486 version "8.0.4" 4590 version "8.1.0"
4487 resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.0.4.tgz#d3c909fcf7897152cdce2d6e42500cd9b5b41a0d" 4591 resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.0.tgz#dbc3ae2565366d8f20efb9f9799d076da64863f2"
4488 integrity sha512-Rs0VxXoyFqHMrPQgKAMy+O907+m5Po71UVPhBi7BUBwU7ZZ2aoc+mZmpOX3DVPCoTcy6+hqJa9yIZfacNpJHdg== 4592 integrity sha512-yfSkyJy7EuVsaoxtUSEhrD81spdJOe/gMTGea3XaV7HyoRhTb9Gdlp6/JppRZERvKSEYXP9bjcmq6CA5oL2lYQ==
4489 dependencies: 4593 dependencies:
4594 "@iamstarkov/listr-update-renderer" "0.4.1"
4490 chalk "^2.3.1" 4595 chalk "^2.3.1"
4491 commander "^2.14.1" 4596 commander "^2.14.1"
4492 cosmiconfig "^5.0.2" 4597 cosmiconfig "5.0.6"
4493 debug "^3.1.0" 4598 debug "^3.1.0"
4494 dedent "^0.7.0" 4599 dedent "^0.7.0"
4495 del "^3.0.0" 4600 del "^3.0.0"
@@ -4500,7 +4605,6 @@ lint-staged@^8.0.4:
4500 is-windows "^1.0.2" 4605 is-windows "^1.0.2"
4501 jest-validate "^23.5.0" 4606 jest-validate "^23.5.0"
4502 listr "^0.14.2" 4607 listr "^0.14.2"
4503 listr-update-renderer "https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update"
4504 lodash "^4.17.5" 4608 lodash "^4.17.5"
4505 log-symbols "^2.2.0" 4609 log-symbols "^2.2.0"
4506 micromatch "^3.1.8" 4610 micromatch "^3.1.8"
@@ -4518,9 +4622,10 @@ listr-silent-renderer@^1.1.1:
4518 resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" 4622 resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
4519 integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= 4623 integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=
4520 4624
4521listr-update-renderer@^0.4.0, "listr-update-renderer@https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update": 4625listr-update-renderer@^0.5.0:
4522 version "0.4.0" 4626 version "0.5.0"
4523 resolved "https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update#06073fa93166277607a7814f4e1f83960081414c" 4627 resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2"
4628 integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==
4524 dependencies: 4629 dependencies:
4525 chalk "^1.1.3" 4630 chalk "^1.1.3"
4526 cli-truncate "^0.2.1" 4631 cli-truncate "^0.2.1"
@@ -4531,30 +4636,30 @@ listr-update-renderer@^0.4.0, "listr-update-renderer@https://github.com/okonet/l
4531 log-update "^2.3.0" 4636 log-update "^2.3.0"
4532 strip-ansi "^3.0.1" 4637 strip-ansi "^3.0.1"
4533 4638
4534listr-verbose-renderer@^0.4.0: 4639listr-verbose-renderer@^0.5.0:
4535 version "0.4.1" 4640 version "0.5.0"
4536 resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" 4641 resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db"
4537 integrity sha1-ggb0z21S3cWCfl/RSYng6WWTOjU= 4642 integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==
4538 dependencies: 4643 dependencies:
4539 chalk "^1.1.3" 4644 chalk "^2.4.1"
4540 cli-cursor "^1.0.2" 4645 cli-cursor "^2.1.0"
4541 date-fns "^1.27.2" 4646 date-fns "^1.27.2"
4542 figures "^1.7.0" 4647 figures "^2.0.0"
4543 4648
4544listr@^0.14.2: 4649listr@^0.14.2:
4545 version "0.14.2" 4650 version "0.14.3"
4546 resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.2.tgz#cbe44b021100a15376addfc2d79349ee430bfe14" 4651 resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586"
4547 integrity sha512-vmaNJ1KlGuGWShHI35X/F8r9xxS0VTHh9GejVXwSN20fG5xpq3Jh4bJbnumoT6q5EDM/8/YP1z3YMtQbFmhuXw== 4652 integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==
4548 dependencies: 4653 dependencies:
4549 "@samverschueren/stream-to-observable" "^0.3.0" 4654 "@samverschueren/stream-to-observable" "^0.3.0"
4550 is-observable "^1.1.0" 4655 is-observable "^1.1.0"
4551 is-promise "^2.1.0" 4656 is-promise "^2.1.0"
4552 is-stream "^1.1.0" 4657 is-stream "^1.1.0"
4553 listr-silent-renderer "^1.1.1" 4658 listr-silent-renderer "^1.1.1"
4554 listr-update-renderer "^0.4.0" 4659 listr-update-renderer "^0.5.0"
4555 listr-verbose-renderer "^0.4.0" 4660 listr-verbose-renderer "^0.5.0"
4556 p-map "^1.1.1" 4661 p-map "^2.0.0"
4557 rxjs "^6.1.0" 4662 rxjs "^6.3.3"
4558 4663
4559load-ip-set@^2.1.0: 4664load-ip-set@^2.1.0:
4560 version "2.1.0" 4665 version "2.1.0"
@@ -4791,9 +4896,9 @@ lowercase-keys@^1.0.0:
4791 integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== 4896 integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
4792 4897
4793lru-cache@4.1.x, lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2, lru-cache@^4.1.3: 4898lru-cache@4.1.x, lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2, lru-cache@^4.1.3:
4794 version "4.1.3" 4899 version "4.1.5"
4795 resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" 4900 resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
4796 integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== 4901 integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
4797 dependencies: 4902 dependencies:
4798 pseudomap "^1.0.2" 4903 pseudomap "^1.0.2"
4799 yallist "^2.1.2" 4904 yallist "^2.1.2"
@@ -5054,9 +5159,9 @@ mime@^1.3.4, mime@^1.4.1:
5054 integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 5159 integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
5055 5160
5056mime@^2.2.0: 5161mime@^2.2.0:
5057 version "2.3.1" 5162 version "2.4.0"
5058 resolved "https://registry.yarnpkg.com/mime/-/mime-2.3.1.tgz#b1621c54d63b97c47d3cfe7f7215f7d64517c369" 5163 resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6"
5059 integrity sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg== 5164 integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==
5060 5165
5061mimelib@^0.3.0: 5166mimelib@^0.3.0:
5062 version "0.3.1" 5167 version "0.3.1"
@@ -5386,9 +5491,9 @@ node-abi@^2.2.0:
5386 semver "^5.4.1" 5491 semver "^5.4.1"
5387 5492
5388node-addon-api@^1.6.0: 5493node-addon-api@^1.6.0:
5389 version "1.6.1" 5494 version "1.6.2"
5390 resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.6.1.tgz#a9881c8dbc6400bac6ddedcb96eccf8051678536" 5495 resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.6.2.tgz#d8aad9781a5cfc4132cc2fecdbdd982534265217"
5391 integrity sha512-GcLOYrG5/enbqH4SMsqXt6GQUQGGnDnE3FLDZzXYkCgQHuZV5UDFR+EboeY8kpG0avroyOjpFQ2qLEBosFcRIA== 5496 integrity sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA==
5392 5497
5393node-fetch-npm@^2.0.2: 5498node-fetch-npm@^2.0.2:
5394 version "2.0.2" 5499 version "2.0.2"
@@ -5484,20 +5589,20 @@ nodemailer-shared@^1.1.0:
5484 nodemailer-fetch "1.6.0" 5589 nodemailer-fetch "1.6.0"
5485 5590
5486nodemailer@^4.4.2: 5591nodemailer@^4.4.2:
5487 version "4.6.8" 5592 version "4.7.0"
5488 resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-4.6.8.tgz#f82fb407828bf2e76d92acc34b823d83e774f89c" 5593 resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-4.7.0.tgz#4420e06abfffd77d0618f184ea49047db84f4ad8"
5489 integrity sha512-A3s7EM/426OBIZbLHXq2KkgvmKbn2Xga4m4G+ZUA4IaZvG8PcZXrFh+2E4VaS2o+emhuUVRnzKN2YmpkXQ9qwA== 5594 integrity sha512-IludxDypFpYw4xpzKdMAozBSkzKHmNBvGanUREjJItgJ2NYcK/s8+PggVhj7c2yGFQykKsnnmv1+Aqo0ZfjHmw==
5490 5595
5491nodemon@^1.18.6: 5596nodemon@^1.18.6:
5492 version "1.18.6" 5597 version "1.18.7"
5493 resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.6.tgz#89b1136634d6c0afc7de24cc932a760e999e2c76" 5598 resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.18.7.tgz#716b66bf3e89ac4fcfb38a9e61887a03fc82efbb"
5494 integrity sha512-4pHQNYEZun+IkIC2jCaXEhkZnfA7rQe73i8RkdRyDJls/K+WxR7IpI5uNUsAvQ0zWvYcCDNGD+XVtw2ZG86/uQ== 5599 integrity sha512-xuC1V0F5EcEyKQ1VhHYD13owznQbUw29JKvZ8bVH7TmuvVNHvvbp9pLgE4PjTMRJVe0pJ8fGRvwR2nMiosIsPQ==
5495 dependencies: 5600 dependencies:
5496 chokidar "^2.0.4" 5601 chokidar "^2.0.4"
5497 debug "^3.1.0" 5602 debug "^3.1.0"
5498 ignore-by-default "^1.0.1" 5603 ignore-by-default "^1.0.1"
5499 minimatch "^3.0.4" 5604 minimatch "^3.0.4"
5500 pstree.remy "^1.1.0" 5605 pstree.remy "^1.1.2"
5501 semver "^5.5.0" 5606 semver "^5.5.0"
5502 supports-color "^5.2.0" 5607 supports-color "^5.2.0"
5503 touch "^3.1.0" 5608 touch "^3.1.0"
@@ -6051,6 +6156,11 @@ p-map@^1.1.1:
6051 resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" 6156 resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
6052 integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== 6157 integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==
6053 6158
6159p-map@^2.0.0:
6160 version "2.0.0"
6161 resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.0.0.tgz#be18c5a5adeb8e156460651421aceca56c213a50"
6162 integrity sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w==
6163
6054p-try@^1.0.0: 6164p-try@^1.0.0:
6055 version "1.0.0" 6165 version "1.0.0"
6056 resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" 6166 resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
@@ -6263,14 +6373,7 @@ pg-connection-string@0.1.3:
6263 resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7" 6373 resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7"
6264 integrity sha1-2hhHsglA5C7hSSvq9l1J2RskXfc= 6374 integrity sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=
6265 6375
6266pg-hstore@^2.3.2: 6376pg-pool@^2.0.4:
6267 version "2.3.2"
6268 resolved "https://registry.yarnpkg.com/pg-hstore/-/pg-hstore-2.3.2.tgz#f7ef053e7b9b892ae986af2f7cbe86432dfcf24f"
6269 integrity sha1-9+8FPnubiSrphq8vfL6GQy388k8=
6270 dependencies:
6271 underscore "^1.7.0"
6272
6273pg-pool@~2.0.3:
6274 version "2.0.4" 6377 version "2.0.4"
6275 resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.4.tgz#05ad0f2d9437d89c94ccc4f4d0a44ac65ade865b" 6378 resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.4.tgz#05ad0f2d9437d89c94ccc4f4d0a44ac65ade865b"
6276 integrity sha512-Mi2AsmlFkVMpI28NreaDkz5DkfxLOG16C/HNwi091LDlOiDiQACtAroLxSd1vIS2imBqxdjjO9cQZg2CwsOPbw== 6379 integrity sha512-Mi2AsmlFkVMpI28NreaDkz5DkfxLOG16C/HNwi091LDlOiDiQACtAroLxSd1vIS2imBqxdjjO9cQZg2CwsOPbw==
@@ -6286,14 +6389,14 @@ pg-types@~1.12.1:
6286 postgres-interval "^1.1.0" 6389 postgres-interval "^1.1.0"
6287 6390
6288pg@^7.4.1: 6391pg@^7.4.1:
6289 version "7.6.1" 6392 version "7.7.1"
6290 resolved "https://registry.yarnpkg.com/pg/-/pg-7.6.1.tgz#42c68aed37bf38b813616e3d21f4338f350c1b79" 6393 resolved "https://registry.yarnpkg.com/pg/-/pg-7.7.1.tgz#546b192ff484322b69689391f885de3ba91a30d4"
6291 integrity sha512-rAItIkYrRaNGinZN/Hs8F9R5mQjQSPlnzxPF+eCimSl92qnuNGR42gkpOQKP1bnvTwkSjRTBL+VNC5EcFhtCuQ== 6394 integrity sha512-p3I0mXOmUvCoVlCMFW6iYSrnguPol6q8He15NGgSIdM3sPGjFc+8JGCeKclw8ZR4ETd+Jxy2KNiaPUcocHZeMw==
6292 dependencies: 6395 dependencies:
6293 buffer-writer "2.0.0" 6396 buffer-writer "2.0.0"
6294 packet-reader "0.3.1" 6397 packet-reader "0.3.1"
6295 pg-connection-string "0.1.3" 6398 pg-connection-string "0.1.3"
6296 pg-pool "~2.0.3" 6399 pg-pool "^2.0.4"
6297 pg-types "~1.12.1" 6400 pg-types "~1.12.1"
6298 pgpass "1.x" 6401 pgpass "1.x"
6299 semver "4.3.2" 6402 semver "4.3.2"
@@ -6396,12 +6499,12 @@ postgres-interval@^1.1.0:
6396 xtend "^4.0.0" 6499 xtend "^4.0.0"
6397 6500
6398prebuild-install@^5.2.0: 6501prebuild-install@^5.2.0:
6399 version "5.2.1" 6502 version "5.2.2"
6400 resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.2.1.tgz#87ba8cf17c65360a75eefeb3519e87973bf9791d" 6503 resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.2.2.tgz#237888f21bfda441d0ee5f5612484390bccd4046"
6401 integrity sha512-9DAccsInWHB48TBQi2eJkLPE049JuAI6FjIH0oIrij4bpDVEbX6JvlWRAcAAlUqBHhjgq0jNqA3m3bBXWm9v6w== 6504 integrity sha512-4e8VJnP3zJdZv/uP0eNWmr2r9urp4NECw7Mt1OSAi3rcLrbBRxGiAkfUFtre2MhQ5wfREAjRV+K1gubvs/GPsA==
6402 dependencies: 6505 dependencies:
6403 detect-libc "^1.0.3" 6506 detect-libc "^1.0.3"
6404 expand-template "^1.0.2" 6507 expand-template "^2.0.3"
6405 github-from-package "0.0.0" 6508 github-from-package "0.0.0"
6406 minimist "^1.2.0" 6509 minimist "^1.2.0"
6407 mkdirp "^0.5.1" 6510 mkdirp "^0.5.1"
@@ -6529,7 +6632,7 @@ psl@^1.1.24:
6529 resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" 6632 resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67"
6530 integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== 6633 integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==
6531 6634
6532pstree.remy@^1.1.0: 6635pstree.remy@^1.1.2:
6533 version "1.1.2" 6636 version "1.1.2"
6534 resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.2.tgz#4448bbeb4b2af1fed242afc8dc7416a6f504951a" 6637 resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.2.tgz#4448bbeb4b2af1fed242afc8dc7416a6f504951a"
6535 integrity sha512-vL6NLxNHzkNTjGJUpMm5PLC+94/0tTlC1vkP9bdU0pOHih+EujMjgMTwfZopZvHWRFbqJ5Y73OMoau50PewDDA== 6638 integrity sha512-vL6NLxNHzkNTjGJUpMm5PLC+94/0tTlC1vkP9bdU0pOHih+EujMjgMTwfZopZvHWRFbqJ5Y73OMoau50PewDDA==
@@ -6587,11 +6690,16 @@ qs@4.0.0:
6587 resolved "https://registry.yarnpkg.com/qs/-/qs-4.0.0.tgz#c31d9b74ec27df75e543a86c78728ed8d4623607" 6690 resolved "https://registry.yarnpkg.com/qs/-/qs-4.0.0.tgz#c31d9b74ec27df75e543a86c78728ed8d4623607"
6588 integrity sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc= 6691 integrity sha1-wx2bdOwn33XlQ6hseHKO2NRiNgc=
6589 6692
6590qs@6.5.2, qs@^6.5.1, qs@~6.5.2: 6693qs@6.5.2, qs@~6.5.2:
6591 version "6.5.2" 6694 version "6.5.2"
6592 resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" 6695 resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
6593 integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== 6696 integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
6594 6697
6698qs@^6.5.1:
6699 version "6.6.0"
6700 resolved "https://registry.yarnpkg.com/qs/-/qs-6.6.0.tgz#a99c0f69a8d26bf7ef012f871cdabb0aee4424c2"
6701 integrity sha512-KIJqT9jQJDQx5h5uAVPimw6yVg2SekOKu959OCtktD3FjzbpvaPr8i4zzg07DOMz+igA4W/aNM7OV8H37pFYfA==
6702
6595query-string@^6.1.0: 6703query-string@^6.1.0:
6596 version "6.2.0" 6704 version "6.2.0"
6597 resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.2.0.tgz#468edeb542b7e0538f9f9b1aeb26f034f19c86e1" 6705 resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.2.0.tgz#468edeb542b7e0538f9f9b1aeb26f034f19c86e1"
@@ -6845,7 +6953,7 @@ referrer-policy@1.1.0:
6845 resolved "https://registry.yarnpkg.com/referrer-policy/-/referrer-policy-1.1.0.tgz#35774eb735bf50fb6c078e83334b472350207d79" 6953 resolved "https://registry.yarnpkg.com/referrer-policy/-/referrer-policy-1.1.0.tgz#35774eb735bf50fb6c078e83334b472350207d79"
6846 integrity sha1-NXdOtzW/UPtsB46DM0tHI1AgfXk= 6954 integrity sha1-NXdOtzW/UPtsB46DM0tHI1AgfXk=
6847 6955
6848reflect-metadata@^0.1.10: 6956reflect-metadata@^0.1.12:
6849 version "0.1.12" 6957 version "0.1.12"
6850 resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2" 6958 resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2"
6851 integrity sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A== 6959 integrity sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A==
@@ -7077,14 +7185,7 @@ rx-lite@^3.1.2:
7077 resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" 7185 resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
7078 integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI= 7186 integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=
7079 7187
7080rxjs@6.2.2: 7188rxjs@^6.3.3:
7081 version "6.2.2"
7082 resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.2.2.tgz#eb75fa3c186ff5289907d06483a77884586e1cf9"
7083 integrity sha512-0MI8+mkKAXZUF9vMrEoPnaoHkfzBPP4IGwUYRJhIRJF6/w3uByO1e91bEHn8zd43RdkTMKiooYKmwz7RH6zfOQ==
7084 dependencies:
7085 tslib "^1.9.0"
7086
7087rxjs@^6.1.0:
7088 version "6.3.3" 7189 version "6.3.3"
7089 resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" 7190 resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"
7090 integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== 7191 integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==
@@ -7425,6 +7526,15 @@ simple-websocket@^7.0.1:
7425 readable-stream "^2.0.5" 7526 readable-stream "^2.0.5"
7426 ws "^6.0.0" 7527 ws "^6.0.0"
7427 7528
7529sitemap@^2.1.0:
7530 version "2.1.0"
7531 resolved "https://registry.yarnpkg.com/sitemap/-/sitemap-2.1.0.tgz#1633cb88c196d755ad94becfb1c1bcacc6d3425a"
7532 integrity sha512-AkfA7RDVCITQo+j5CpXsMJlZ/8ENO2NtgMHYIh+YMvex2Hao/oe3MQgNa03p0aWY6srCfUA1Q02OgiWCAiuccA==
7533 dependencies:
7534 lodash "^4.17.10"
7535 url-join "^4.0.0"
7536 xmlbuilder "^10.0.0"
7537
7428slash@^1.0.0: 7538slash@^1.0.0:
7429 version "1.0.0" 7539 version "1.0.0"
7430 resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" 7540 resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
@@ -7508,6 +7618,11 @@ socket.io-adapter@0.5.0:
7508 debug "2.3.3" 7618 debug "2.3.3"
7509 socket.io-parser "2.3.1" 7619 socket.io-parser "2.3.1"
7510 7620
7621socket.io-adapter@~1.1.0:
7622 version "1.1.1"
7623 resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz#2a805e8a14d6372124dd9159ad4502f8cb07f06b"
7624 integrity sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=
7625
7511socket.io-client@1.7.3: 7626socket.io-client@1.7.3:
7512 version "1.7.3" 7627 version "1.7.3"
7513 resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.3.tgz#b30e86aa10d5ef3546601c09cde4765e381da377" 7628 resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.3.tgz#b30e86aa10d5ef3546601c09cde4765e381da377"
@@ -7525,6 +7640,26 @@ socket.io-client@1.7.3:
7525 socket.io-parser "2.3.1" 7640 socket.io-parser "2.3.1"
7526 to-array "0.1.4" 7641 to-array "0.1.4"
7527 7642
7643socket.io-client@2.2.0:
7644 version "2.2.0"
7645 resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.2.0.tgz#84e73ee3c43d5020ccc1a258faeeb9aec2723af7"
7646 integrity sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==
7647 dependencies:
7648 backo2 "1.0.2"
7649 base64-arraybuffer "0.1.5"
7650 component-bind "1.0.0"
7651 component-emitter "1.2.1"
7652 debug "~3.1.0"
7653 engine.io-client "~3.3.1"
7654 has-binary2 "~1.0.2"
7655 has-cors "1.1.0"
7656 indexof "0.0.1"
7657 object-component "0.0.3"
7658 parseqs "0.0.5"
7659 parseuri "0.0.5"
7660 socket.io-parser "~3.3.0"
7661 to-array "0.1.4"
7662
7528socket.io-parser@2.3.1: 7663socket.io-parser@2.3.1:
7529 version "2.3.1" 7664 version "2.3.1"
7530 resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.3.1.tgz#dd532025103ce429697326befd64005fcfe5b4a0" 7665 resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.3.1.tgz#dd532025103ce429697326befd64005fcfe5b4a0"
@@ -7535,6 +7670,15 @@ socket.io-parser@2.3.1:
7535 isarray "0.0.1" 7670 isarray "0.0.1"
7536 json3 "3.3.2" 7671 json3 "3.3.2"
7537 7672
7673socket.io-parser@~3.3.0:
7674 version "3.3.0"
7675 resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f"
7676 integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==
7677 dependencies:
7678 component-emitter "1.2.1"
7679 debug "~3.1.0"
7680 isarray "2.0.1"
7681
7538socket.io@1.7.3: 7682socket.io@1.7.3:
7539 version "1.7.3" 7683 version "1.7.3"
7540 resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.3.tgz#b8af9caba00949e568e369f1327ea9be9ea2461b" 7684 resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.3.tgz#b8af9caba00949e568e369f1327ea9be9ea2461b"
@@ -7548,6 +7692,18 @@ socket.io@1.7.3:
7548 socket.io-client "1.7.3" 7692 socket.io-client "1.7.3"
7549 socket.io-parser "2.3.1" 7693 socket.io-parser "2.3.1"
7550 7694
7695socket.io@^2.2.0:
7696 version "2.2.0"
7697 resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.2.0.tgz#f0f633161ef6712c972b307598ecd08c9b1b4d5b"
7698 integrity sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==
7699 dependencies:
7700 debug "~4.1.0"
7701 engine.io "~3.3.1"
7702 has-binary2 "~1.0.2"
7703 socket.io-adapter "~1.1.0"
7704 socket.io-client "2.2.0"
7705 socket.io-parser "~3.3.0"
7706
7551socks-proxy-agent@^3.0.1: 7707socks-proxy-agent@^3.0.1:
7552 version "3.0.1" 7708 version "3.0.1"
7553 resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz#2eae7cf8e2a82d34565761539a7f9718c5617659" 7709 resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz#2eae7cf8e2a82d34565761539a7f9718c5617659"
@@ -7869,10 +8025,10 @@ string2compact@^1.1.1, string2compact@^1.2.5:
7869 addr-to-ip-port "^1.0.1" 8025 addr-to-ip-port "^1.0.1"
7870 ipaddr.js "^1.0.1" 8026 ipaddr.js "^1.0.1"
7871 8027
7872string_decoder@^1.1.1, string_decoder@~1.1.1: 8028string_decoder@^1.1.1:
7873 version "1.1.1" 8029 version "1.2.0"
7874 resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 8030 resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
7875 integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 8031 integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==
7876 dependencies: 8032 dependencies:
7877 safe-buffer "~5.1.0" 8033 safe-buffer "~5.1.0"
7878 8034
@@ -7881,6 +8037,13 @@ string_decoder@~0.10.x:
7881 resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 8037 resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
7882 integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= 8038 integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
7883 8039
8040string_decoder@~1.1.1:
8041 version "1.1.1"
8042 resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
8043 integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
8044 dependencies:
8045 safe-buffer "~5.1.0"
8046
7884stringify-object@^3.2.2: 8047stringify-object@^3.2.2:
7885 version "3.3.0" 8048 version "3.3.0"
7886 resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" 8049 resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629"
@@ -8342,9 +8505,9 @@ tsutils@^2.27.2:
8342 tslib "^1.8.1" 8505 tslib "^1.8.1"
8343 8506
8344tsutils@^3.0.0: 8507tsutils@^3.0.0:
8345 version "3.5.0" 8508 version "3.5.2"
8346 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.5.0.tgz#42602f7df241e753a2105cc3627a664abf11f745" 8509 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.5.2.tgz#6fd3c2d5a731e83bb21b070a173ec0faf3a8f6d3"
8347 integrity sha512-/FZ+pEJQixWruFejFxNPRSwg+iF6aw7PYZVRqUscJ7EnzV3zieI8byfZziUR7QjCuJFulq8SEe9JcGflO4ze4Q== 8510 integrity sha512-qIlklNuI/1Dzfm+G+kJV5gg3gimZIX5haYtIVQe7qGyKd7eu8T1t1DY6pz4Sc2CGXAj9s1izycctm9Zfl9sRuQ==
8348 dependencies: 8511 dependencies:
8349 tslib "^1.8.1" 8512 tslib "^1.8.1"
8350 8513
@@ -8411,9 +8574,9 @@ typedarray@^0.0.6:
8411 integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= 8574 integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
8412 8575
8413typescript@^3.1.6: 8576typescript@^3.1.6:
8414 version "3.1.6" 8577 version "3.2.1"
8415 resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68" 8578 resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.1.tgz#0b7a04b8cf3868188de914d9568bd030f0c56192"
8416 integrity sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA== 8579 integrity sha512-jw7P2z/h6aPT4AENXDGjcfHTu5CSqzsbZc6YlUIebTyBAq8XaKp78x7VcSh30xwSCcsu5irZkYZUSFP1MrAMbg==
8417 8580
8418uid-number@0.0.6: 8581uid-number@0.0.6:
8419 version "0.0.6" 8582 version "0.0.6"
@@ -8451,7 +8614,7 @@ underscore-keypath@~0.0.22:
8451 dependencies: 8614 dependencies:
8452 underscore "*" 8615 underscore "*"
8453 8616
8454underscore@*, underscore@^1.7.0: 8617underscore@*:
8455 version "1.9.1" 8618 version "1.9.1"
8456 resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" 8619 resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
8457 integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== 8620 integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==
@@ -8553,6 +8716,11 @@ urix@^0.1.0:
8553 resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" 8716 resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
8554 integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= 8717 integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
8555 8718
8719url-join@^4.0.0:
8720 version "4.0.0"
8721 resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a"
8722 integrity sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=
8723
8556url-parse-lax@^1.0.0: 8724url-parse-lax@^1.0.0:
8557 version "1.0.0" 8725 version "1.0.0"
8558 resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" 8726 resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
@@ -8720,9 +8888,9 @@ wcwidth@^1.0.0:
8720 defaults "^1.0.3" 8888 defaults "^1.0.3"
8721 8889
8722webfinger.js@^2.6.6: 8890webfinger.js@^2.6.6:
8723 version "2.6.6" 8891 version "2.7.0"
8724 resolved "https://registry.yarnpkg.com/webfinger.js/-/webfinger.js-2.6.6.tgz#52ebdc85da8c8fb6beb690e8e32594c99d2ff4ae" 8892 resolved "https://registry.yarnpkg.com/webfinger.js/-/webfinger.js-2.7.0.tgz#403354a14a65aeeba64c1408c18a387487cea106"
8725 integrity sha512-dQpuL01XtluQ9Ndgu62o3pEmIe/ssDoIE0CQsOyavGl04xyHal+Ge4gFerw5V0BFoLTQpD8ZZqaDzb43hG9atw== 8893 integrity sha512-l+UtsuV4zrBKyVAj9VCtwWgscTgadCsdGgL1OvbV102cvydWwJCGXlFIXauzWLzfheIDHfPNRWfgMuwyC6ZfIA==
8726 dependencies: 8894 dependencies:
8727 xhr2 "^0.1.4" 8895 xhr2 "^0.1.4"
8728 8896
@@ -8908,10 +9076,10 @@ ws@1.1.2:
8908 options ">=0.0.5" 9076 options ">=0.0.5"
8909 ultron "1.0.x" 9077 ultron "1.0.x"
8910 9078
8911ws@^6.0.0: 9079ws@^6.0.0, ws@~6.1.0:
8912 version "6.1.0" 9080 version "6.1.2"
8913 resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.0.tgz#119a9dbf92c54e190ec18d10e871d55c95cf9373" 9081 resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8"
8914 integrity sha512-H3dGVdGvW2H8bnYpIDc3u3LH8Wue3Qh+Zto6aXXFzvESkTVT6rAfKR6tR/+coaUvxs8yHtmNV0uioBF62ZGSTg== 9082 integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==
8915 dependencies: 9083 dependencies:
8916 async-limiter "~1.0.0" 9084 async-limiter "~1.0.0"
8917 9085
@@ -8936,16 +9104,16 @@ xhr2@^0.1.4:
8936 integrity sha1-f4dliEdxbbUCYyOBL4GMras4el8= 9104 integrity sha1-f4dliEdxbbUCYyOBL4GMras4el8=
8937 9105
8938xliff@^4.0.0: 9106xliff@^4.0.0:
8939 version "4.1.0" 9107 version "4.1.2"
8940 resolved "https://registry.yarnpkg.com/xliff/-/xliff-4.1.0.tgz#32ea268a6442c122e132e6abf874539b1fc9c6b3" 9108 resolved "https://registry.yarnpkg.com/xliff/-/xliff-4.1.2.tgz#eb6fae21346d82653febd44d478f5748ad79fbd2"
8941 integrity sha512-BlqCVTd16GLNx4TAll1Ebs1Gswh6g/Mx/9z6cXmbNTVqy7iqXAAwZjmhE2G1fX+++xoXy0IufPp+DOv8tJC/pA== 9109 integrity sha512-ru+ya+rz2cb+D3Or9sf5xrj0MCL+q+vZmWOJlqZehIWlG3hqeIXhbfLMDAW9A5BsnRfL+BdMBHaogaTUGHyMyA==
8942 dependencies: 9110 dependencies:
8943 xml-js "1.6.7" 9111 xml-js "1.6.8"
8944 9112
8945xml-js@1.6.7: 9113xml-js@1.6.8:
8946 version "1.6.7" 9114 version "1.6.8"
8947 resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.7.tgz#a99b40c18a16d3e06537b3ae026a27bd60ffe8ab" 9115 resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.8.tgz#e06419c54235f18f4c2cdda824cbd65a782330de"
8948 integrity sha512-1hn0xwwfMcWywnJxqiOXiv+pZaOJyf/YWcUeqJICF0BFb+IOkRFSkKyeA0V62WqTHXNdBxNuCFHhS/w2DtYpoA== 9116 integrity sha512-kUv/geyN80d+s1T68uBfjoz+PjNUjwwf5AWWRwKRqqQaGozpMVsFsKYnenPsxlbN/VL7f0ia8NfLLPCDwX+95Q==
8949 dependencies: 9117 dependencies:
8950 sax "^1.2.4" 9118 sax "^1.2.4"
8951 9119
@@ -8962,6 +9130,11 @@ xml@^1.0.1:
8962 resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" 9130 resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
8963 integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= 9131 integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=
8964 9132
9133xmlbuilder@^10.0.0:
9134 version "10.1.1"
9135 resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-10.1.1.tgz#8cae6688cc9b38d850b7c8d3c0a4161dcaf475b0"
9136 integrity sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==
9137
8965xmlbuilder@~9.0.1: 9138xmlbuilder@~9.0.1:
8966 version "9.0.7" 9139 version "9.0.7"
8967 resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" 9140 resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
@@ -8977,10 +9150,10 @@ xmlhttprequest-ssl@1.5.3:
8977 resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d" 9150 resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d"
8978 integrity sha1-GFqIjATspGw+QHDZn3tJ3jUomS0= 9151 integrity sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=
8979 9152
8980xregexp@4.0.0: 9153xmlhttprequest-ssl@~1.5.4:
8981 version "4.0.0" 9154 version "1.5.5"
8982 resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020" 9155 resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
8983 integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg== 9156 integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=
8984 9157
8985"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: 9158"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
8986 version "4.0.1" 9159 version "4.0.1"
@@ -9003,16 +9176,17 @@ yallist@^2.1.2:
9003 integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= 9176 integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
9004 9177
9005yallist@^3.0.0, yallist@^3.0.2: 9178yallist@^3.0.0, yallist@^3.0.2:
9006 version "3.0.2" 9179 version "3.0.3"
9007 resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" 9180 resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9"
9008 integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= 9181 integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==
9009 9182
9010yargs-parser@^10.1.0: 9183yargs-parser@^11.1.1:
9011 version "10.1.0" 9184 version "11.1.1"
9012 resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" 9185 resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"
9013 integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== 9186 integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==
9014 dependencies: 9187 dependencies:
9015 camelcase "^4.1.0" 9188 camelcase "^5.0.0"
9189 decamelize "^1.2.0"
9016 9190
9017yargs-parser@^8.0.0: 9191yargs-parser@^8.0.0:
9018 version "8.1.0" 9192 version "8.1.0"
@@ -9047,12 +9221,12 @@ yargs@^11.0.0:
9047 yargs-parser "^9.0.2" 9221 yargs-parser "^9.0.2"
9048 9222
9049yargs@^12.0.1, yargs@^12.0.2: 9223yargs@^12.0.1, yargs@^12.0.2:
9050 version "12.0.2" 9224 version "12.0.5"
9051 resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc" 9225 resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
9052 integrity sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ== 9226 integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
9053 dependencies: 9227 dependencies:
9054 cliui "^4.0.0" 9228 cliui "^4.0.0"
9055 decamelize "^2.0.0" 9229 decamelize "^1.2.0"
9056 find-up "^3.0.0" 9230 find-up "^3.0.0"
9057 get-caller-file "^1.0.1" 9231 get-caller-file "^1.0.1"
9058 os-locale "^3.0.0" 9232 os-locale "^3.0.0"
@@ -9062,7 +9236,7 @@ yargs@^12.0.1, yargs@^12.0.2:
9062 string-width "^2.0.0" 9236 string-width "^2.0.0"
9063 which-module "^2.0.0" 9237 which-module "^2.0.0"
9064 y18n "^3.2.1 || ^4.0.0" 9238 y18n "^3.2.1 || ^4.0.0"
9065 yargs-parser "^10.1.0" 9239 yargs-parser "^11.1.1"
9066 9240
9067yeast@0.1.2: 9241yeast@0.1.2:
9068 version "0.1.2" 9242 version "0.1.2"
@@ -9085,9 +9259,9 @@ youtube-dl@^1.12.2:
9085 streamify "^0.2.9" 9259 streamify "^0.2.9"
9086 9260
9087z-schema@^3.24.1: 9261z-schema@^3.24.1:
9088 version "3.24.1" 9262 version "3.24.2"
9089 resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-3.24.1.tgz#07a3643c8e061ec1af32e823c9f9e5e5e56e3c8d" 9263 resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-3.24.2.tgz#193560e718812d98fdc190c38871b634b92f2386"
9090 integrity sha512-2eR8eq/v1coNqyBc5HzswEcoLbw+S33RMnR326uiuOIr97ve5vwPNMDrKS1IRCB12bZ3a8BrfGxrRwuSXUyPvw== 9264 integrity sha512-Zb2YLJ9g72MexBXKPRzoypd4OZfVkFghdy10eVbcMNLl9YQsPXtyMpiK7a3sG7IIERg1lEDjEMrG9Km9DPbWLw==
9091 dependencies: 9265 dependencies:
9092 core-js "^2.5.7" 9266 core-js "^2.5.7"
9093 lodash.get "^4.0.0" 9267 lodash.get "^4.0.0"