@@ -93,7 +94,7 @@ const PageThree = ({ me }) => (
);
PageThree.propTypes = {
- me: ImmutablePropTypes.map.isRequired,
+ myAccount: ImmutablePropTypes.map.isRequired,
};
const PageFour = ({ domain, intl }) => (
@@ -161,7 +162,7 @@ PageSix.propTypes = {
};
const mapStateToProps = state => ({
- me: state.getIn(['accounts', state.getIn(['meta', 'me'])]),
+ myAccount: state.getIn(['accounts', me]),
admin: state.getIn(['accounts', state.getIn(['meta', 'admin'])]),
domain: state.getIn(['meta', 'domain']),
});
@@ -173,7 +174,7 @@ export default class OnboardingModal extends React.PureComponent {
static propTypes = {
onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
- me: ImmutablePropTypes.map.isRequired,
+ myAccount: ImmutablePropTypes.map.isRequired,
domain: PropTypes.string.isRequired,
admin: ImmutablePropTypes.map,
};
@@ -183,11 +184,11 @@ export default class OnboardingModal extends React.PureComponent {
};
componentWillMount() {
- const { me, admin, domain, intl } = this.props;
+ const { myAccount, admin, domain, intl } = this.props;
this.pages = [
-
,
-
,
-
,
+
,
+
,
+
,
,
,
];
diff --git a/app/javascript/mastodon/features/ui/containers/status_list_container.js b/app/javascript/mastodon/features/ui/containers/status_list_container.js
index ff29bfdd45..a0aec44032 100644
--- a/app/javascript/mastodon/features/ui/containers/status_list_container.js
+++ b/app/javascript/mastodon/features/ui/containers/status_list_container.js
@@ -4,13 +4,13 @@ import { scrollTopTimeline } from '../../../actions/timelines';
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
import { createSelector } from 'reselect';
import { debounce } from 'lodash';
+import { me } from '../../../initial_state';
const makeGetStatusIds = () => createSelector([
(state, { type }) => state.getIn(['settings', type], ImmutableMap()),
(state, { type }) => state.getIn(['timelines', type, 'items'], ImmutableList()),
(state) => state.get('statuses'),
- (state) => state.getIn(['meta', 'me']),
-], (columnSettings, statusIds, statuses, me) => {
+], (columnSettings, statusIds, statuses) => {
const rawRegex = columnSettings.getIn(['regex', 'body'], '').trim();
let regex = null;
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index 70e451373d..f28b370992 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -38,14 +38,20 @@ import {
PinnedStatuses,
} from './util/async-components';
import { HotKeys } from 'react-hotkeys';
+import { me } from '../../initial_state';
+import { defineMessages, injectIntl } from 'react-intl';
// Dummy import, to make sure that
ends up in the application bundle.
// Without this it ends up in ~8 very commonly used bundles.
import '../../components/status';
+const messages = defineMessages({
+ beforeUnload: { id: 'ui.beforeunload', defaultMessage: 'Your draft will be lost if you leave Mastodon.' },
+});
+
const mapStateToProps = state => ({
- me: state.getIn(['meta', 'me']),
isComposing: state.getIn(['compose', 'is_composing']),
+ hasComposingText: state.getIn(['compose', 'text']) !== '',
});
const keyMap = {
@@ -75,6 +81,7 @@ const keyMap = {
};
@connect(mapStateToProps)
+@injectIntl
@withRouter
export default class UI extends React.Component {
@@ -86,8 +93,9 @@ export default class UI extends React.Component {
dispatch: PropTypes.func.isRequired,
children: PropTypes.node,
isComposing: PropTypes.bool,
- me: PropTypes.string,
+ hasComposingText: PropTypes.bool,
location: PropTypes.object,
+ intl: PropTypes.object.isRequired,
};
state = {
@@ -95,6 +103,17 @@ export default class UI extends React.Component {
draggingOver: false,
};
+ handleBeforeUnload = (e) => {
+ const { intl, isComposing, hasComposingText } = this.props;
+
+ if (isComposing && hasComposingText) {
+ // Setting returnValue to any string causes confirmation dialog.
+ // Many browsers no longer display this text to users,
+ // but we set user-friendly message for other browsers, e.g. Edge.
+ e.returnValue = intl.formatMessage(messages.beforeUnload);
+ }
+ }
+
handleResize = debounce(() => {
// The cached heights are no longer accurate, invalidate
this.props.dispatch(clearHeight());
@@ -169,6 +188,7 @@ export default class UI extends React.Component {
}
componentWillMount () {
+ window.addEventListener('beforeunload', this.handleBeforeUnload, false);
window.addEventListener('resize', this.handleResize, { passive: true });
document.addEventListener('dragenter', this.handleDragEnter, false);
document.addEventListener('dragover', this.handleDragOver, false);
@@ -210,6 +230,7 @@ export default class UI extends React.Component {
}
componentWillUnmount () {
+ window.removeEventListener('beforeunload', this.handleBeforeUnload);
window.removeEventListener('resize', this.handleResize);
document.removeEventListener('dragenter', this.handleDragEnter);
document.removeEventListener('dragover', this.handleDragOver);
@@ -305,7 +326,7 @@ export default class UI extends React.Component {
}
handleHotkeyGoToProfile = () => {
- this.context.router.history.push(`/accounts/${this.props.me}`);
+ this.context.router.history.push(`/accounts/${me}`);
}
handleHotkeyGoToBlocked = () => {
diff --git a/app/javascript/mastodon/features/ui/util/optional_motion.js b/app/javascript/mastodon/features/ui/util/optional_motion.js
index af63687384..df3a8b54af 100644
--- a/app/javascript/mastodon/features/ui/util/optional_motion.js
+++ b/app/javascript/mastodon/features/ui/util/optional_motion.js
@@ -1,56 +1,5 @@
-// Like react-motion's Motion, but checks to see if the user prefers
-// reduced motion and uses a cross-fade in those cases.
-
-import React from 'react';
+import { reduceMotion } from '../../../initial_state';
+import ReducedMotion from './reduced_motion';
import Motion from 'react-motion/lib/Motion';
-import PropTypes from 'prop-types';
-const stylesToKeep = ['opacity', 'backgroundOpacity'];
-
-let reduceMotion;
-
-const extractValue = (value) => {
- // This is either an object with a "val" property or it's a number
- return (typeof value === 'object' && value && 'val' in value) ? value.val : value;
-};
-
-class OptionalMotion extends React.Component {
-
- static propTypes = {
- defaultStyle: PropTypes.object,
- style: PropTypes.object,
- children: PropTypes.func,
- }
-
- render() {
-
- const { style, defaultStyle, children } = this.props;
-
- if (typeof reduceMotion !== 'boolean') {
- // This never changes without a page reload, so we can just grab it
- // once from the body classes as opposed to using Redux's connect(),
- // which would unnecessarily update every state change
- reduceMotion = document.body.classList.contains('reduce-motion');
- }
- if (reduceMotion) {
- Object.keys(style).forEach(key => {
- if (stylesToKeep.includes(key)) {
- return;
- }
- // If it's setting an x or height or scale or some other value, we need
- // to preserve the end-state value without actually animating it
- style[key] = defaultStyle[key] = extractValue(style[key]);
- });
- }
-
- return (
-
- {children}
-
- );
- }
-
-}
-
-
-export default OptionalMotion;
+export default reduceMotion ? ReducedMotion : Motion;
diff --git a/app/javascript/mastodon/features/ui/util/react_router_helpers.js b/app/javascript/mastodon/features/ui/util/react_router_helpers.js
index 86b30d4887..43007ddc3d 100644
--- a/app/javascript/mastodon/features/ui/util/react_router_helpers.js
+++ b/app/javascript/mastodon/features/ui/util/react_router_helpers.js
@@ -7,11 +7,19 @@ import BundleColumnError from '../components/bundle_column_error';
import BundleContainer from '../containers/bundle_container';
// Small wrapper to pass multiColumn to the route components
-export const WrappedSwitch = ({ multiColumn, children }) => (
-
- {React.Children.map(children, child => React.cloneElement(child, { multiColumn }))}
-
-);
+export class WrappedSwitch extends React.PureComponent {
+
+ render () {
+ const { multiColumn, children } = this.props;
+
+ return (
+
+ {React.Children.map(children, child => React.cloneElement(child, { multiColumn }))}
+
+ );
+ }
+
+}
WrappedSwitch.propTypes = {
multiColumn: PropTypes.bool,
diff --git a/app/javascript/mastodon/features/ui/util/reduced_motion.js b/app/javascript/mastodon/features/ui/util/reduced_motion.js
new file mode 100644
index 0000000000..95519042b4
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/util/reduced_motion.js
@@ -0,0 +1,44 @@
+// Like react-motion's Motion, but reduces all animations to cross-fades
+// for the benefit of users with motion sickness.
+import React from 'react';
+import Motion from 'react-motion/lib/Motion';
+import PropTypes from 'prop-types';
+
+const stylesToKeep = ['opacity', 'backgroundOpacity'];
+
+const extractValue = (value) => {
+ // This is either an object with a "val" property or it's a number
+ return (typeof value === 'object' && value && 'val' in value) ? value.val : value;
+};
+
+class ReducedMotion extends React.Component {
+
+ static propTypes = {
+ defaultStyle: PropTypes.object,
+ style: PropTypes.object,
+ children: PropTypes.func,
+ }
+
+ render() {
+
+ const { style, defaultStyle, children } = this.props;
+
+ Object.keys(style).forEach(key => {
+ if (stylesToKeep.includes(key)) {
+ return;
+ }
+ // If it's setting an x or height or scale or some other value, we need
+ // to preserve the end-state value without actually animating it
+ style[key] = defaultStyle[key] = extractValue(style[key]);
+ });
+
+ return (
+
+ {children}
+
+ );
+ }
+
+}
+
+export default ReducedMotion;
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
new file mode 100644
index 0000000000..3fc45077d4
--- /dev/null
+++ b/app/javascript/mastodon/initial_state.js
@@ -0,0 +1,13 @@
+const element = document.getElementById('initial-state');
+const initialState = element && JSON.parse(element.textContent);
+
+const getMeta = (prop) => initialState && initialState.meta && initialState.meta[prop];
+
+export const reduceMotion = getMeta('reduce_motion');
+export const autoPlayGif = getMeta('auto_play_gif');
+export const unfollowModal = getMeta('unfollow_modal');
+export const boostModal = getMeta('boost_modal');
+export const deleteModal = getMeta('delete_modal');
+export const me = getMeta('me');
+
+export default initialState;
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 22639f6f99..3f67a8fff1 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -1,221 +1,221 @@
{
"account.block": "Bloki @{name}",
- "account.block_domain": "Hide everything from {domain}",
- "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
+ "account.block_domain": "Kaŝi ĉion el {domain}",
+ "account.disclaimer_full": "La ĉi-subaj informoj povas ne plene reflekti la profilon de la uzanto.",
"account.edit_profile": "Redakti la profilon",
"account.follow": "Sekvi",
"account.followers": "Sekvantoj",
"account.follows": "Sekvatoj",
"account.follows_you": "Sekvas vin",
- "account.media": "Media",
+ "account.media": "Sonbildaĵoj",
"account.mention": "Mencii @{name}",
- "account.mute": "Mute @{name}",
+ "account.mute": "Silentigi @{name}",
"account.posts": "Mesaĝoj",
- "account.report": "Report @{name}",
+ "account.report": "Signali @{name}",
"account.requested": "Atendas aprobon",
- "account.share": "Share @{name}'s profile",
+ "account.share": "Diskonigi la profilon de @{name}",
"account.unblock": "Malbloki @{name}",
- "account.unblock_domain": "Unhide {domain}",
- "account.unfollow": "Malsekvi",
- "account.unmute": "Unmute @{name}",
- "account.view_full_profile": "View full profile",
- "boost_modal.combo": "You can press {combo} to skip this next time",
- "bundle_column_error.body": "Something went wrong while loading this component.",
- "bundle_column_error.retry": "Try again",
- "bundle_column_error.title": "Network error",
- "bundle_modal_error.close": "Close",
- "bundle_modal_error.message": "Something went wrong while loading this component.",
- "bundle_modal_error.retry": "Try again",
- "column.blocks": "Blocked users",
+ "account.unblock_domain": "Malkaŝi {domain}",
+ "account.unfollow": "Ne plus sekvi",
+ "account.unmute": "Malsilentigi @{name}",
+ "account.view_full_profile": "Vidi plenan profilon",
+ "boost_modal.combo": "La proksiman fojon, premu {combo} por pasigi",
+ "bundle_column_error.body": "Io malfunkciis ŝargante tiun ĉi komponanton.",
+ "bundle_column_error.retry": "Bonvolu reprovi",
+ "bundle_column_error.title": "Reta eraro",
+ "bundle_modal_error.close": "Fermi",
+ "bundle_modal_error.message": "Io malfunkciis ŝargante tiun ĉi komponanton.",
+ "bundle_modal_error.retry": "Bonvolu reprovi",
+ "column.blocks": "Blokitaj uzantoj",
"column.community": "Loka tempolinio",
- "column.favourites": "Favourites",
- "column.follow_requests": "Follow requests",
+ "column.favourites": "Favoritoj",
+ "column.follow_requests": "Abonpetoj",
"column.home": "Hejmo",
- "column.mutes": "Muted users",
+ "column.mutes": "Silentigitaj uzantoj",
"column.notifications": "Sciigoj",
- "column.pins": "Pinned toot",
+ "column.pins": "Alpinglitaj pepoj",
"column.public": "Fratara tempolinio",
"column_back_button.label": "Reveni",
- "column_header.hide_settings": "Hide settings",
- "column_header.moveLeft_settings": "Move column to the left",
- "column_header.moveRight_settings": "Move column to the right",
- "column_header.pin": "Pin",
- "column_header.show_settings": "Show settings",
- "column_header.unpin": "Unpin",
- "column_subheading.navigation": "Navigation",
- "column_subheading.settings": "Settings",
- "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
- "compose_form.lock_disclaimer.lock": "locked",
+ "column_header.hide_settings": "Kaŝi agordojn",
+ "column_header.moveLeft_settings": "Movi kolumnon maldekstren",
+ "column_header.moveRight_settings": "Movi kolumnon dekstren",
+ "column_header.pin": "Alpingli",
+ "column_header.show_settings": "Malkaŝi agordojn",
+ "column_header.unpin": "Depingli",
+ "column_subheading.navigation": "Navigado",
+ "column_subheading.settings": "Agordoj",
+ "compose_form.lock_disclaimer": "Via konta ne estas ŝlosita. Iu ajn povas sekvi vin por vidi viajn privatajn pepojn.",
+ "compose_form.lock_disclaimer.lock": "ŝlosita",
"compose_form.placeholder": "Pri kio vi pensas?",
"compose_form.publish": "Hup",
"compose_form.publish_loud": "{publish}!",
"compose_form.sensitive": "Marki ke la enhavo estas tikla",
"compose_form.spoiler": "Kaŝi la tekston malantaŭ averto",
- "compose_form.spoiler_placeholder": "Content warning",
- "confirmation_modal.cancel": "Cancel",
- "confirmations.block.confirm": "Block",
- "confirmations.block.message": "Are you sure you want to block {name}?",
- "confirmations.delete.confirm": "Delete",
- "confirmations.delete.message": "Are you sure you want to delete this status?",
- "confirmations.domain_block.confirm": "Hide entire domain",
- "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
- "confirmations.mute.confirm": "Mute",
- "confirmations.mute.message": "Are you sure you want to mute {name}?",
- "confirmations.unfollow.confirm": "Unfollow",
- "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
- "embed.instructions": "Embed this status on your website by copying the code below.",
- "embed.preview": "Here is what it will look like:",
- "emoji_button.activity": "Activity",
- "emoji_button.custom": "Custom",
- "emoji_button.flags": "Flags",
- "emoji_button.food": "Food & Drink",
- "emoji_button.label": "Insert emoji",
- "emoji_button.nature": "Nature",
- "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
- "emoji_button.objects": "Objects",
- "emoji_button.people": "People",
- "emoji_button.recent": "Frequently used",
- "emoji_button.search": "Search...",
- "emoji_button.search_results": "Search results",
- "emoji_button.symbols": "Symbols",
- "emoji_button.travel": "Travel & Places",
- "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
- "empty_column.hashtag": "There is nothing in this hashtag yet.",
- "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
- "empty_column.home.public_timeline": "the public timeline",
- "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
- "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
- "follow_request.authorize": "Authorize",
- "follow_request.reject": "Reject",
- "getting_started.appsshort": "Apps",
- "getting_started.faq": "FAQ",
+ "compose_form.spoiler_placeholder": "Skribu tie vian averton",
+ "confirmation_modal.cancel": "Malfari",
+ "confirmations.block.confirm": "Bloki",
+ "confirmations.block.message": "Ĉu vi konfirmas la blokadon de {name}?",
+ "confirmations.delete.confirm": "Malaperigi",
+ "confirmations.delete.message": "Ĉu vi konfirmas la malaperigon de tiun pepon?",
+ "confirmations.domain_block.confirm": "Kaŝi la tutan reton",
+ "confirmations.domain_block.message": "Ĉu vi vere, vere certas, ke vi volas bloki {domain} tute? Plej ofte, kelkaj celitaj blokadoj aŭ silentigoj estas sufiĉaj kaj preferindaj.",
+ "confirmations.mute.confirm": "Silentigi",
+ "confirmations.mute.message": "Ĉu vi konfirmas la silentigon de {name}?",
+ "confirmations.unfollow.confirm": "Ne plu sekvi",
+ "confirmations.unfollow.message": "Ĉu vi volas ĉesi sekvi {name}?",
+ "embed.instructions": "Enmetu tiun statkonigon ĉe vian retejon kopiante la ĉi-suban kodon.",
+ "embed.preview": "Ĝi aperos tiel:",
+ "emoji_button.activity": "Aktivecoj",
+ "emoji_button.custom": "Personaj",
+ "emoji_button.flags": "Flagoj",
+ "emoji_button.food": "Manĝi kaj trinki",
+ "emoji_button.label": "Enmeti mieneton",
+ "emoji_button.nature": "Naturo",
+ "emoji_button.not_found": "Neniuj mienetoj!! (╯°□°)╯︵ ┻━┻",
+ "emoji_button.objects": "Objektoj",
+ "emoji_button.people": "Homoj",
+ "emoji_button.recent": "Ofte uzataj",
+ "emoji_button.search": "Serĉo…",
+ "emoji_button.search_results": "Rezultatoj de serĉo",
+ "emoji_button.symbols": "Simboloj",
+ "emoji_button.travel": "Vojaĝoj & lokoj",
+ "empty_column.community": "La loka tempolinio estas malplena. Skribu ion por plenigi ĝin!",
+ "empty_column.hashtag": "Ĝise, neniu enhavo estas asociita kun tiu kradvorto.",
+ "empty_column.home": "Via hejma tempolinio estas malplena! Vizitu {public} aŭ uzu la serĉilon por renkonti aliajn uzantojn.",
+ "empty_column.home.public_timeline": "la publika tempolinio",
+ "empty_column.notifications": "Vi dume ne havas sciigojn. Interagi kun aliajn uzantojn por komenci la konversacion.",
+ "empty_column.public": "Estas nenio ĉi tie! Publike skribu ion, aŭ mane sekvu uzantojn de aliaj instancoj por plenigi la publikan tempolinion.",
+ "follow_request.authorize": "Akcepti",
+ "follow_request.reject": "Rifuzi",
+ "getting_started.appsshort": "Aplikaĵoj",
+ "getting_started.faq": "Oftaj demandoj",
"getting_started.heading": "Por komenci",
- "getting_started.open_source_notice": "Mastodon estas malfermitkoda programo. Vi povas kontribui aŭ raporti problemojn en github je {github}.",
- "getting_started.userguide": "User Guide",
- "home.column_settings.advanced": "Advanced",
- "home.column_settings.basic": "Basic",
- "home.column_settings.filter_regex": "Filter out by regular expressions",
- "home.column_settings.show_reblogs": "Show boosts",
- "home.column_settings.show_replies": "Show replies",
- "home.settings": "Column settings",
+ "getting_started.open_source_notice": "Mastodono estas malfermkoda programo. Vi povas kontribui aŭ raporti problemojn en GitHub je {github}.",
+ "getting_started.userguide": "Gvidilo de uzo",
+ "home.column_settings.advanced": "Precizaj agordoj",
+ "home.column_settings.basic": "Bazaj agordoj",
+ "home.column_settings.filter_regex": "Forfiltri per regulesprimo",
+ "home.column_settings.show_reblogs": "Montri diskonigojn",
+ "home.column_settings.show_replies": "Montri respondojn",
+ "home.settings": "Agordoj de la kolumno",
"lightbox.close": "Fermi",
- "lightbox.next": "Next",
- "lightbox.previous": "Previous",
- "loading_indicator.label": "Ŝarĝanta...",
- "media_gallery.toggle_visible": "Toggle visibility",
- "missing_indicator.label": "Not found",
- "navigation_bar.blocks": "Blocked users",
+ "lightbox.next": "Malantaŭa",
+ "lightbox.previous": "Antaŭa",
+ "loading_indicator.label": "Ŝarganta…",
+ "media_gallery.toggle_visible": "Baskuli videblecon",
+ "missing_indicator.label": "Ne trovita",
+ "navigation_bar.blocks": "Blokitaj uzantoj",
"navigation_bar.community_timeline": "Loka tempolinio",
"navigation_bar.edit_profile": "Redakti la profilon",
- "navigation_bar.favourites": "Favourites",
- "navigation_bar.follow_requests": "Follow requests",
- "navigation_bar.info": "Extended information",
+ "navigation_bar.favourites": "Favoritaj",
+ "navigation_bar.follow_requests": "Abonpetoj",
+ "navigation_bar.info": "Plia informo",
"navigation_bar.logout": "Elsaluti",
- "navigation_bar.mutes": "Muted users",
- "navigation_bar.pins": "Pinned toots",
+ "navigation_bar.mutes": "Silentigitaj uzantoj",
+ "navigation_bar.pins": "Alpinglitaj pepoj",
"navigation_bar.preferences": "Preferoj",
"navigation_bar.public_timeline": "Fratara tempolinio",
"notification.favourite": "{name} favoris vian mesaĝon",
"notification.follow": "{name} sekvis vin",
"notification.mention": "{name} menciis vin",
"notification.reblog": "{name} diskonigis vian mesaĝon",
- "notifications.clear": "Clear notifications",
- "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
+ "notifications.clear": "Forviŝi la sciigojn",
+ "notifications.clear_confirmation": "Ĉu vi certe volas malaperigi ĉiujn viajn sciigojn?",
"notifications.column_settings.alert": "Retumilaj atentigoj",
- "notifications.column_settings.favourite": "Favoroj:",
+ "notifications.column_settings.favourite": "Favoritoj:",
"notifications.column_settings.follow": "Novaj sekvantoj:",
"notifications.column_settings.mention": "Mencioj:",
- "notifications.column_settings.push": "Push notifications",
- "notifications.column_settings.push_meta": "This device",
+ "notifications.column_settings.push": "Puŝsciigoj",
+ "notifications.column_settings.push_meta": "Tiu ĉi aparato",
"notifications.column_settings.reblog": "Diskonigoj:",
"notifications.column_settings.show": "Montri en kolono",
- "notifications.column_settings.sound": "Play sound",
- "onboarding.done": "Done",
- "onboarding.next": "Next",
- "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
- "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
- "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
- "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
- "onboarding.page_one.handle": "You are on {domain}, so your full handle is {handle}",
- "onboarding.page_one.welcome": "Welcome to Mastodon!",
- "onboarding.page_six.admin": "Your instance's admin is {admin}.",
- "onboarding.page_six.almost_done": "Almost done...",
- "onboarding.page_six.appetoot": "Bon Appetoot!",
- "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
- "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
- "onboarding.page_six.guidelines": "community guidelines",
- "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
- "onboarding.page_six.various_app": "mobile apps",
- "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
- "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
- "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
- "onboarding.skip": "Skip",
- "privacy.change": "Adjust status privacy",
- "privacy.direct.long": "Post to mentioned users only",
- "privacy.direct.short": "Direct",
- "privacy.private.long": "Post to followers only",
- "privacy.private.short": "Followers-only",
- "privacy.public.long": "Post to public timelines",
- "privacy.public.short": "Public",
- "privacy.unlisted.long": "Do not show in public timelines",
- "privacy.unlisted.short": "Unlisted",
- "relative_time.days": "{number}d",
+ "notifications.column_settings.sound": "Eligi sonon",
+ "onboarding.done": "Farita",
+ "onboarding.next": "Malantaŭa",
+ "onboarding.page_five.public_timelines": "La loka tempolinio enhavas mesaĝojn de ĉiuj ĉe {domain}. La federacia tempolinio enhavas ĉiujn mesaĝojn de uzantoj, kiujn iu ĉe {domain} sekvas. Ambaŭ tre utilas por trovi novajn kunparolantojn.",
+ "onboarding.page_four.home": "La hejma tempolinio enhavas la mesaĝojn de ĉiuj uzantoj, kiuj vi sekvas.",
+ "onboarding.page_four.notifications": "La sciiga kolumno informas vin kiam iu interagas kun vi.",
+ "onboarding.page_one.federation": "Mastodono estas reto de nedependaj serviloj, unuiĝintaj por krei pligrandan socian retejon. Ni nomas tiujn servilojn instancoj.",
+ "onboarding.page_one.handle": "Vi estas ĉe {domain}, unu el la multaj instancoj de Mastodono. Via kompleta uznomo do estas {handle}",
+ "onboarding.page_one.welcome": "Bonvenon al Mastodono!",
+ "onboarding.page_six.admin": "Via instancestro estas {admin}.",
+ "onboarding.page_six.almost_done": "Estas preskaŭ finita…",
+ "onboarding.page_six.appetoot": "Bonan a‘pepi’ton!",
+ "onboarding.page_six.apps_available": "{apps} estas elŝuteblaj por iOS, Androido kaj alioj. Kaj nun… bonan a‘pepi’ton!",
+ "onboarding.page_six.github": "Mastodono estas libera, senpaga kaj malfermkoda programaro. Vi povas signali cimojn, proponi funkciojn aŭ kontribui al gîa kreskado ĉe {github}.",
+ "onboarding.page_six.guidelines": "komunreguloj",
+ "onboarding.page_six.read_guidelines": "Ni petas vin: ne forgesu legi la {guidelines}n de {domain}!",
+ "onboarding.page_six.various_app": "telefon-aplikaĵoj",
+ "onboarding.page_three.profile": "Redaktu vian profilon por ŝanĝi vian avataron, priskribon kaj vian nomon. Vi tie trovos ankoraŭ aliajn agordojn.",
+ "onboarding.page_three.search": "Uzu la serĉokampo por trovi uzantojn kaj esplori kradvortojn tiel ke {illustration} kaj {introductions}. Por trovi iun, kiu ne estas ĉe ĉi tiu instanco, uzu ĝian kompletan uznomon.",
+ "onboarding.page_two.compose": "Skribu pepojn en la verkkolumno. Vi povas aldoni bildojn, ŝanĝi la agordojn de privateco kaj aldoni tiklavertojn (« content warning ») dank' al la piktogramoj malsupre.",
+ "onboarding.skip": "Pasigi",
+ "privacy.change": "Alĝustigi la privateco de la mesaĝo",
+ "privacy.direct.long": "Vidigi nur al la menciitaj personoj",
+ "privacy.direct.short": "Rekta",
+ "privacy.private.long": "Vidigi nur al viaj sekvantoj",
+ "privacy.private.short": "Nursekvanta",
+ "privacy.public.long": "Vidigi en publikaj tempolinioj",
+ "privacy.public.short": "Publika",
+ "privacy.unlisted.long": "Ne vidigi en publikaj tempolinioj",
+ "privacy.unlisted.short": "Nelistigita",
+ "relative_time.days": "{number}t",
"relative_time.hours": "{number}h",
- "relative_time.just_now": "now",
+ "relative_time.just_now": "nun",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
- "reply_indicator.cancel": "Rezigni",
- "report.placeholder": "Additional comments",
- "report.submit": "Submit",
- "report.target": "Reporting",
+ "reply_indicator.cancel": "Malfari",
+ "report.placeholder": "Pliaj komentoj",
+ "report.submit": "Sendi",
+ "report.target": "Signalaĵo",
"search.placeholder": "Serĉi",
- "search_popout.search_format": "Advanced search format",
- "search_popout.tips.hashtag": "hashtag",
- "search_popout.tips.status": "status",
- "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
- "search_popout.tips.user": "user",
- "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
- "standalone.public_title": "A look inside...",
- "status.cannot_reblog": "This post cannot be boosted",
+ "search_popout.search_format": "Detala serĉo",
+ "search_popout.tips.hashtag": "kradvorto",
+ "search_popout.tips.status": "statkonigo",
+ "search_popout.tips.text": "Simpla teksto eligas la kongruajn afiŝnomojn, uznomojn kaj kradvortojn.",
+ "search_popout.tips.user": "uzanto",
+ "search_results.total": "{count, number} {count, plural, one {rezultato} other {rezultatoj}}",
+ "standalone.public_title": "Rigardeti…",
+ "status.cannot_reblog": "Tiun publikaĵon oni ne povas diskonigi",
"status.delete": "Forigi",
- "status.embed": "Embed",
+ "status.embed": "Enmeti",
"status.favourite": "Favori",
- "status.load_more": "Load more",
- "status.media_hidden": "Media hidden",
+ "status.load_more": "Ŝargi plie",
+ "status.media_hidden": "Sonbildaĵo kaŝita",
"status.mention": "Mencii @{name}",
- "status.more": "More",
- "status.mute_conversation": "Mute conversation",
- "status.open": "Expand this status",
- "status.pin": "Pin on profile",
+ "status.more": "Pli",
+ "status.mute_conversation": "Silentigi konversacion",
+ "status.open": "Disfaldi statkonigon",
+ "status.pin": "Pingli al la profilo",
"status.reblog": "Diskonigi",
- "status.reblogged_by": "{name} diskonigita",
+ "status.reblogged_by": "{name} diskonigis",
"status.reply": "Respondi",
- "status.replyAll": "Reply to thread",
- "status.report": "Report @{name}",
+ "status.replyAll": "Respondi al la fadeno",
+ "status.report": "Signali @{name}",
"status.sensitive_toggle": "Alklaki por vidi",
"status.sensitive_warning": "Tikla enhavo",
- "status.share": "Share",
- "status.show_less": "Show less",
- "status.show_more": "Show more",
- "status.unmute_conversation": "Unmute conversation",
- "status.unpin": "Unpin from profile",
+ "status.share": "Diskonigi",
+ "status.show_less": "Refaldi",
+ "status.show_more": "Disfaldi",
+ "status.unmute_conversation": "Malsilentigi konversacion",
+ "status.unpin": "Depingli de profilo",
"tabs_bar.compose": "Ekskribi",
- "tabs_bar.federated_timeline": "Federated",
+ "tabs_bar.federated_timeline": "Federacia tempolinio",
"tabs_bar.home": "Hejmo",
- "tabs_bar.local_timeline": "Local",
+ "tabs_bar.local_timeline": "Loka tempolinio",
"tabs_bar.notifications": "Sciigoj",
- "upload_area.title": "Drag & drop to upload",
- "upload_button.label": "Aldoni enhavaĵon",
- "upload_form.description": "Describe for the visually impaired",
+ "upload_area.title": "Algliti por alŝuti",
+ "upload_button.label": "Aldoni sonbildaĵon",
+ "upload_form.description": "Priskribi por la misvidantaj",
"upload_form.undo": "Malfari",
- "upload_progress.label": "Uploading...",
- "video.close": "Close video",
- "video.exit_fullscreen": "Exit full screen",
- "video.expand": "Expand video",
- "video.fullscreen": "Full screen",
- "video.hide": "Hide video",
- "video.mute": "Mute sound",
- "video.pause": "Pause",
- "video.play": "Play",
- "video.unmute": "Unmute sound"
+ "upload_progress.label": "Alŝutanta…",
+ "video.close": "Fermi videon",
+ "video.exit_fullscreen": "Eliri el plenekrano",
+ "video.expand": "Vastigi videon",
+ "video.fullscreen": "Igi plenekrane",
+ "video.hide": "Kaŝi videon",
+ "video.mute": "Silentigi",
+ "video.pause": "Paŭzi",
+ "video.play": "Legi",
+ "video.unmute": "Malsilentigi"
}
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index d99dacd593..2919928afa 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -63,7 +63,7 @@
"confirmations.mute.message": "정말로 {name}를 뮤트하시겠습니까?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
- "embed.instructions": "아래의 코드를 복사하여 대화를 원하는 곳으로 퍼가세요.",
+ "embed.instructions": "아래의 코드를 복사하여 대화를 원하는 곳으로 공유하세요.",
"embed.preview": "다음과 같이 표시됩니다:",
"emoji_button.activity": "활동",
"emoji_button.custom": "Custom",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index 1e0849d951..d826423b5b 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -31,7 +31,7 @@
"column.favourites": "Favorits",
"column.follow_requests": "Demandas d’abonament",
"column.home": "Acuèlh",
- "column.mutes": "Personas en silenci",
+ "column.mutes": "Personas rescondudas",
"column.notifications": "Notificacions",
"column.pins": "Tuts penjats",
"column.public": "Flux public global",
@@ -55,12 +55,12 @@
"confirmation_modal.cancel": "Anullar",
"confirmations.block.confirm": "Blocar",
"confirmations.block.message": "Sètz segur de voler blocar {name} ?",
- "confirmations.delete.confirm": "Suprimir",
- "confirmations.delete.message": "Sètz segur de voler suprimir l’estatut ?",
+ "confirmations.delete.confirm": "Escafar",
+ "confirmations.delete.message": "Sètz segur de voler escafar l’estatut ?",
"confirmations.domain_block.confirm": "Amagar tot lo domeni",
"confirmations.domain_block.message": "Sètz segur segur de voler blocar completament {domain} ? De còps cal pas que blocar o rescondre unas personas solament.",
- "confirmations.mute.confirm": "Metre en silenci",
- "confirmations.mute.message": "Sètz segur de voler metre en silenci {name} ?",
+ "confirmations.mute.confirm": "Rescondre",
+ "confirmations.mute.message": "Sètz segur de voler rescondre {name} ?",
"confirmations.unfollow.confirm": "Quitar de sègre",
"confirmations.unfollow.message": "Volètz vertadièrament quitar de sègre {name} ?",
"embed.instructions": "Embarcar aqueste estatut per lo far veire sus un site Internet en copiar lo còdi çai-jos.",
@@ -135,7 +135,7 @@
"onboarding.page_five.public_timelines": "Lo flux local mòstra los estatuts publics del monde de vòstra instància, aquí {domain}. Lo flux federat mòstra los estatuts publics de la gent que los de {domain} sègon. Son los fluxes publics, un bon biais de trobar de mond.",
"onboarding.page_four.home": "Lo flux d’acuèlh mòstra los estatuts del mond que seguètz.",
"onboarding.page_four.notifications": "La colomna de notificacions vos fa veire quand qualqu’un interagís amb vos",
- "onboarding.page_one.federation": "Mastodon es un malhum de servidors independents que comunican per bastir un malhum mai larg. Òm los apèla instàncias.",
+ "onboarding.page_one.federation": "Mastodon es un malhum de servidors independents que comunican per construire un malhum mai larg. Òm los apèla instàncias.",
"onboarding.page_one.handle": "Sètz sus {domain}, doncas vòstre identificant complet es {handle}",
"onboarding.page_one.welcome": "Benvengut a Mastodon !",
"onboarding.page_six.admin": "Vòstre administrator d’instància es {admin}.",
@@ -159,11 +159,11 @@
"privacy.public.short": "Public",
"privacy.unlisted.long": "Mostrar pas dins los fluxes publics",
"privacy.unlisted.short": "Pas-listat",
- "relative_time.days": "fa {number}j",
- "relative_time.hours": "fa {number}h",
+ "relative_time.days": "fa {number} d",
+ "relative_time.hours": "fa {number} h",
"relative_time.just_now": "ara",
- "relative_time.minutes": "fa {number} minutas",
- "relative_time.seconds": "fa {number} segondas",
+ "relative_time.minutes": "fa {number} min",
+ "relative_time.seconds": "fa {number} s",
"reply_indicator.cancel": "Anullar",
"report.placeholder": "Comentaris addicionals",
"report.submit": "Mandar",
@@ -197,7 +197,7 @@
"status.share": "Partejar",
"status.show_less": "Tornar plegar",
"status.show_more": "Desplegar",
- "status.unmute_conversation": "Conversacions amb silenci levat",
+ "status.unmute_conversation": "Tornar mostrar la conversacion",
"status.unpin": "Tirar del perfil",
"tabs_bar.compose": "Compausar",
"tabs_bar.federated_timeline": "Flux public global",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index cf76f1b1fa..b23a5e69fb 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -89,7 +89,7 @@
"follow_request.reject": "Odrzuć",
"getting_started.appsshort": "Aplikacje",
"getting_started.faq": "FAQ",
- "getting_started.heading": "Naucz się korzystać",
+ "getting_started.heading": "Rozpocznij",
"getting_started.open_source_notice": "Mastodon jest oprogramowaniem o otwartym źródle. Możesz pomóc w rozwoju lub zgłaszać błędy na GitHubie tutaj: {github}.",
"getting_started.userguide": "Podręcznik użytkownika",
"home.column_settings.advanced": "Zaawansowane",
@@ -174,7 +174,7 @@
"search_popout.tips.status": "wpis",
"search_popout.tips.text": "Proste wyszukiwanie pasujących pseudonimów, nazw użytkowników i hashtagów",
"search_popout.tips.user": "użytkownik",
- "search_results.total": "{count, number} {count, plural, one {wynik} more {wyniki}}",
+ "search_results.total": "{count, number} {count, plural, one {wynik} few {wyniki} many {wyników} more {wyników}}",
"standalone.public_title": "Spojrzenie w głąb…",
"status.cannot_reblog": "Ten wpis nie może zostać podbity",
"status.delete": "Usuń",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index ddb8b83f5f..a04d1cc31d 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -161,7 +161,7 @@
"privacy.unlisted.short": "Não listada",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
- "relative_time.just_now": "now",
+ "relative_time.just_now": "agora",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancelar",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 104b063f54..65bc5b374b 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -63,20 +63,20 @@
"confirmations.mute.message": "Вы уверены, что хотите заглушить {name}?",
"confirmations.unfollow.confirm": "Отписаться",
"confirmations.unfollow.message": "Вы уверены, что хотите отписаться от {name}?",
- "embed.instructions": "Embed this status on your website by copying the code below.",
- "embed.preview": "Here is what it will look like:",
+ "embed.instructions": "Встройте этот статус на Вашем сайте, скопировав код внизу.",
+ "embed.preview": "Так это будет выглядеть:",
"emoji_button.activity": "Занятия",
- "emoji_button.custom": "Custom",
+ "emoji_button.custom": "Собственные",
"emoji_button.flags": "Флаги",
"emoji_button.food": "Еда и напитки",
"emoji_button.label": "Вставить эмодзи",
"emoji_button.nature": "Природа",
- "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
+ "emoji_button.not_found": "Нет эмодзи!! (╯°□°)╯︵ ┻━┻",
"emoji_button.objects": "Предметы",
"emoji_button.people": "Люди",
- "emoji_button.recent": "Frequently used",
+ "emoji_button.recent": "Последние",
"emoji_button.search": "Найти...",
- "emoji_button.search_results": "Search results",
+ "emoji_button.search_results": "Результаты поиска",
"emoji_button.symbols": "Символы",
"emoji_button.travel": "Путешествия",
"empty_column.community": "Локальная лента пуста. Напишите что-нибудь, чтобы разогреть народ!",
@@ -159,34 +159,34 @@
"privacy.public.short": "Публичный",
"privacy.unlisted.long": "Не показывать в лентах",
"privacy.unlisted.short": "Скрытый",
- "relative_time.days": "{number}d",
- "relative_time.hours": "{number}h",
- "relative_time.just_now": "now",
- "relative_time.minutes": "{number}m",
- "relative_time.seconds": "{number}s",
+ "relative_time.days": "{number}д",
+ "relative_time.hours": "{number}ч",
+ "relative_time.just_now": "только что",
+ "relative_time.minutes": "{number}м",
+ "relative_time.seconds": "{number}с",
"reply_indicator.cancel": "Отмена",
"report.placeholder": "Комментарий",
"report.submit": "Отправить",
"report.target": "Жалуемся на",
"search.placeholder": "Поиск",
- "search_popout.search_format": "Advanced search format",
- "search_popout.tips.hashtag": "hashtag",
- "search_popout.tips.status": "status",
- "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
- "search_popout.tips.user": "user",
+ "search_popout.search_format": "Продвинутый формат поиска",
+ "search_popout.tips.hashtag": "хэштег",
+ "search_popout.tips.status": "статус",
+ "search_popout.tips.text": "Простой ввод текста покажет совпадающие имена пользователей, отображаемые имена и хэштеги",
+ "search_popout.tips.user": "пользователь",
"search_results.total": "{count, number} {count, plural, one {результат} few {результата} many {результатов} other {результатов}}",
- "standalone.public_title": "A look inside...",
+ "standalone.public_title": "Прямо сейчас",
"status.cannot_reblog": "Этот статус не может быть продвинут",
"status.delete": "Удалить",
- "status.embed": "Embed",
+ "status.embed": "Встроить",
"status.favourite": "Нравится",
"status.load_more": "Показать еще",
"status.media_hidden": "Медиаконтент скрыт",
"status.mention": "Упомянуть @{name}",
- "status.more": "More",
+ "status.more": "Больше",
"status.mute_conversation": "Заглушить тред",
"status.open": "Развернуть статус",
- "status.pin": "Pin on profile",
+ "status.pin": "Закрепить в профиле",
"status.reblog": "Продвинуть",
"status.reblogged_by": "{name} продвинул(а)",
"status.reply": "Ответить",
@@ -194,11 +194,11 @@
"status.report": "Пожаловаться",
"status.sensitive_toggle": "Нажмите для просмотра",
"status.sensitive_warning": "Чувствительный контент",
- "status.share": "Share",
+ "status.share": "Поделиться",
"status.show_less": "Свернуть",
"status.show_more": "Развернуть",
"status.unmute_conversation": "Снять глушение с треда",
- "status.unpin": "Unpin from profile",
+ "status.unpin": "Открепить от профиля",
"tabs_bar.compose": "Написать",
"tabs_bar.federated_timeline": "Глобальная",
"tabs_bar.home": "Главная",
@@ -206,16 +206,16 @@
"tabs_bar.notifications": "Уведомления",
"upload_area.title": "Перетащите сюда, чтобы загрузить",
"upload_button.label": "Добавить медиаконтент",
- "upload_form.description": "Describe for the visually impaired",
+ "upload_form.description": "Описать для людей с нарушениями зрения",
"upload_form.undo": "Отменить",
"upload_progress.label": "Загрузка...",
- "video.close": "Close video",
- "video.exit_fullscreen": "Exit full screen",
- "video.expand": "Expand video",
- "video.fullscreen": "Full screen",
- "video.hide": "Hide video",
- "video.mute": "Mute sound",
- "video.pause": "Pause",
- "video.play": "Play",
- "video.unmute": "Unmute sound"
+ "video.close": "Закрыть видео",
+ "video.exit_fullscreen": "Покинуть полноэкранный режим",
+ "video.expand": "Развернуть видео",
+ "video.fullscreen": "Полноэкранный режим",
+ "video.hide": "Скрыть видео",
+ "video.mute": "Заглушить звук",
+ "video.pause": "Пауза",
+ "video.play": "Пуск",
+ "video.unmute": "Включить звук"
}
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index 827c815cf2..0f4bbb7c10 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -1,25 +1,25 @@
{
"account.block": "屏蔽 @{name}",
"account.block_domain": "隐藏一切来自 {domain} 的嘟文",
- "account.disclaimer_full": "下列资料不一定完整。",
+ "account.disclaimer_full": "此处显示的信息可能不是全部内容。",
"account.edit_profile": "修改个人资料",
"account.follow": "关注",
"account.followers": "关注者",
- "account.follows": "正关注",
- "account.follows_you": "关注你",
+ "account.follows": "正在关注",
+ "account.follows_you": "关注了你",
"account.media": "媒体",
"account.mention": "提及 @{name}",
- "account.mute": "将 @{name} 静音",
+ "account.mute": "静音 @{name}",
"account.posts": "嘟文",
"account.report": "举报 @{name}",
- "account.requested": "等待审批",
- "account.share": "分享 @{name}的个人资料",
- "account.unblock": "解除对 @{name} 的屏蔽",
+ "account.requested": "正在等待对方同意。点击以取消发送关注请求",
+ "account.share": "分享 @{name} 的个人资料",
+ "account.unblock": "不再屏蔽 @{name}",
"account.unblock_domain": "不再隐藏 {domain}",
"account.unfollow": "取消关注",
- "account.unmute": "取消 @{name} 的静音",
+ "account.unmute": "不再静音 @{name}",
"account.view_full_profile": "查看完整资料",
- "boost_modal.combo": "如你想在下次路过时显示,请按{combo},",
+ "boost_modal.combo": "下次按住 {combo} 即可跳过此提示",
"bundle_column_error.body": "载入组件出错。",
"bundle_column_error.retry": "重试",
"bundle_column_error.title": "网络错误",
@@ -37,72 +37,72 @@
"column.public": "跨站公共时间轴",
"column_back_button.label": "返回",
"column_header.hide_settings": "隐藏设置",
- "column_header.moveLeft_settings": "将栏左移",
- "column_header.moveRight_settings": "将栏右移",
+ "column_header.moveLeft_settings": "将此栏左移",
+ "column_header.moveRight_settings": "将此栏右移",
"column_header.pin": "固定",
"column_header.show_settings": "显示设置",
- "column_header.unpin": "取下",
+ "column_header.unpin": "取消固定",
"column_subheading.navigation": "导航",
"column_subheading.settings": "设置",
- "compose_form.lock_disclaimer": "你的帐户没 {locked}. 任何人可以通过关注你来查看只有关注者可见的嘟文.",
+ "compose_form.lock_disclaimer": "你的帐户没有{locked}。任何人都可以通过关注你来查看仅关注者可见的嘟文。",
"compose_form.lock_disclaimer.lock": "被保护",
"compose_form.placeholder": "在想啥?",
"compose_form.publish": "嘟嘟",
"compose_form.publish_loud": "{publish}!",
- "compose_form.sensitive": "将媒体文件标示为“敏感内容”",
- "compose_form.spoiler": "将部分文本藏于警告消息之后",
- "compose_form.spoiler_placeholder": "敏感内容的警告消息",
+ "compose_form.sensitive": "将媒体文件标记为敏感内容",
+ "compose_form.spoiler": "折叠嘟文内容",
+ "compose_form.spoiler_placeholder": "折叠部分的警告消息",
"confirmation_modal.cancel": "取消",
"confirmations.block.confirm": "屏蔽",
- "confirmations.block.message": "想好了,真的要屏蔽 {name}?",
+ "confirmations.block.message": "想好了,真的要屏蔽 {name}?",
"confirmations.delete.confirm": "删除",
- "confirmations.delete.message": "想好了,真的要删除这条嘟文?",
+ "confirmations.delete.message": "想好了,真的要删除这条嘟文?",
"confirmations.domain_block.confirm": "隐藏整个网站",
- "confirmations.domain_block.message": "你真的真的确定要隐藏整个 {domain} ?多数情况下,封锁或静音几个特定目标就好。",
+ "confirmations.domain_block.message": "你真的真的确定要隐藏整个 {domain}?多数情况下,屏蔽或静音几个特定的用户就应该能满足你的需要了。",
"confirmations.mute.confirm": "静音",
- "confirmations.mute.message": "想好了,真的要静音 {name}?",
+ "confirmations.mute.message": "想好了,真的要静音 {name}?",
"confirmations.unfollow.confirm": "取消关注",
- "confirmations.unfollow.message": "确定要取消关注 {name}吗?",
- "embed.instructions": "要内嵌此嘟文,请将以下代码贴进你的网站。",
- "embed.preview": "到时大概长这样:",
+ "confirmations.unfollow.message": "确定要取消关注 {name} 吗?",
+ "embed.instructions": "要在你的网站上嵌入这条嘟文,请复制以下代码。",
+ "embed.preview": "它会像这样显示出来:",
"emoji_button.activity": "活动",
- "emoji_button.custom": "Custom",
+ "emoji_button.custom": "自定义",
"emoji_button.flags": "旗帜",
"emoji_button.food": "食物和饮料",
"emoji_button.label": "加入表情符号",
"emoji_button.nature": "自然",
- "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
+ "emoji_button.not_found": "木有这个表情符号!(╯°□°)╯︵ ┻━┻",
"emoji_button.objects": "物体",
"emoji_button.people": "人物",
- "emoji_button.recent": "Frequently used",
+ "emoji_button.recent": "常用",
"emoji_button.search": "搜索…",
- "emoji_button.search_results": "Search results",
+ "emoji_button.search_results": "搜索结果",
"emoji_button.symbols": "符号",
- "emoji_button.travel": "旅途和地点",
- "empty_column.community": "本站时间轴暂时未有内容,快嘟几个来抢头香啊!",
- "empty_column.hashtag": "这个标签暂时未有内容。",
+ "emoji_button.travel": "旅行和地点",
+ "empty_column.community": "本站时间轴暂时没有内容,快嘟几个来抢头香啊!",
+ "empty_column.hashtag": "这个话题标签下暂时没有内容。",
"empty_column.home": "你还没有关注任何用户。快看看{public},向其他用户搭讪吧。",
"empty_column.home.public_timeline": "公共时间轴",
- "empty_column.notifications": "你没有任何通知纪录,快向其他用户搭讪吧。",
- "empty_column.public": "跨站公共时间轴暂时没有内容!快写一些公共的嘟文,或者关注另一些服务器实例的用户吧!你和本站、友站的交流,将决定这里出现的内容。",
- "follow_request.authorize": "批准",
+ "empty_column.notifications": "你还没有收到过通知信息,快向其他用户搭讪吧。",
+ "empty_column.public": "这里神马都没有!写一些公开的嘟文,或者关注其他实例的用户,这里就会有嘟文出现了哦!",
+ "follow_request.authorize": "同意",
"follow_request.reject": "拒绝",
- "getting_started.appsshort": "Apps",
- "getting_started.faq": "FAQ",
+ "getting_started.appsshort": "应用",
+ "getting_started.faq": "常见问题",
"getting_started.heading": "开始使用",
- "getting_started.open_source_notice": "Mastodon 是一个开放源码的软件。你可以在官方 GitHub ({github}) 贡献或者回报问题。",
+ "getting_started.open_source_notice": "Mastodon 是一个开源软件。欢迎前往 GitHub({github})贡献代码或反馈问题。",
"getting_started.userguide": "用户指南",
- "home.column_settings.advanced": "高端",
- "home.column_settings.basic": "基本",
- "home.column_settings.filter_regex": "使用正则表达式 (regex) 过滤",
- "home.column_settings.show_reblogs": "显示被转的嘟文",
- "home.column_settings.show_replies": "显示回应嘟文",
- "home.settings": "字段设置",
+ "home.column_settings.advanced": "高级设置",
+ "home.column_settings.basic": "基本设置",
+ "home.column_settings.filter_regex": "使用正则表达式(regex)过滤",
+ "home.column_settings.show_reblogs": "显示转嘟",
+ "home.column_settings.show_replies": "显示回复",
+ "home.settings": "栏目设置",
"lightbox.close": "关闭",
"lightbox.next": "下一步",
"lightbox.previous": "上一步",
"loading_indicator.label": "加载中……",
- "media_gallery.toggle_visible": "打开或关上",
+ "media_gallery.toggle_visible": "切换显示/隐藏",
"missing_indicator.label": "找不到内容",
"navigation_bar.blocks": "被屏蔽的用户",
"navigation_bar.community_timeline": "本站时间轴",
@@ -119,9 +119,9 @@
"notification.follow": "{name} 开始关注你",
"notification.mention": "{name} 提及你",
"notification.reblog": "{name} 转嘟了你的嘟文",
- "notifications.clear": "清空通知纪录",
- "notifications.clear_confirmation": "你确定要清空通知纪录吗?",
- "notifications.column_settings.alert": "显示桌面通知",
+ "notifications.clear": "清空通知列表",
+ "notifications.clear_confirmation": "你确定要清空通知列表吗?",
+ "notifications.column_settings.alert": "桌面通知",
"notifications.column_settings.favourite": "你的嘟文被收藏:",
"notifications.column_settings.follow": "关注你:",
"notifications.column_settings.mention": "提及你:",
@@ -132,90 +132,91 @@
"notifications.column_settings.sound": "播放音效",
"onboarding.done": "出发!",
"onboarding.next": "下一步",
- "onboarding.page_five.public_timelines": "本站时间轴显示来自 {domain} 的所有人的公共嘟文。 跨站公共时间轴显示 {domain} 上的各位关注的来自所有Mastodon服务器实例上的人发表的公共嘟文。这些就是寻人好去处的公共时间轴啦。",
- "onboarding.page_four.home": "你的主时间轴上是你关注的用户的嘟文.",
- "onboarding.page_four.notifications": "如果你和他人产生了互动,便会出现在通知列上啦~",
- "onboarding.page_one.federation": "Mastodon是由一系列独立的服务器共同打造的强大的社交网络,我们将这些独立但又相互连接的服务器叫做服务器实例。",
- "onboarding.page_one.handle": "你在 {domain}, {handle} 就是你的完整帐户名称。",
- "onboarding.page_one.welcome": "欢迎来到 Mastodon!",
+ "onboarding.page_five.public_timelines": "本站时间轴显示的是由本站({domain})用户发布的所有公开嘟文。跨站公共时间轴显示的的是由本站用户关注对象所发布的所有公开嘟文。这些就是寻人好去处的公共时间轴啦。",
+ "onboarding.page_four.home": "你的主页上的时间轴上显示的是你关注对象的嘟文。",
+ "onboarding.page_four.notifications": "如果有人与你互动,便会出现在通知栏中哦~",
+ "onboarding.page_one.federation": "Mastodon 是由一系列独立的服务器共同打造的强大的社交网络,我们将这些各自独立但又相互连接的服务器叫做实例。",
+ "onboarding.page_one.handle": "你在 {domain},{handle} 就是你的完整帐户名称。",
+ "onboarding.page_one.welcome": "欢迎来到 Mastodon!",
"onboarding.page_six.admin": "{admin} 是你所在服务器实例的管理员.",
- "onboarding.page_six.almost_done": "差不多了…",
- "onboarding.page_six.appetoot": "嗷呜~",
- "onboarding.page_six.apps_available": "也有适用于 iOS, Android 和其它平台的 {apps} 咯~",
- "onboarding.page_six.github": "Mastodon 是自由的开放源代码软件。欢迎来 {github} 报告问题,提交功能请求,或者贡献代码 :-)",
+ "onboarding.page_six.almost_done": "差不多了……",
+ "onboarding.page_six.appetoot": "嗷呜~",
+ "onboarding.page_six.apps_available": "我们还有适用于 iOS、Android 和其它平台的{apps}哦~",
+ "onboarding.page_six.github": "Mastodon 是自由的开源软件。欢迎前往 {github} 反馈问题、提出对新功能的建议或贡献代码 :-)",
"onboarding.page_six.guidelines": "社区指南",
- "onboarding.page_six.read_guidelines": "别忘了看看 {domain} 的 {guidelines}!",
- "onboarding.page_six.various_app": "移动应用程序",
- "onboarding.page_three.profile": "修改你的个人资料,比如头像、简介、和昵称等等。在那还可以找到其它首选项。",
- "onboarding.page_three.search": "用搜索来找人和标签吧,比如 {illustration} 或者 {introductions}。想找其它服务器实例上的人,用完整帐户名称(用户名@域名)啦。",
- "onboarding.page_two.compose": "从这里开始嘟!上面的按钮提供了上传图片,修改隐私设置和提示敏感内容等多种功能。.",
- "onboarding.skip": "好啦好啦我知道啦",
- "privacy.change": "调整隐私设置",
- "privacy.direct.long": "只有提及的用户能看到",
- "privacy.direct.short": "私人消息",
- "privacy.private.long": "只有关注你用户能看到",
- "privacy.private.short": "关注者",
- "privacy.public.long": "在公共时间轴显示",
- "privacy.public.short": "公共",
- "privacy.unlisted.long": "公开,但不在公共时间轴显示",
- "privacy.unlisted.short": "公开",
- "relative_time.days": "{number}d",
- "relative_time.hours": "{number}h",
- "relative_time.just_now": "now",
- "relative_time.minutes": "{number}m",
- "relative_time.seconds": "{number}s",
+ "onboarding.page_six.read_guidelines": "别忘了看看 {domain} 的{guidelines}!",
+ "onboarding.page_six.various_app": "移动设备应用",
+ "onboarding.page_three.profile": "你可以修改你的个人资料,比如头像、简介和昵称等偏好设置。",
+ "onboarding.page_three.search": "你可以通过搜索功能寻找用户和话题标签,比如{illustration}或者{introductions}。如果你想搜索其他实例上的用户,就需要输入完整帐户名称(用户名@域名)哦。",
+ "onboarding.page_two.compose": "在撰写栏中开始嘟嘟吧!下方的按钮分别用来上传图片,修改嘟文可见范围,以及添加警告信息。",
+ "onboarding.skip": "跳过",
+ "privacy.change": "设置嘟文可见范围",
+ "privacy.direct.long": "只有被提及的用户能看到",
+ "privacy.direct.short": "私信",
+ "privacy.private.long": "只有关注你的用户能看到",
+ "privacy.private.short": "仅关注者",
+ "privacy.public.long": "所有人可见,并会出现在公共时间轴上",
+ "privacy.public.short": "公开",
+ "privacy.unlisted.long": "所有人可见,但不会出现在公共时间轴上",
+ "privacy.unlisted.short": "不公开",
+ "relative_time.days": "{number} 天",
+ "relative_time.hours": "{number} 时",
+ "relative_time.just_now": "刚刚",
+ "relative_time.minutes": "{number} 分",
+ "relative_time.seconds": "{number} 秒",
"reply_indicator.cancel": "取消",
- "report.placeholder": "额外消息",
+ "report.placeholder": "附言",
"report.submit": "提交",
- "report.target": "Reporting",
+ "report.target": "举报 {target}",
"search.placeholder": "搜索",
- "search_popout.search_format": "Advanced search format",
- "search_popout.tips.hashtag": "hashtag",
- "search_popout.tips.status": "status",
- "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
- "search_popout.tips.user": "user",
- "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
+ "search_popout.search_format": "高级搜索格式",
+ "search_popout.tips.hashtag": "话题标签",
+ "search_popout.tips.status": "嘟文",
+ "search_popout.tips.text": "使用普通字符进行搜索将会返回昵称、用户名和话题标签",
+ "search_popout.tips.user": "用户",
+ "search_results.total": "共 {count, number} 个结果",
"standalone.public_title": "大家都在干啥?",
- "status.cannot_reblog": "没法转嘟这条嘟文啦……",
+ "status.cannot_reblog": "无法转嘟这条嘟文",
"status.delete": "删除",
"status.embed": "嵌入",
"status.favourite": "收藏",
"status.load_more": "加载更多",
"status.media_hidden": "隐藏媒体内容",
"status.mention": "提及 @{name}",
- "status.more": "More",
- "status.mute_conversation": "静音对话",
+ "status.more": "更多",
+ "status.mute_conversation": "静音此对话",
"status.open": "展开嘟文",
- "status.pin": "置顶到资料",
+ "status.pin": "在个人资料页面置顶",
"status.reblog": "转嘟",
- "status.reblogged_by": "{name} 转嘟",
- "status.reply": "回应",
- "status.replyAll": "回应整串",
+ "status.reblogged_by": "{name} 转嘟了",
+ "status.reply": "回复",
+ "status.replyAll": "回复所有人",
"status.report": "举报 @{name}",
"status.sensitive_toggle": "点击显示",
"status.sensitive_warning": "敏感内容",
- "status.share": "Share",
- "status.show_less": "减少显示",
- "status.show_more": "显示更多",
- "status.unmute_conversation": "解禁对话",
- "status.unpin": "解除置顶",
+ "status.share": "分享",
+ "status.show_less": "隐藏内容",
+ "status.show_more": "显示内容",
+ "status.unmute_conversation": "不再静音此对话",
+ "status.unpin": "在个人资料页面取消置顶",
"tabs_bar.compose": "撰写",
"tabs_bar.federated_timeline": "跨站",
"tabs_bar.home": "主页",
"tabs_bar.local_timeline": "本站",
"tabs_bar.notifications": "通知",
- "upload_area.title": "将文件拖放至此上传",
+ "ui.beforeunload": "如果你现在离开 Mastodon,你的草稿内容将会被丢弃。",
+ "upload_area.title": "将文件拖放到此处开始上传",
"upload_button.label": "上传媒体文件",
- "upload_form.description": "Describe for the visually impaired",
- "upload_form.undo": "还原",
- "upload_progress.label": "上传中……",
- "video.close": "关闭影片",
+ "upload_form.description": "为视觉障碍人士添加文字说明",
+ "upload_form.undo": "取消上传",
+ "upload_progress.label": "上传中…",
+ "video.close": "关闭视频",
"video.exit_fullscreen": "退出全屏",
- "video.expand": "展开影片",
+ "video.expand": "展开视频",
"video.fullscreen": "全屏",
- "video.hide": "隐藏影片",
+ "video.hide": "隐藏视频",
"video.mute": "静音",
"video.pause": "暂停",
"video.play": "播放",
- "video.unmute": "解除静音"
+ "video.unmute": "取消静音"
}
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index 3e9310f164..c709fb88c9 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -31,6 +31,7 @@ import { TIMELINE_DELETE } from '../actions/timelines';
import { STORE_HYDRATE } from '../actions/store';
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
import uuid from '../uuid';
+import { me } from '../initial_state';
const initialState = ImmutableMap({
mounted: false,
@@ -49,7 +50,6 @@ const initialState = ImmutableMap({
media_attachments: ImmutableList(),
suggestion_token: null,
suggestions: ImmutableList(),
- me: null,
default_privacy: 'public',
default_sensitive: false,
resetFileKey: Math.floor((Math.random() * 0x10000)),
@@ -58,7 +58,6 @@ const initialState = ImmutableMap({
function statusToTextMentions(state, status) {
let set = ImmutableOrderedSet([]);
- let me = state.get('me');
if (status.getIn(['account', 'id']) !== me) {
set = set.add(`@${status.getIn(['account', 'acct'])} `);
diff --git a/app/javascript/mastodon/reducers/custom_emojis.js b/app/javascript/mastodon/reducers/custom_emojis.js
index f2a8ca5d2e..307bcc7dc4 100644
--- a/app/javascript/mastodon/reducers/custom_emojis.js
+++ b/app/javascript/mastodon/reducers/custom_emojis.js
@@ -8,7 +8,7 @@ const initialState = ImmutableList();
export default function custom_emojis(state = initialState, action) {
switch(action.type) {
case STORE_HYDRATE:
- emojiSearch('', { custom: buildCustomEmojis(action.state.get('custom_emojis', []), action.state.getIn(['meta', 'auto_play_gif'], false)) });
+ emojiSearch('', { custom: buildCustomEmojis(action.state.get('custom_emojis', [])) });
return action.state.get('custom_emojis');
default:
return state;
diff --git a/app/javascript/mastodon/reducers/meta.js b/app/javascript/mastodon/reducers/meta.js
index 119ef9d8f8..36a5a1c354 100644
--- a/app/javascript/mastodon/reducers/meta.js
+++ b/app/javascript/mastodon/reducers/meta.js
@@ -4,7 +4,6 @@ import { Map as ImmutableMap } from 'immutable';
const initialState = ImmutableMap({
streaming_api_base_url: null,
access_token: null,
- me: null,
});
export default function meta(state = initialState, action) {
diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js
index cccf00a1f7..264db4f558 100644
--- a/app/javascript/mastodon/reducers/notifications.js
+++ b/app/javascript/mastodon/reducers/notifications.js
@@ -99,9 +99,10 @@ export default function notifications(state = initialState, action) {
switch(action.type) {
case NOTIFICATIONS_REFRESH_REQUEST:
case NOTIFICATIONS_EXPAND_REQUEST:
+ return state.set('isLoading', true);
case NOTIFICATIONS_REFRESH_FAIL:
case NOTIFICATIONS_EXPAND_FAIL:
- return state.set('isLoading', true);
+ return state.set('isLoading', false);
case NOTIFICATIONS_SCROLL_TOP:
return updateTop(state, action.top);
case NOTIFICATIONS_UPDATE:
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 8d2bae4f43..0ded6f1596 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -244,6 +244,15 @@
width: 0;
height: 0;
position: absolute;
+
+ img,
+ svg {
+ margin: 0 !important;
+ border: 0 !important;
+ padding: 0 !important;
+ width: 0 !important;
+ height: 0 !important;
+ }
}
.ellipsis {
@@ -510,6 +519,7 @@
font-weight: 400;
overflow: hidden;
white-space: pre-wrap;
+ padding-top: 5px;
&.status__content--with-spoiler {
white-space: normal;
@@ -520,8 +530,9 @@
}
.emojione {
- width: 18px;
- height: 18px;
+ width: 20px;
+ height: 20px;
+ margin: -5px 0 0;
}
p {
@@ -601,7 +612,7 @@
outline: 0;
background: lighten($ui-base-color, 4%);
- &.status-direct {
+ .status.status-direct {
background: lighten($ui-base-color, 12%);
}
@@ -620,6 +631,12 @@
border-bottom: 1px solid lighten($ui-base-color, 8%);
cursor: default;
+ @supports (-ms-overflow-style: -ms-autohiding-scrollbar) {
+ // Add margin to avoid Edge auto-hiding scrollbar appearing over content.
+ // On Edge 16 this is 16px and Edge <=15 it's 12px, so aim for 16px.
+ padding-right: 26px; // 10px + 16px
+ }
+
@keyframes fade {
0% { opacity: 0; }
100% { opacity: 1; }
@@ -751,7 +768,7 @@
.status__action-bar {
align-items: center;
display: flex;
- margin-top: 10px;
+ margin-top: 5px;
}
.status__action-bar-button {
@@ -782,8 +799,9 @@
line-height: 24px;
.emojione {
- width: 22px;
- height: 22px;
+ width: 24px;
+ height: 24px;
+ margin: -5px 0 0;
}
}
@@ -2281,6 +2299,7 @@ button.icon-button.active i.fa-retweet {
}
.column-header {
+ display: flex;
padding: 15px;
font-size: 16px;
background: lighten($ui-base-color, 4%);
@@ -2306,12 +2325,10 @@ button.icon-button.active i.fa-retweet {
}
.column-header__buttons {
- position: absolute;
- right: 0;
- top: 0;
- height: 100%;
- display: flex;
height: 48px;
+ display: flex;
+ margin: -15px;
+ margin-left: 0;
}
.column-header__button {
@@ -2379,6 +2396,14 @@ button.icon-button.active i.fa-retweet {
}
}
+.column-header__title {
+ display: inline-block;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ flex: 1;
+}
+
.text-btn {
display: inline-block;
padding: 0;
@@ -2582,7 +2607,7 @@ button.icon-button.active i.fa-retweet {
color: $primary-text-color;
position: absolute;
top: 10px;
- right: 10px;
+ left: 10px;
opacity: 0.7;
display: inline-block;
vertical-align: top;
@@ -2597,7 +2622,7 @@ button.icon-button.active i.fa-retweet {
.account--action-button {
position: absolute;
top: 10px;
- left: 20px;
+ right: 20px;
}
.setting-toggle {
@@ -3068,7 +3093,6 @@ button.icon-button.active i.fa-retweet {
right: 0;
bottom: 0;
background: rgba($base-overlay-background, 0.7);
- transform: translateZ(0);
}
.modal-root__container {
diff --git a/app/javascript/styles/mastodon/landing_strip.scss b/app/javascript/styles/mastodon/landing_strip.scss
index 15ff849128..0bf9daafd4 100644
--- a/app/javascript/styles/mastodon/landing_strip.scss
+++ b/app/javascript/styles/mastodon/landing_strip.scss
@@ -1,4 +1,5 @@
-.landing-strip {
+.landing-strip,
+.memoriam-strip {
background: rgba(darken($ui-base-color, 7%), 0.8);
color: $ui-primary-color;
font-weight: 400;
@@ -29,3 +30,7 @@
margin-bottom: 0;
}
}
+
+.memoriam-strip {
+ background: rgba($base-shadow-color, 0.7);
+}
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index d6e9bc1def..376684c006 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -53,9 +53,9 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
end
def process_tags(status)
- return unless @object['tag'].is_a?(Array)
+ return if @object['tag'].nil?
- @object['tag'].each do |tag|
+ as_array(@object['tag']).each do |tag|
case tag['type']
when 'Hashtag'
process_hashtag tag, status
@@ -103,9 +103,9 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
end
def process_attachments(status)
- return unless @object['attachment'].is_a?(Array)
+ return if @object['attachment'].nil?
- @object['attachment'].each do |attachment|
+ as_array(@object['attachment']).each do |attachment|
next if unsupported_media_type?(attachment['mediaType']) || attachment['url'].blank?
href = Addressable::URI.parse(attachment['url']).normalize.to_s
diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb
index 57f105da74..733a1c4b71 100644
--- a/app/lib/formatter.rb
+++ b/app/lib/formatter.rb
@@ -89,20 +89,28 @@ class Formatter
end
end
+ def count_tag_nesting(tag)
+ if tag[1] == '/' then -1
+ elsif tag[-2] == '/' then 0
+ else 1
+ end
+ end
+
def encode_custom_emojis(html, emojis)
return html if emojis.empty?
emoji_map = emojis.map { |e| [e.shortcode, full_asset_url(e.image.url(:static))] }.to_h
i = -1
- inside_tag = false
+ tag_open_index = nil
inside_shortname = false
shortname_start_index = -1
+ invisible_depth = 0
while i + 1 < html.size
i += 1
- if inside_shortname && html[i] == ':'
+ if invisible_depth.zero? && inside_shortname && html[i] == ':'
shortcode = html[shortname_start_index + 1..i - 1]
emoji = emoji_map[shortcode]
@@ -116,12 +124,18 @@ class Formatter
end
inside_shortname = false
- elsif inside_tag && html[i] == '>'
- inside_tag = false
+ elsif tag_open_index && html[i] == '>'
+ tag = html[tag_open_index..i]
+ tag_open_index = nil
+ if invisible_depth.positive?
+ invisible_depth += count_tag_nesting(tag)
+ elsif tag == '
'
+ invisible_depth = 1
+ end
elsif html[i] == '<'
- inside_tag = true
+ tag_open_index = i
inside_shortname = false
- elsif !inside_tag && html[i] == ':'
+ elsif !tag_open_index && html[i] == ':'
inside_shortname = true
shortname_start_index = i
end
diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb
index 80c9d8ccfa..d79f26366a 100644
--- a/app/mailers/notification_mailer.rb
+++ b/app/mailers/notification_mailer.rb
@@ -7,6 +7,8 @@ class NotificationMailer < ApplicationMailer
@me = recipient
@status = notification.target_status
+ return if @me.user.disabled?
+
locale_for_account(@me) do
thread_by_conversation(@status.conversation)
mail to: @me.user.email, subject: I18n.t('notification_mailer.mention.subject', name: @status.account.acct)
@@ -17,6 +19,8 @@ class NotificationMailer < ApplicationMailer
@me = recipient
@account = notification.from_account
+ return if @me.user.disabled?
+
locale_for_account(@me) do
mail to: @me.user.email, subject: I18n.t('notification_mailer.follow.subject', name: @account.acct)
end
@@ -27,6 +31,8 @@ class NotificationMailer < ApplicationMailer
@account = notification.from_account
@status = notification.target_status
+ return if @me.user.disabled?
+
locale_for_account(@me) do
thread_by_conversation(@status.conversation)
mail to: @me.user.email, subject: I18n.t('notification_mailer.favourite.subject', name: @account.acct)
@@ -38,6 +44,8 @@ class NotificationMailer < ApplicationMailer
@account = notification.from_account
@status = notification.target_status
+ return if @me.user.disabled?
+
locale_for_account(@me) do
thread_by_conversation(@status.conversation)
mail to: @me.user.email, subject: I18n.t('notification_mailer.reblog.subject', name: @account.acct)
@@ -48,6 +56,8 @@ class NotificationMailer < ApplicationMailer
@me = recipient
@account = notification.from_account
+ return if @me.user.disabled?
+
locale_for_account(@me) do
mail to: @me.user.email, subject: I18n.t('notification_mailer.follow_request.subject', name: @account.acct)
end
@@ -59,15 +69,11 @@ class NotificationMailer < ApplicationMailer
@notifications = Notification.where(account: @me, activity_type: 'Mention').where('created_at > ?', @since)
@follows_since = Notification.where(account: @me, activity_type: 'Follow').where('created_at > ?', @since).count
- return if @notifications.empty?
+ return if @me.user.disabled? || @notifications.empty?
locale_for_account(@me) do
mail to: @me.user.email,
- subject: I18n.t(
- :subject,
- scope: [:notification_mailer, :digest],
- count: @notifications.size
- )
+ subject: I18n.t(:subject, scope: [:notification_mailer, :digest], count: @notifications.size)
end
end
diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb
index c475a9911b..bdb29ebade 100644
--- a/app/mailers/user_mailer.rb
+++ b/app/mailers/user_mailer.rb
@@ -10,6 +10,8 @@ class UserMailer < Devise::Mailer
@token = token
@instance = Rails.configuration.x.local_domain
+ return if @resource.disabled?
+
I18n.with_locale(@resource.locale || I18n.default_locale) do
mail to: @resource.unconfirmed_email.blank? ? @resource.email : @resource.unconfirmed_email, subject: I18n.t('devise.mailer.confirmation_instructions.subject', instance: @instance)
end
@@ -20,6 +22,8 @@ class UserMailer < Devise::Mailer
@token = token
@instance = Rails.configuration.x.local_domain
+ return if @resource.disabled?
+
I18n.with_locale(@resource.locale || I18n.default_locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.reset_password_instructions.subject')
end
@@ -29,6 +33,8 @@ class UserMailer < Devise::Mailer
@resource = user
@instance = Rails.configuration.x.local_domain
+ return if @resource.disabled?
+
I18n.with_locale(@resource.locale || I18n.default_locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.password_change.subject')
end
diff --git a/app/models/account.rb b/app/models/account.rb
index 3dc2a95ab6..6f6010f7af 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -3,7 +3,7 @@
#
# Table name: accounts
#
-# id :integer not null, primary key
+# id :bigint not null, primary key
# username :string default(""), not null
# domain :string
# secret :string default(""), not null
@@ -41,10 +41,11 @@
# shared_inbox_url :string default(""), not null
# followers_url :string default(""), not null
# protocol :integer default("ostatus"), not null
+# memorial :boolean default(FALSE), not null
#
class Account < ApplicationRecord
- MENTION_RE = /(?:^|[^\/[:word:]])@(([a-z0-9_]+)(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
+ MENTION_RE = /(?<=^|[^\/[:word:]])@(([a-z0-9_]+)(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
include AccountAvatar
include AccountFinderConcern
@@ -150,6 +151,20 @@ class Account < ApplicationRecord
ResolveRemoteAccountService.new.call(acct)
end
+ def unsuspend!
+ transaction do
+ user&.enable! if local?
+ update!(suspended: false)
+ end
+ end
+
+ def memorialize!
+ transaction do
+ user&.disable! if local?
+ update!(memorial: true)
+ end
+ end
+
def keypair
@keypair ||= OpenSSL::PKey::RSA.new(private_key || public_key)
end
diff --git a/app/models/account_domain_block.rb b/app/models/account_domain_block.rb
index fb695e473e..9c98ec2a6f 100644
--- a/app/models/account_domain_block.rb
+++ b/app/models/account_domain_block.rb
@@ -6,8 +6,8 @@
# domain :string
# created_at :datetime not null
# updated_at :datetime not null
-# account_id :integer
-# id :integer not null, primary key
+# account_id :bigint
+# id :bigint not null, primary key
#
class AccountDomainBlock < ApplicationRecord
diff --git a/app/models/account_moderation_note.rb b/app/models/account_moderation_note.rb
index 3ac9b1ac14..06f464850c 100644
--- a/app/models/account_moderation_note.rb
+++ b/app/models/account_moderation_note.rb
@@ -3,10 +3,10 @@
#
# Table name: account_moderation_notes
#
-# id :integer not null, primary key
+# id :bigint not null, primary key
# content :text not null
-# account_id :integer not null
-# target_account_id :integer not null
+# account_id :bigint not null
+# target_account_id :bigint not null
# created_at :datetime not null
# updated_at :datetime not null
#
diff --git a/app/models/block.rb b/app/models/block.rb
index a913782edd..5778f7e90b 100644
--- a/app/models/block.rb
+++ b/app/models/block.rb
@@ -5,9 +5,9 @@
#
# created_at :datetime not null
# updated_at :datetime not null
-# account_id :integer not null
-# id :integer not null, primary key
-# target_account_id :integer not null
+# account_id :bigint not null
+# id :bigint not null, primary key
+# target_account_id :bigint not null
#
class Block < ApplicationRecord
diff --git a/app/models/conversation.rb b/app/models/conversation.rb
index 08c1ce9458..e085325225 100644
--- a/app/models/conversation.rb
+++ b/app/models/conversation.rb
@@ -3,7 +3,7 @@
#
# Table name: conversations
#
-# id :integer not null, primary key
+# id :bigint not null, primary key
# uri :string
# created_at :datetime not null
# updated_at :datetime not null
diff --git a/app/models/conversation_mute.rb b/app/models/conversation_mute.rb
index 8d2399adf5..316865bd27 100644
--- a/app/models/conversation_mute.rb
+++ b/app/models/conversation_mute.rb
@@ -3,9 +3,9 @@
#
# Table name: conversation_mutes
#
-# conversation_id :integer not null
-# account_id :integer not null
-# id :integer not null, primary key
+# conversation_id :bigint not null
+# account_id :bigint not null
+# id :bigint not null, primary key
#
class ConversationMute < ApplicationRecord
diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb
index 65d9840d56..5723ebd5db 100644
--- a/app/models/custom_emoji.rb
+++ b/app/models/custom_emoji.rb
@@ -3,7 +3,7 @@
#
# Table name: custom_emojis
#
-# id :integer not null, primary key
+# id :bigint not null, primary key
# shortcode :string default(""), not null
# domain :string
# image_file_name :string
@@ -15,6 +15,7 @@
# disabled :boolean default(FALSE), not null
# uri :string
# image_remote_url :string
+# visible_in_picker :boolean default(TRUE), not null
#
class CustomEmoji < ApplicationRecord
@@ -24,6 +25,8 @@ class CustomEmoji < ApplicationRecord
:(#{SHORTCODE_RE_FRAGMENT}):
(?=[^[:alnum:]:]|$)/x
+ has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode
+
has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce -strip' } }
validates_attachment :image, content_type: { content_type: 'image/png' }, presence: true, size: { in: 0..50.kilobytes }
diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb
index 1268290bc0..557d0a19c7 100644
--- a/app/models/domain_block.rb
+++ b/app/models/domain_block.rb
@@ -8,7 +8,7 @@
# updated_at :datetime not null
# severity :integer default("silence")
# reject_media :boolean default(FALSE), not null
-# id :integer not null, primary key
+# id :bigint not null, primary key
#
class DomainBlock < ApplicationRecord
diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb
index 839038bea6..2c348197cc 100644
--- a/app/models/email_domain_block.rb
+++ b/app/models/email_domain_block.rb
@@ -3,15 +3,34 @@
#
# Table name: email_domain_blocks
#
-# id :integer not null, primary key
-# domain :string not null
+# id :bigint not null, primary key
+# domain :string default(""), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class EmailDomainBlock < ApplicationRecord
+ before_validation :normalize_domain
+
+ validates :domain, presence: true, uniqueness: true
+
def self.block?(email)
- domain = email.gsub(/.+@([^.]+)/, '\1')
+ _, domain = email.split('@', 2)
+
+ return true if domain.nil?
+
+ begin
+ domain = TagManager.instance.normalize_domain(domain)
+ rescue Addressable::URI::InvalidURIError
+ return true
+ end
+
where(domain: domain).exists?
end
+
+ private
+
+ def normalize_domain
+ self.domain = TagManager.instance.normalize_domain(domain)
+ end
end
diff --git a/app/models/favourite.rb b/app/models/favourite.rb
index d28d5c05b9..f611aa6a99 100644
--- a/app/models/favourite.rb
+++ b/app/models/favourite.rb
@@ -5,9 +5,9 @@
#
# created_at :datetime not null
# updated_at :datetime not null
-# account_id :integer not null
-# id :integer not null, primary key
-# status_id :integer not null
+# account_id :bigint not null
+# id :bigint not null, primary key
+# status_id :bigint not null
#
class Favourite < ApplicationRecord
diff --git a/app/models/follow.rb b/app/models/follow.rb
index 667720a88f..3d5447fb1f 100644
--- a/app/models/follow.rb
+++ b/app/models/follow.rb
@@ -5,9 +5,9 @@
#
# created_at :datetime not null
# updated_at :datetime not null
-# account_id :integer not null
-# id :integer not null, primary key
-# target_account_id :integer not null
+# account_id :bigint not null
+# id :bigint not null, primary key
+# target_account_id :bigint not null
#
class Follow < ApplicationRecord
diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb
index 60036d9030..ce27fc9214 100644
--- a/app/models/follow_request.rb
+++ b/app/models/follow_request.rb
@@ -5,9 +5,9 @@
#
# created_at :datetime not null
# updated_at :datetime not null
-# account_id :integer not null
-# id :integer not null, primary key
-# target_account_id :integer not null
+# account_id :bigint not null
+# id :bigint not null, primary key
+# target_account_id :bigint not null
#
class FollowRequest < ApplicationRecord
@@ -27,7 +27,5 @@ class FollowRequest < ApplicationRecord
destroy!
end
- def reject!
- destroy!
- end
+ alias reject! destroy!
end
diff --git a/app/models/import.rb b/app/models/import.rb
index 8ae7e3a46f..6f12785566 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -11,8 +11,8 @@
# data_content_type :string
# data_file_size :integer
# data_updated_at :datetime
-# account_id :integer not null
-# id :integer not null, primary key
+# account_id :bigint not null
+# id :bigint not null, primary key
#
class Import < ApplicationRecord
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index 60380198b3..f054189255 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -3,14 +3,14 @@
#
# Table name: media_attachments
#
-# id :integer not null, primary key
-# status_id :integer
+# id :bigint not null, primary key
+# status_id :bigint
# file_file_name :string
# file_content_type :string
# file_file_size :integer
# file_updated_at :datetime
# remote_url :string default(""), not null
-# account_id :integer
+# account_id :bigint
# created_at :datetime not null
# updated_at :datetime not null
# shortcode :string
diff --git a/app/models/mention.rb b/app/models/mention.rb
index 3700c781c8..fc089d3659 100644
--- a/app/models/mention.rb
+++ b/app/models/mention.rb
@@ -3,11 +3,11 @@
#
# Table name: mentions
#
-# status_id :integer
+# status_id :bigint
# created_at :datetime not null
# updated_at :datetime not null
-# account_id :integer
-# id :integer not null, primary key
+# account_id :bigint
+# id :bigint not null, primary key
#
class Mention < ApplicationRecord
diff --git a/app/models/notification.rb b/app/models/notification.rb
index 0a5d987cfe..c88af9021b 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -3,13 +3,13 @@
#
# Table name: notifications
#
-# id :integer not null, primary key
-# account_id :integer
-# activity_id :integer
+# id :bigint not null, primary key
+# account_id :bigint
+# activity_id :bigint
# activity_type :string
# created_at :datetime not null
# updated_at :datetime not null
-# from_account_id :integer
+# from_account_id :bigint
#
class Notification < ApplicationRecord
diff --git a/app/models/preview_card.rb b/app/models/preview_card.rb
index e2bf65d947..63c04b410e 100644
--- a/app/models/preview_card.rb
+++ b/app/models/preview_card.rb
@@ -3,7 +3,7 @@
#
# Table name: preview_cards
#
-# id :integer not null, primary key
+# id :bigint not null, primary key
# url :string default(""), not null
# title :string default(""), not null
# description :string default(""), not null
diff --git a/app/models/report.rb b/app/models/report.rb
index bffb42b481..99c90b7dd2 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -8,10 +8,10 @@
# action_taken :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
-# account_id :integer not null
-# action_taken_by_account_id :integer
-# id :integer not null, primary key
-# target_account_id :integer not null
+# account_id :bigint not null
+# action_taken_by_account_id :bigint
+# id :bigint not null, primary key
+# target_account_id :bigint not null
#
class Report < ApplicationRecord
diff --git a/app/models/session_activation.rb b/app/models/session_activation.rb
index c1645223bd..59565f8775 100644
--- a/app/models/session_activation.rb
+++ b/app/models/session_activation.rb
@@ -3,25 +3,25 @@
#
# Table name: session_activations
#
-# id :integer not null, primary key
-# user_id :integer not null
+# id :bigint not null, primary key
+# user_id :bigint not null
# session_id :string not null
# created_at :datetime not null
# updated_at :datetime not null
# user_agent :string default(""), not null
# ip :inet
-# access_token_id :integer
-# web_push_subscription_id :integer
+# access_token_id :bigint
+# web_push_subscription_id :bigint
#
-# id :integer not null, primary key
-# user_id :integer not null
+# id :bigint not null, primary key
+# user_id :bigint not null
# session_id :string not null
# created_at :datetime not null
# updated_at :datetime not null
# user_agent :string default(""), not null
# ip :inet
-# access_token_id :integer
+# access_token_id :bigint
#
class SessionActivation < ApplicationRecord
diff --git a/app/models/setting.rb b/app/models/setting.rb
index a14f156a1e..be68d3123b 100644
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -8,8 +8,8 @@
# thing_type :string
# created_at :datetime
# updated_at :datetime
-# id :integer not null, primary key
-# thing_id :integer
+# id :bigint not null, primary key
+# thing_id :bigint
#
class Setting < RailsSettings::Base
diff --git a/app/models/site_upload.rb b/app/models/site_upload.rb
index 8ffdc83131..ba2ca777b8 100644
--- a/app/models/site_upload.rb
+++ b/app/models/site_upload.rb
@@ -3,7 +3,7 @@
#
# Table name: site_uploads
#
-# id :integer not null, primary key
+# id :bigint not null, primary key
# var :string default(""), not null
# file_file_name :string
# file_content_type :string
diff --git a/app/models/status.rb b/app/models/status.rb
index 5a72456135..b4f3143117 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -3,25 +3,25 @@
#
# Table name: statuses
#
-# id :integer not null, primary key
+# id :bigint not null, primary key
# uri :string
-# account_id :integer not null
+# account_id :bigint not null
# text :text default(""), not null
# created_at :datetime not null
# updated_at :datetime not null
-# in_reply_to_id :integer
-# reblog_of_id :integer
+# in_reply_to_id :bigint
+# reblog_of_id :bigint
# url :string
# sensitive :boolean default(FALSE), not null
# visibility :integer default("public"), not null
-# in_reply_to_account_id :integer
-# application_id :integer
+# in_reply_to_account_id :bigint
+# application_id :bigint
# spoiler_text :text default(""), not null
# reply :boolean default(FALSE), not null
# favourites_count :integer default(0), not null
# reblogs_count :integer default(0), not null
# language :string
-# conversation_id :integer
+# conversation_id :bigint
# local :boolean
#
diff --git a/app/models/status_pin.rb b/app/models/status_pin.rb
index a72c19750e..5795d07bf9 100644
--- a/app/models/status_pin.rb
+++ b/app/models/status_pin.rb
@@ -3,9 +3,9 @@
#
# Table name: status_pins
#
-# id :integer not null, primary key
-# account_id :integer not null
-# status_id :integer not null
+# id :bigint not null, primary key
+# account_id :bigint not null
+# status_id :bigint not null
# created_at :datetime not null
# updated_at :datetime not null
#
diff --git a/app/models/stream_entry.rb b/app/models/stream_entry.rb
index b51fe9ad76..50b900c3cb 100644
--- a/app/models/stream_entry.rb
+++ b/app/models/stream_entry.rb
@@ -3,13 +3,13 @@
#
# Table name: stream_entries
#
-# activity_id :integer
+# activity_id :bigint
# activity_type :string
# created_at :datetime not null
# updated_at :datetime not null
# hidden :boolean default(FALSE), not null
-# account_id :integer
-# id :integer not null, primary key
+# account_id :bigint
+# id :bigint not null, primary key
#
class StreamEntry < ApplicationRecord
diff --git a/app/models/subscription.rb b/app/models/subscription.rb
index 39860196b2..bc50c53176 100644
--- a/app/models/subscription.rb
+++ b/app/models/subscription.rb
@@ -11,8 +11,8 @@
# updated_at :datetime not null
# last_successful_delivery_at :datetime
# domain :string
-# account_id :integer not null
-# id :integer not null, primary key
+# account_id :bigint not null
+# id :bigint not null, primary key
#
class Subscription < ApplicationRecord
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 0fa08e157c..6ebaf11459 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -3,7 +3,7 @@
#
# Table name: tags
#
-# id :integer not null, primary key
+# id :bigint not null, primary key
# name :string default(""), not null
# created_at :datetime not null
# updated_at :datetime not null
diff --git a/app/models/user.rb b/app/models/user.rb
index 325e27f441..ebe768c523 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -3,9 +3,8 @@
#
# Table name: users
#
-# id :integer not null, primary key
+# id :bigint not null, primary key
# email :string default(""), not null
-# account_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
# encrypted_password :string default(""), not null
@@ -31,10 +30,14 @@
# last_emailed_at :datetime
# otp_backup_codes :string is an Array
# filtered_languages :string default([]), not null, is an Array
+# account_id :bigint not null
+# disabled :boolean default(FALSE), not null
+# moderator :boolean default(FALSE), not null
#
class User < ApplicationRecord
include Settings::Extend
+
ACTIVE_DURATION = 14.days
devise :registerable, :recoverable,
@@ -51,8 +54,10 @@ class User < ApplicationRecord
validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale?
validates_with BlacklistedEmailValidator, if: :email_changed?
- scope :recent, -> { order(id: :desc) }
- scope :admins, -> { where(admin: true) }
+ scope :recent, -> { order(id: :desc) }
+ scope :admins, -> { where(admin: true) }
+ scope :moderators, -> { where(moderator: true) }
+ scope :staff, -> { admins.or(moderators) }
scope :confirmed, -> { where.not(confirmed_at: nil) }
scope :inactive, -> { where(arel_table[:current_sign_in_at].lt(ACTIVE_DURATION.ago)) }
scope :active, -> { confirmed.where(arel_table[:current_sign_in_at].gteq(ACTIVE_DURATION.ago)).joins(:account).where(accounts: { suspended: false }) }
@@ -72,12 +77,61 @@ class User < ApplicationRecord
confirmed_at.present?
end
+ def staff?
+ admin? || moderator?
+ end
+
+ def role
+ if admin?
+ 'admin'
+ elsif moderator?
+ 'moderator'
+ else
+ 'user'
+ end
+ end
+
+ def disable!
+ update!(disabled: true,
+ last_sign_in_at: current_sign_in_at,
+ current_sign_in_at: nil)
+ end
+
+ def enable!
+ update!(disabled: false)
+ end
+
+ def confirm!
+ skip_confirmation!
+ save!
+ end
+
+ def promote!
+ if moderator?
+ update!(moderator: false, admin: true)
+ elsif !admin?
+ update!(moderator: true)
+ end
+ end
+
+ def demote!
+ if admin?
+ update!(admin: false, moderator: true)
+ elsif moderator?
+ update!(moderator: false)
+ end
+ end
+
def disable_two_factor!
self.otp_required_for_login = false
otp_backup_codes&.clear
save!
end
+ def active_for_authentication?
+ super && !disabled?
+ end
+
def setting_default_privacy
settings.default_privacy || (account.locked? ? 'private' : 'public')
end
diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb
index cb15dfa370..da67e76653 100644
--- a/app/models/web/push_subscription.rb
+++ b/app/models/web/push_subscription.rb
@@ -3,7 +3,7 @@
#
# Table name: web_push_subscriptions
#
-# id :integer not null, primary key
+# id :bigint not null, primary key
# endpoint :string not null
# key_p256dh :string not null
# key_auth :string not null
diff --git a/app/models/web/setting.rb b/app/models/web/setting.rb
index 1b0bfb2b7b..6d08c4d355 100644
--- a/app/models/web/setting.rb
+++ b/app/models/web/setting.rb
@@ -6,8 +6,8 @@
# data :json
# created_at :datetime not null
# updated_at :datetime not null
-# id :integer not null, primary key
-# user_id :integer
+# id :bigint not null, primary key
+# user_id :bigint
#
class Web::Setting < ApplicationRecord
diff --git a/app/policies/account_moderation_note_policy.rb b/app/policies/account_moderation_note_policy.rb
new file mode 100644
index 0000000000..885411a5b5
--- /dev/null
+++ b/app/policies/account_moderation_note_policy.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AccountModerationNotePolicy < ApplicationPolicy
+ def create?
+ staff?
+ end
+
+ def destroy?
+ admin? || owner?
+ end
+
+ private
+
+ def owner?
+ record.account_id == current_account&.id
+ end
+end
diff --git a/app/policies/account_policy.rb b/app/policies/account_policy.rb
new file mode 100644
index 0000000000..85e2c84199
--- /dev/null
+++ b/app/policies/account_policy.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+class AccountPolicy < ApplicationPolicy
+ def index?
+ staff?
+ end
+
+ def show?
+ staff?
+ end
+
+ def suspend?
+ staff? && !record.user&.staff?
+ end
+
+ def unsuspend?
+ staff?
+ end
+
+ def silence?
+ staff? && !record.user&.staff?
+ end
+
+ def unsilence?
+ staff?
+ end
+
+ def redownload?
+ admin?
+ end
+
+ def subscribe?
+ admin?
+ end
+
+ def unsubscribe?
+ admin?
+ end
+
+ def memorialize?
+ admin? && !record.user&.admin?
+ end
+end
diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb
new file mode 100644
index 0000000000..3e617001fa
--- /dev/null
+++ b/app/policies/application_policy.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class ApplicationPolicy
+ attr_reader :current_account, :record
+
+ def initialize(current_account, record)
+ @current_account = current_account
+ @record = record
+ end
+
+ delegate :admin?, :moderator?, :staff?, to: :current_user, allow_nil: true
+
+ private
+
+ def current_user
+ current_account&.user
+ end
+end
diff --git a/app/policies/custom_emoji_policy.rb b/app/policies/custom_emoji_policy.rb
new file mode 100644
index 0000000000..a8c3cbc733
--- /dev/null
+++ b/app/policies/custom_emoji_policy.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+class CustomEmojiPolicy < ApplicationPolicy
+ def index?
+ staff?
+ end
+
+ def create?
+ admin?
+ end
+
+ def update?
+ admin?
+ end
+
+ def copy?
+ admin?
+ end
+
+ def enable?
+ staff?
+ end
+
+ def disable?
+ staff?
+ end
+
+ def destroy?
+ admin?
+ end
+end
diff --git a/app/policies/domain_block_policy.rb b/app/policies/domain_block_policy.rb
new file mode 100644
index 0000000000..47c0a81af4
--- /dev/null
+++ b/app/policies/domain_block_policy.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class DomainBlockPolicy < ApplicationPolicy
+ def index?
+ admin?
+ end
+
+ def show?
+ admin?
+ end
+
+ def create?
+ admin?
+ end
+
+ def destroy?
+ admin?
+ end
+end
diff --git a/app/policies/email_domain_block_policy.rb b/app/policies/email_domain_block_policy.rb
new file mode 100644
index 0000000000..5a75ee1838
--- /dev/null
+++ b/app/policies/email_domain_block_policy.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class EmailDomainBlockPolicy < ApplicationPolicy
+ def index?
+ admin?
+ end
+
+ def create?
+ admin?
+ end
+
+ def destroy?
+ admin?
+ end
+end
diff --git a/app/policies/instance_policy.rb b/app/policies/instance_policy.rb
new file mode 100644
index 0000000000..d1956e2ded
--- /dev/null
+++ b/app/policies/instance_policy.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class InstancePolicy < ApplicationPolicy
+ def index?
+ admin?
+ end
+
+ def resubscribe?
+ admin?
+ end
+end
diff --git a/app/policies/report_policy.rb b/app/policies/report_policy.rb
new file mode 100644
index 0000000000..95b5c30c88
--- /dev/null
+++ b/app/policies/report_policy.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class ReportPolicy < ApplicationPolicy
+ def update?
+ staff?
+ end
+
+ def index?
+ staff?
+ end
+
+ def show?
+ staff?
+ end
+end
diff --git a/app/policies/settings_policy.rb b/app/policies/settings_policy.rb
new file mode 100644
index 0000000000..2dcb79f51f
--- /dev/null
+++ b/app/policies/settings_policy.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class SettingsPolicy < ApplicationPolicy
+ def update?
+ admin?
+ end
+
+ def show?
+ admin?
+ end
+end
diff --git a/app/policies/status_policy.rb b/app/policies/status_policy.rb
index 2ded61850a..0373fdf04f 100644
--- a/app/policies/status_policy.rb
+++ b/app/policies/status_policy.rb
@@ -1,20 +1,17 @@
# frozen_string_literal: true
-class StatusPolicy
- attr_reader :account, :status
-
- def initialize(account, status)
- @account = account
- @status = status
+class StatusPolicy < ApplicationPolicy
+ def index?
+ staff?
end
def show?
if direct?
- owned? || status.mentions.where(account: account).exists?
+ owned? || record.mentions.where(account: current_account).exists?
elsif private?
- owned? || account&.following?(status.account) || status.mentions.where(account: account).exists?
+ owned? || current_account&.following?(author) || record.mentions.where(account: current_account).exists?
else
- account.nil? || !status.account.blocking?(account)
+ current_account.nil? || !author.blocking?(current_account)
end
end
@@ -23,26 +20,30 @@ class StatusPolicy
end
def destroy?
- admin? || owned?
+ staff? || owned?
end
alias unreblog? destroy?
- private
-
- def admin?
- account&.user&.admin?
+ def update?
+ staff?
end
+ private
+
def direct?
- status.direct_visibility?
+ record.direct_visibility?
end
def owned?
- status.account.id == account&.id
+ author.id == current_account&.id
end
def private?
- status.private_visibility?
+ record.private_visibility?
+ end
+
+ def author
+ record.account
end
end
diff --git a/app/policies/subscription_policy.rb b/app/policies/subscription_policy.rb
new file mode 100644
index 0000000000..ac9a8a6c44
--- /dev/null
+++ b/app/policies/subscription_policy.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class SubscriptionPolicy < ApplicationPolicy
+ def index?
+ admin?
+ end
+end
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
new file mode 100644
index 0000000000..aae207d06f
--- /dev/null
+++ b/app/policies/user_policy.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+class UserPolicy < ApplicationPolicy
+ def reset_password?
+ staff? && !record.staff?
+ end
+
+ def disable_2fa?
+ admin? && !record.staff?
+ end
+
+ def confirm?
+ staff? && !record.confirmed?
+ end
+
+ def enable?
+ admin?
+ end
+
+ def disable?
+ admin? && !record.admin?
+ end
+
+ def promote?
+ admin? && promoteable?
+ end
+
+ def demote?
+ admin? && !record.admin? && demoteable?
+ end
+
+ private
+
+ def promoteable?
+ !record.staff? || !record.admin?
+ end
+
+ def demoteable?
+ record.staff?
+ end
+end
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index a8db731617..4fa1981ed4 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -7,7 +7,7 @@ class InitialStateSerializer < ActiveModel::Serializer
has_many :custom_emojis, serializer: REST::CustomEmojiSerializer
def custom_emojis
- CustomEmoji.local
+ CustomEmoji.local.where(disabled: false)
end
def meta
diff --git a/app/serializers/rest/custom_emoji_serializer.rb b/app/serializers/rest/custom_emoji_serializer.rb
index b958e6a5db..65686a8666 100644
--- a/app/serializers/rest/custom_emoji_serializer.rb
+++ b/app/serializers/rest/custom_emoji_serializer.rb
@@ -3,7 +3,7 @@
class REST::CustomEmojiSerializer < ActiveModel::Serializer
include RoutingHelper
- attributes :shortcode, :url, :static_url
+ attributes :shortcode, :url, :static_url, :visible_in_picker
def url
full_asset_url(object.image.url)
diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb
index e2a89a87c8..8d7b7a17ce 100644
--- a/app/services/activitypub/fetch_remote_status_service.rb
+++ b/app/services/activitypub/fetch_remote_status_service.rb
@@ -16,7 +16,7 @@ class ActivityPub::FetchRemoteStatusService < BaseService
return if actor_id.nil? || !trustworthy_attribution?(@json['id'], actor_id)
actor = ActivityPub::TagManager.instance.uri_to_resource(actor_id, Account)
- actor = ActivityPub::FetchRemoteAccountService.new.call(actor_id, id: true) if actor.nil?
+ actor = ActivityPub::FetchRemoteAccountService.new.call(actor_id, id: true) if actor.nil? || needs_update(actor)
return if actor.suspended?
@@ -44,4 +44,8 @@ class ActivityPub::FetchRemoteStatusService < BaseService
def expected_type?
%w(Note Article).include? @json['type']
end
+
+ def needs_update(actor)
+ actor.possibly_stale?
+ end
end
diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb
index fb09df983f..8a77f2f38a 100644
--- a/app/services/notify_service.rb
+++ b/app/services/notify_service.rb
@@ -36,17 +36,58 @@ class NotifyService < BaseService
false
end
+ def following_sender?
+ return @following_sender if defined?(@following_sender)
+ @following_sender = @recipient.following?(@notification.from_account) || @recipient.requested?(@notification.from_account)
+ end
+
+ def optional_non_follower?
+ @recipient.user.settings.interactions['must_be_follower'] && !@notification.from_account.following?(@recipient)
+ end
+
+ def optional_non_following?
+ @recipient.user.settings.interactions['must_be_following'] && !following_sender?
+ end
+
+ def direct_message?
+ @notification.type == :mention && @notification.target_status.direct_visibility?
+ end
+
+ def response_to_recipient?
+ @notification.target_status.in_reply_to_account_id == @recipient.id
+ end
+
+ def optional_non_following_and_direct?
+ direct_message? &&
+ @recipient.user.settings.interactions['must_be_following_dm'] &&
+ !following_sender? &&
+ !response_to_recipient?
+ end
+
+ def hellbanned?
+ @notification.from_account.silenced? && !following_sender?
+ end
+
+ def from_self?
+ @recipient.id == @notification.from_account.id
+ end
+
+ def domain_blocking?
+ @recipient.domain_blocking?(@notification.from_account.domain) && !following_sender?
+ end
+
def blocked?
- blocked = @recipient.suspended? # Skip if the recipient account is suspended anyway
- blocked ||= @recipient.id == @notification.from_account.id # Skip for interactions with self
- blocked ||= @recipient.domain_blocking?(@notification.from_account.domain) && !@recipient.following?(@notification.from_account) # Skip for domain blocked accounts
- blocked ||= @recipient.blocking?(@notification.from_account) # Skip for blocked accounts
+ blocked = @recipient.suspended? # Skip if the recipient account is suspended anyway
+ blocked ||= from_self? # Skip for interactions with self
+ blocked ||= domain_blocking? # Skip for domain blocked accounts
+ blocked ||= @recipient.blocking?(@notification.from_account) # Skip for blocked accounts
blocked ||= @recipient.muting_notifications?(@notification.from_account)
- blocked ||= (@notification.from_account.silenced? && !@recipient.following?(@notification.from_account)) # Hellban
- blocked ||= (@recipient.user.settings.interactions['must_be_follower'] && !@notification.from_account.following?(@recipient)) # Options
- blocked ||= (@recipient.user.settings.interactions['must_be_following'] && !@recipient.following?(@notification.from_account)) # Options
+ blocked ||= hellbanned? # Hellban
+ blocked ||= optional_non_follower? # Options
+ blocked ||= optional_non_following? # Options
+ blocked ||= optional_non_following_and_direct? # Options
blocked ||= conversation_muted?
- blocked ||= send("blocked_#{@notification.type}?") # Type-dependent filters
+ blocked ||= send("blocked_#{@notification.type}?") # Type-dependent filters
blocked
end
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index e37cd94df4..de350f8e6f 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -70,11 +70,11 @@ class PostStatusService < BaseService
end
def process_mentions_service
- @process_mentions_service ||= ProcessMentionsService.new
+ ProcessMentionsService.new
end
def process_hashtags_service
- @process_hashtags_service ||= ProcessHashtagsService.new
+ ProcessHashtagsService.new
end
def redis
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index 1c3eea3697..a229d4ff86 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -10,23 +10,26 @@ class ProcessMentionsService < BaseService
def call(status)
return unless status.local?
- status.text.scan(Account::MENTION_RE).each do |match|
- username, domain = match.first.split('@')
- mentioned_account = Account.find_remote(username, domain)
-
- if mentioned_account.nil? && !domain.nil?
- begin
- mentioned_account = follow_remote_account_service.call(match.first.to_s)
- rescue Goldfinger::Error, HTTP::Error
- mentioned_account = nil
- end
+ status.text = status.text.gsub(Account::MENTION_RE) do |match|
+ begin
+ mentioned_account = resolve_remote_account_service.call($1)
+ rescue Goldfinger::Error, HTTP::Error
+ mentioned_account = nil
end
- next if mentioned_account.nil?
+ if mentioned_account.nil?
+ username, domain = match.first.split('@')
+ mentioned_account = Account.find_remote(username, domain)
+ end
+
+ next match if mentioned_account.nil? || (!mentioned_account.local? && mentioned_account.ostatus? && status.stream_entry.hidden?)
mentioned_account.mentions.where(status: status).first_or_create(status: status)
+ "@#{mentioned_account.acct}"
end
+ status.save!
+
status.mentions.includes(:account).each do |mention|
create_notification(status, mention)
end
@@ -54,7 +57,7 @@ class ProcessMentionsService < BaseService
).as_json).sign!(status.account))
end
- def follow_remote_account_service
- @follow_remote_account_service ||= ResolveRemoteAccountService.new
+ def resolve_remote_account_service
+ ResolveRemoteAccountService.new
end
end
diff --git a/app/services/suspend_account_service.rb b/app/services/suspend_account_service.rb
index 983c5495b6..5b37ba9ba7 100644
--- a/app/services/suspend_account_service.rb
+++ b/app/services/suspend_account_service.rb
@@ -1,22 +1,27 @@
# frozen_string_literal: true
class SuspendAccountService < BaseService
- def call(account, remove_user = false)
+ def call(account, options = {})
@account = account
+ @options = options
- purge_user if remove_user
- purge_profile
- purge_content
- unsubscribe_push_subscribers
+ purge_user!
+ purge_profile!
+ purge_content!
+ unsubscribe_push_subscribers!
end
private
- def purge_user
- @account.user.destroy
+ def purge_user!
+ if @options[:remove_user]
+ @account.user&.destroy
+ else
+ @account.user&.disable!
+ end
end
- def purge_content
+ def purge_content!
@account.statuses.reorder(nil).find_in_batches do |statuses|
BatchedRemoveStatusService.new.call(statuses)
end
@@ -33,7 +38,7 @@ class SuspendAccountService < BaseService
end
end
- def purge_profile
+ def purge_profile!
@account.suspended = true
@account.display_name = ''
@account.note = ''
@@ -42,7 +47,7 @@ class SuspendAccountService < BaseService
@account.save!
end
- def unsubscribe_push_subscribers
+ def unsubscribe_push_subscribers!
destroy_all(@account.subscriptions)
end
diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml
index 08c3891d27..5530fcc200 100644
--- a/app/views/accounts/_header.html.haml
+++ b/app/views/accounts/_header.html.haml
@@ -1,21 +1,22 @@
.card.h-card.p-author{ style: "background-image: url(#{account.header.url(:original)})" }
.card__illustration
- - if user_signed_in? && current_account.id != account.id && !current_account.requested?(account)
- .controls
- - if current_account.following?(account)
- = link_to account_unfollow_path(account), data: { method: :post }, class: 'icon-button' do
- = fa_icon 'user-times'
- = t('accounts.unfollow')
- - else
- = link_to account_follow_path(account), data: { method: :post }, class: 'icon-button' do
- = fa_icon 'user-plus'
- = t('accounts.follow')
- - elsif !user_signed_in?
- .controls
- .remote-follow
- = link_to account_remote_follow_path(account), class: 'icon-button' do
- = fa_icon 'user-plus'
- = t('accounts.remote_follow')
+ - unless account.memorial?
+ - if user_signed_in? && current_account.id != account.id && !current_account.requested?(account)
+ .controls
+ - if current_account.following?(account)
+ = link_to account_unfollow_path(account), data: { method: :post }, class: 'icon-button' do
+ = fa_icon 'user-times'
+ = t('accounts.unfollow')
+ - else
+ = link_to account_follow_path(account), data: { method: :post }, class: 'icon-button' do
+ = fa_icon 'user-plus'
+ = t('accounts.follow')
+ - elsif !user_signed_in?
+ .controls
+ .remote-follow
+ = link_to account_remote_follow_path(account), class: 'icon-button' do
+ = fa_icon 'user-plus'
+ = t('accounts.remote_follow')
.avatar= image_tag account.avatar.url(:original), class: 'u-photo'
diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml
index 6c90b2c04f..fd8ad5530b 100644
--- a/app/views/accounts/show.html.haml
+++ b/app/views/accounts/show.html.haml
@@ -12,7 +12,9 @@
= opengraph 'og:type', 'profile'
= render 'og', account: @account, url: short_account_url(@account, only_path: false)
-- if show_landing_strip?
+- if @account.memorial?
+ .memoriam-strip= t('in_memoriam_html')
+- elsif show_landing_strip?
= render partial: 'shared/landing_strip', locals: { account: @account }
.h-feed
diff --git a/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml b/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml
index 4651630e95..6761a43192 100644
--- a/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml
+++ b/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml
@@ -7,4 +7,4 @@
%time.formatted{ datetime: account_moderation_note.created_at.iso8601, title: l(account_moderation_note.created_at) }
= l account_moderation_note.created_at
%td
- = link_to t('admin.account_moderation_notes.delete'), admin_account_moderation_note_path(account_moderation_note), method: :delete
+ = link_to t('admin.account_moderation_notes.delete'), admin_account_moderation_note_path(account_moderation_note), method: :delete if can?(:destroy, account_moderation_note)
diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml
index 1b56a3a316..27a0682d8b 100644
--- a/app/views/admin/accounts/index.html.haml
+++ b/app/views/admin/accounts/index.html.haml
@@ -42,7 +42,7 @@
- if params[key].present?
= hidden_field_tag key, params[key]
- - %i(username display_name email ip).each do |key|
+ - %i(username by_domain display_name email ip).each do |key|
.input.string.optional
= text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.accounts.#{key}")
diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml
index 1f5c8fcf53..f495948281 100644
--- a/app/views/admin/accounts/show.html.haml
+++ b/app/views/admin/accounts/show.html.haml
@@ -17,7 +17,20 @@
- if @account.local?
%tr
%th= t('admin.accounts.email')
- %td= @account.user_email
+ %td
+ = @account.user_email
+
+ - if @account.user_confirmed?
+ = fa_icon('check')
+ %tr
+ %th= t('admin.accounts.login_status')
+ %td
+ - if @account.user&.disabled?
+ = t('admin.accounts.disabled')
+ = table_link_to 'unlock', t('admin.accounts.enable'), enable_admin_account_path(@account.id), method: :post if can?(:enable, @account.user)
+ - else
+ = t('admin.accounts.enabled')
+ = table_link_to 'lock', t('admin.accounts.disable'), disable_admin_account_path(@account.id), method: :post if can?(:disable, @account.user)
%tr
%th= t('admin.accounts.most_recent_ip')
%td= @account.user_current_sign_in_ip
@@ -62,26 +75,28 @@
%div{ style: 'overflow: hidden' }
%div{ style: 'float: right' }
- if @account.local?
- = link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button'
+ = link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button' if can?(:reset_password, @account.user)
- if @account.user&.otp_required_for_login?
- = link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button'
+ = link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button' if can?(:disable_2fa, @account.user)
+ - unless @account.memorial?
+ = link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:memorialize, @account)
- else
- = link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button'
+ = link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button' if can?(:redownload, @account)
%div{ style: 'float: left' }
- if @account.silenced?
- = link_to t('admin.accounts.undo_silenced'), admin_account_silence_path(@account.id), method: :delete, class: 'button'
+ = link_to t('admin.accounts.undo_silenced'), admin_account_silence_path(@account.id), method: :delete, class: 'button' if can?(:unsilence, @account)
- else
- = link_to t('admin.accounts.silence'), admin_account_silence_path(@account.id), method: :post, class: 'button'
+ = link_to t('admin.accounts.silence'), admin_account_silence_path(@account.id), method: :post, class: 'button' if can?(:silence, @account)
- if @account.local?
- unless @account.user_confirmed?
- = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(@account.id), method: :post, class: 'button'
+ = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(@account.id), method: :post, class: 'button' if can?(:confirm, @account.user)
- if @account.suspended?
- = link_to t('admin.accounts.undo_suspension'), admin_account_suspension_path(@account.id), method: :delete, class: 'button'
+ = link_to t('admin.accounts.undo_suspension'), admin_account_suspension_path(@account.id), method: :delete, class: 'button' if can?(:unsuspend, @account)
- else
- = link_to t('admin.accounts.perform_full_suspension'), admin_account_suspension_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button'
+ = link_to t('admin.accounts.perform_full_suspension'), admin_account_suspension_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:suspend, @account)
- unless @account.local?
%hr
@@ -107,9 +122,9 @@
%div{ style: 'overflow: hidden' }
%div{ style: 'float: right' }
- = link_to @account.subscribed? ? t('admin.accounts.resubscribe') : t('admin.accounts.subscribe'), subscribe_admin_account_path(@account.id), method: :post, class: 'button'
+ = link_to @account.subscribed? ? t('admin.accounts.resubscribe') : t('admin.accounts.subscribe'), subscribe_admin_account_path(@account.id), method: :post, class: 'button' if can?(:subscribe, @account)
- if @account.subscribed?
- = link_to t('admin.accounts.unsubscribe'), unsubscribe_admin_account_path(@account.id), method: :post, class: 'button negative'
+ = link_to t('admin.accounts.unsubscribe'), unsubscribe_admin_account_path(@account.id), method: :post, class: 'button negative' if can?(:unsubscribe, @account)
%hr
%h3 ActivityPub
@@ -130,6 +145,20 @@
%th= t('admin.accounts.followers_url')
%td= link_to @account.followers_url, @account.followers_url
+- else
+ %hr
+
+ .table-wrapper
+ %table.table
+ %tbody
+ %tr
+ %th= t('admin.accounts.role')
+ %td
+ = t("admin.accounts.roles.#{@account.user&.role}")
+ %td<
+ = table_link_to 'angle-double-up', t('admin.accounts.promote'), promote_admin_account_role_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:promote, @account.user)
+ = table_link_to 'angle-double-down', t('admin.accounts.demote'), demote_admin_account_role_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:demote, @account.user)
+
%hr
%h3= t('admin.accounts.moderation_notes')
diff --git a/app/views/admin/custom_emojis/_custom_emoji.html.haml b/app/views/admin/custom_emojis/_custom_emoji.html.haml
index 1fa64908c0..bab34bc8d7 100644
--- a/app/views/admin/custom_emojis/_custom_emoji.html.haml
+++ b/app/views/admin/custom_emojis/_custom_emoji.html.haml
@@ -1,6 +1,6 @@
%tr
%td
- = image_tag custom_emoji.image.url, class: 'emojione', alt: ":#{custom_emoji.shortcode}:"
+ = custom_emoji_tag(custom_emoji)
%td
%samp= ":#{custom_emoji.shortcode}:"
%td
@@ -9,8 +9,16 @@
- else
= custom_emoji.domain
%td
- - unless custom_emoji.local?
- = table_link_to 'copy', t('admin.custom_emojis.copy'), copy_admin_custom_emoji_path(custom_emoji, page: params[:page]), method: :post
+ - if custom_emoji.local?
+ - if custom_emoji.visible_in_picker
+ = table_link_to 'eye', t('admin.custom_emojis.listed'), admin_custom_emoji_path(custom_emoji, custom_emoji: { visible_in_picker: false }), method: :patch
+ - else
+ = table_link_to 'eye-slash', t('admin.custom_emojis.unlisted'), admin_custom_emoji_path(custom_emoji, custom_emoji: { visible_in_picker: true }), method: :patch
+ - else
+ - if custom_emoji.local_counterpart.present?
+ = link_to safe_join([custom_emoji_tag(custom_emoji.local_counterpart), t('admin.custom_emojis.overwrite')]), copy_admin_custom_emoji_path(custom_emoji, page: params[:page]), method: :post, class: 'table-action-link'
+ - else
+ = table_link_to 'copy', t('admin.custom_emojis.copy'), copy_admin_custom_emoji_path(custom_emoji, page: params[:page]), method: :post
%td
- if custom_emoji.disabled?
= table_link_to 'power-off', t('admin.custom_emojis.enable'), enable_admin_custom_emoji_path(custom_emoji), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml
index 659295ebf5..8c88d2d64f 100644
--- a/app/views/home/index.html.haml
+++ b/app/views/home/index.html.haml
@@ -3,8 +3,6 @@
%link{ href: asset_pack_path('features/compose.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
%link{ href: asset_pack_path('features/home_timeline.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
%link{ href: asset_pack_path('features/notifications.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
- %link{ href: asset_pack_path('features/community_timeline.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
- %link{ href: asset_pack_path('features/public_timeline.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
%meta{name: 'applicationServerKey', content: Rails.configuration.x.vapid_public_key}
%script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json)
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 831858bcf0..ee995c987e 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -27,7 +27,6 @@
= yield :header_tags
- body_classes ||= @body_classes || ''
- - body_classes += ' reduce-motion' if current_account&.user&.setting_reduce_motion
- body_classes += ' system-font' if current_account&.user&.setting_system_font_ui
%body{ class: add_rtl_body_class(body_classes) }
diff --git a/app/views/settings/notifications/show.html.haml b/app/views/settings/notifications/show.html.haml
index 80cd615c7e..b718b62df5 100644
--- a/app/views/settings/notifications/show.html.haml
+++ b/app/views/settings/notifications/show.html.haml
@@ -11,7 +11,7 @@
= ff.input :reblog, as: :boolean, wrapper: :with_label
= ff.input :favourite, as: :boolean, wrapper: :with_label
= ff.input :mention, as: :boolean, wrapper: :with_label
-
+
.fields-group
= f.simple_fields_for :notification_emails, hash_to_object(current_user.settings.notification_emails) do |ff|
= ff.input :digest, as: :boolean, wrapper: :with_label
@@ -20,6 +20,7 @@
= f.simple_fields_for :interactions, hash_to_object(current_user.settings.interactions) do |ff|
= ff.input :must_be_follower, as: :boolean, wrapper: :with_label
= ff.input :must_be_following, as: :boolean, wrapper: :with_label
+ = ff.input :must_be_following_dm, as: :boolean, wrapper: :with_label
.actions
= f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/user_mailer/confirmation_instructions.pt-BR.html.erb b/app/views/user_mailer/confirmation_instructions.pt-BR.html.erb
index 80edcfda7b..0be16d994e 100644
--- a/app/views/user_mailer/confirmation_instructions.pt-BR.html.erb
+++ b/app/views/user_mailer/confirmation_instructions.pt-BR.html.erb
@@ -1,6 +1,6 @@
Boas vindas, <%= @resource.email %>!
-Você acabou de criar uma conta no <%= @instance %>.
+Você acabou de criar uma conta na instância <%= @instance %>.
Para confirmar o seu cadastro, por favor clique no link a seguir:
<%= link_to 'Confirmar cadastro', confirmation_url(@resource, confirmation_token: @token) %>
@@ -9,4 +9,4 @@
Atenciosamente,
-
A equipe do <%= @instance %>
+A equipe da instância <%= @instance %>
diff --git a/app/views/user_mailer/confirmation_instructions.pt-BR.text.erb b/app/views/user_mailer/confirmation_instructions.pt-BR.text.erb
index 95efb3436a..578f7acb59 100644
--- a/app/views/user_mailer/confirmation_instructions.pt-BR.text.erb
+++ b/app/views/user_mailer/confirmation_instructions.pt-BR.text.erb
@@ -1,6 +1,6 @@
Boas vindas, <%= @resource.email %>!
-Você acabou de criar uma conta no <%= @instance %>.
+Você acabou de criar uma conta na instância <%= @instance %>.
Para confirmar o seu cadastro, por favor clique no link a seguir:
<%= confirmation_url(@resource, confirmation_token: @token) %>
@@ -9,4 +9,4 @@ Por favor, leia também os nossos termos e condições de uso <%= terms_url %>
Atenciosamente,
-A equipe do <%= @instance %>
+A equipe da instância <%= @instance %>
diff --git a/app/views/user_mailer/confirmation_instructions.zh-cn.html.erb b/app/views/user_mailer/confirmation_instructions.zh-cn.html.erb
index de2f8b6e0f..8a676498aa 100644
--- a/app/views/user_mailer/confirmation_instructions.zh-cn.html.erb
+++ b/app/views/user_mailer/confirmation_instructions.zh-cn.html.erb
@@ -1,10 +1,13 @@
-<%= @resource.email %> ,嗨呀!
+<%= @resource.email %>,你好呀!
-你刚刚在 <%= @instance %> 创建了帐号。
+你刚刚在 <%= @instance %> 创建了一个帐户呢。
-点击下面的链接来完成注册啦 :
+
点击下面的链接来完成注册啦:
<%= link_to '确认帐户', confirmation_url(@resource, confirmation_token: @token) %>
-
别忘了看看 <%= link_to '使用条款', terms_url %>。
+上面的链接按不动?把下面的链接复制到地址栏再试试:
+<%= confirmation_url(@resource, confirmation_token: @token) %>
-
<%= @instance %> 敬上
\ No newline at end of file
+记得读一读我们的<%= link_to '使用条款', terms_url %>哦。
+
+来自 <%= @instance %> 管理团队
diff --git a/app/views/user_mailer/confirmation_instructions.zh-cn.text.erb b/app/views/user_mailer/confirmation_instructions.zh-cn.text.erb
index d7d4b4b236..25d901f163 100644
--- a/app/views/user_mailer/confirmation_instructions.zh-cn.text.erb
+++ b/app/views/user_mailer/confirmation_instructions.zh-cn.text.erb
@@ -1,10 +1,10 @@
-<%= @resource.email %> ,嗨呀!
+<%= @resource.email %>,你好呀!
-你刚刚在 <%= @instance %> 创建了帐号。
+你刚刚在 <%= @instance %> 创建了一个帐户呢。
-点击下面的链接来完成注册啦 :
-<%= link_to '确认帐户', confirmation_url(@resource, confirmation_token: @token) %>
+点击下面的链接来完成注册啦:
+<%= confirmation_url(@resource, confirmation_token: @token) %>
-别忘了看看 <%= link_to 'terms and conditions', terms_url %>。
+记得读一读我们的使用条款哦:<%= terms_url %>
-<%= @instance %> 敬上
\ No newline at end of file
+来自 <%= @instance %> 管理团队
\ No newline at end of file
diff --git a/app/views/user_mailer/password_change.pt-BR.html.erb b/app/views/user_mailer/password_change.pt-BR.html.erb
index 5f707ba094..a1aaa265e8 100644
--- a/app/views/user_mailer/password_change.pt-BR.html.erb
+++ b/app/views/user_mailer/password_change.pt-BR.html.erb
@@ -1,3 +1,3 @@
Olá, <%= @resource.email %>!
-Estamos te contatando para te notificar que a senha senha no <%= @instance %> foi modificada.
+Estamos te contatando para te notificar que a sua senha na instância <%= @instance %> foi modificada.
diff --git a/app/views/user_mailer/password_change.pt-BR.text.erb b/app/views/user_mailer/password_change.pt-BR.text.erb
index d8b76648cf..eb7368ba92 100644
--- a/app/views/user_mailer/password_change.pt-BR.text.erb
+++ b/app/views/user_mailer/password_change.pt-BR.text.erb
@@ -1,3 +1,3 @@
Olá, <%= @resource.email %>!
-Estamos te contatando para te notificar que a senha senha no <%= @instance %> foi modificada.
+Estamos te contatando para te notificar que a sua senha na instância <%= @instance %> foi modificada.
diff --git a/app/views/user_mailer/password_change.zh-cn.html.erb b/app/views/user_mailer/password_change.zh-cn.html.erb
index 115030af48..64e8b6b2ff 100644
--- a/app/views/user_mailer/password_change.zh-cn.html.erb
+++ b/app/views/user_mailer/password_change.zh-cn.html.erb
@@ -1,3 +1,3 @@
-<%= @resource.email %>,嗨呀!
+<%= @resource.email %>,你好呀!
-这只是一封用来通知你的密码已经被修改的邮件。_(:3」∠)_
+提醒一下,你在 <%= @instance %> 上的密码被更改了哦。
diff --git a/app/views/user_mailer/password_change.zh-cn.text.erb b/app/views/user_mailer/password_change.zh-cn.text.erb
index 5a989d324e..dbc065173e 100644
--- a/app/views/user_mailer/password_change.zh-cn.text.erb
+++ b/app/views/user_mailer/password_change.zh-cn.text.erb
@@ -1,3 +1,3 @@
-<%= @resource.email %>,嗨呀!
+<%= @resource.email %>,你好呀!
-这只是一封用来通知你的密码已经被修改的邮件。_(:3」∠)_
+提醒一下,你在 <%= @instance %> 上的密码被更改了哦。
diff --git a/app/views/user_mailer/reset_password_instructions.oc.html.erb b/app/views/user_mailer/reset_password_instructions.oc.html.erb
index 6c775b3a16..92e4b8f8b7 100644
--- a/app/views/user_mailer/reset_password_instructions.oc.html.erb
+++ b/app/views/user_mailer/reset_password_instructions.oc.html.erb
@@ -1,6 +1,6 @@
Bonjorn <%= @resource.email %> !
-Qualqu’un a demandat la reĩnicializacion de vòstre senhal per Mastodon. Podètz realizar la reĩnicializacion en clicant sul ligam çai-jos.
+Qualqu’un a demandat la reïnicializacion de vòstre senhal per Mastodon. Podètz realizar la reïnicializacion en clicant sul ligam çai-jos.
<%= link_to 'Modificar mon senhal', edit_password_url(@resource, reset_password_token: @token) %>
diff --git a/app/views/user_mailer/reset_password_instructions.oc.text.erb b/app/views/user_mailer/reset_password_instructions.oc.text.erb
index 26432d2df5..5a5219589b 100644
--- a/app/views/user_mailer/reset_password_instructions.oc.text.erb
+++ b/app/views/user_mailer/reset_password_instructions.oc.text.erb
@@ -1,6 +1,6 @@
Bonjorn <%= @resource.email %> !
-Qualqu’un a demandat la reĩnicializacion de vòstre senhal per Mastodon. Podètz realizar la reĩnicializacion en clicant sul ligam çai-jos.
+Qualqu’un a demandat la reïnicializacion de vòstre senhal per Mastodon. Podètz realizar la reïnicializacion en clicant sul ligam çai-jos.
<%= link_to 'Modificar mon senhal', edit_password_url(@resource, reset_password_token: @token) %>
diff --git a/app/views/user_mailer/reset_password_instructions.pt-BR.html.erb b/app/views/user_mailer/reset_password_instructions.pt-BR.html.erb
index 940438b7cb..9b21aae928 100644
--- a/app/views/user_mailer/reset_password_instructions.pt-BR.html.erb
+++ b/app/views/user_mailer/reset_password_instructions.pt-BR.html.erb
@@ -1,8 +1,8 @@
Olá, <%= @resource.email %>!
-Alguém solicitou um link para mudar a sua senha no <%= @instance %>. Você pode fazer isso através do link abaixo:
+Alguém solicitou um link para mudar a sua senha na instância <%= @instance %>. Você pode fazer isso através do link abaixo:
<%= link_to 'Mudar a minha senha', edit_password_url(@resource, reset_password_token: @token) %>
Se você não solicitou isso, por favor ignore este e-mail.
-A senha senha não será modificada até que você acesse o link acima e crie uma nova.
+A senha não será modificada até que você acesse o link acima e crie uma nova.
diff --git a/app/views/user_mailer/reset_password_instructions.pt-BR.text.erb b/app/views/user_mailer/reset_password_instructions.pt-BR.text.erb
index f574fe08f9..2abff0c0d1 100644
--- a/app/views/user_mailer/reset_password_instructions.pt-BR.text.erb
+++ b/app/views/user_mailer/reset_password_instructions.pt-BR.text.erb
@@ -1,8 +1,8 @@
Olá, <%= @resource.email %>!
-Alguém solicitou um link para mudar a sua senha no <%= @instance %>. Você pode fazer isso através do link abaixo:
+Alguém solicitou um link para mudar a sua senha na instância <%= @instance %>. Você pode fazer isso através do link abaixo:
<%= edit_password_url(@resource, reset_password_token: @token) %>
Se você não solicitou isso, por favor ignore este e-mail.
-A senha senha não será modificada até que você acesse o link acima e crie uma nova.
+A senha não será modificada até que você acesse o link acima e crie uma nova.
diff --git a/app/views/user_mailer/reset_password_instructions.zh-cn.html.erb b/app/views/user_mailer/reset_password_instructions.zh-cn.html.erb
index 51e3073f14..124305675c 100644
--- a/app/views/user_mailer/reset_password_instructions.zh-cn.html.erb
+++ b/app/views/user_mailer/reset_password_instructions.zh-cn.html.erb
@@ -1,7 +1,8 @@
-<%= @resource.email %> ,嗨呀!!
+<%= @resource.email %>,你好呀!
-有人(但愿是你)请求更改你Mastodon帐户的密码。如果是你的话,请点击下面的链接:
+有人想修改你在 <%= @instance %> 上的密码呢。如果你确实想修改密码的话,点击下面的链接吧:
-<%= link_to '更改密码', edit_password_url(@resource, reset_password_token: @token) %>
+<%= link_to '修改密码', edit_password_url(@resource, reset_password_token: @token) %>
-如果不是的话,忘了它吧。只有你本人通过上面的链接设置新的密码以后你的新密码才会生效。
+如果你不想修改密码的话,还请忽略这封邮件哦。
+在你点击上面的链接并修改密码前,你的密码是不会改变的。
diff --git a/app/views/user_mailer/reset_password_instructions.zh-cn.text.erb b/app/views/user_mailer/reset_password_instructions.zh-cn.text.erb
index 7df590f788..f7cd888471 100644
--- a/app/views/user_mailer/reset_password_instructions.zh-cn.text.erb
+++ b/app/views/user_mailer/reset_password_instructions.zh-cn.text.erb
@@ -1,7 +1,8 @@
-<%= @resource.email %> ,嗨呀!!
+<%= @resource.email %>,你好呀!
-有人(但愿是你)请求更改你Mastodon帐户的密码。如果是你的话,请点击下面的链接:
+有人想修改你在 <%= @instance %> 上的密码呢。如果你确实想修改密码的话,点击下面的链接吧:
-<%= link_to '更改密码', edit_password_url(@resource, reset_password_token: @token) %>
+<%= edit_password_url(@resource, reset_password_token: @token) %>
-如果不是的话,忘了它吧。只有你本人通过上面的链接设置新的密码以后你的新密码才会生效。
+如果你不想修改密码的话,还请忽略这封邮件哦。
+在你点击上面的链接并修改密码前,你的密码是不会改变的。
diff --git a/app/workers/admin/suspension_worker.rb b/app/workers/admin/suspension_worker.rb
index 6338b1130d..e41465ccca 100644
--- a/app/workers/admin/suspension_worker.rb
+++ b/app/workers/admin/suspension_worker.rb
@@ -6,6 +6,6 @@ class Admin::SuspensionWorker
sidekiq_options queue: 'pull'
def perform(account_id, remove_user = false)
- SuspendAccountService.new.call(Account.find(account_id), remove_user)
+ SuspendAccountService.new.call(Account.find(account_id), remove_user: remove_user)
end
end
diff --git a/app/workers/thread_resolve_worker.rb b/app/workers/thread_resolve_worker.rb
index 38287e8e64..c18a778d55 100644
--- a/app/workers/thread_resolve_worker.rb
+++ b/app/workers/thread_resolve_worker.rb
@@ -3,7 +3,11 @@
class ThreadResolveWorker
include Sidekiq::Worker
- sidekiq_options queue: 'pull', retry: false
+ sidekiq_options queue: 'pull', retry: 3
+
+ sidekiq_retry_in do |count|
+ 15 + 10 * (count**4) + rand(10 * (count**4))
+ end
def perform(child_status_id, parent_url)
child_status = Status.find(child_status_id)
diff --git a/bin/webpack b/bin/webpack
index 528233a784..9d3800c749 100755
--- a/bin/webpack
+++ b/bin/webpack
@@ -1,27 +1,17 @@
#!/usr/bin/env ruby
-$stdout.sync = true
+# frozen_string_literal: true
+#
+# This file was generated by Bundler.
+#
+# The application 'webpack' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
-require "shellwords"
+require "pathname"
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
+ Pathname.new(__FILE__).realpath)
-ENV["RAILS_ENV"] ||= "development"
-RAILS_ENV = ENV["RAILS_ENV"]
+require "rubygems"
+require "bundler/setup"
-ENV["NODE_ENV"] ||= RAILS_ENV
-NODE_ENV = ENV["NODE_ENV"]
-
-APP_PATH = File.expand_path("../", __dir__)
-NODE_MODULES_PATH = File.join(APP_PATH, "node_modules")
-WEBPACK_CONFIG = File.join(APP_PATH, "config/webpack/#{NODE_ENV}.js")
-
-unless File.exist?(WEBPACK_CONFIG)
- puts "Webpack configuration not found."
- puts "Please run bundle exec rails webpacker:install to install webpacker"
- exit!
-end
-
-env = { "NODE_PATH" => NODE_MODULES_PATH.shellescape }
-cmd = [ "#{NODE_MODULES_PATH}/.bin/webpack", "--config", WEBPACK_CONFIG ] + ARGV
-
-Dir.chdir(APP_PATH) do
- exec env, *cmd
-end
+load Gem.bin_path("webpacker", "webpack")
diff --git a/bin/webpack-dev-server b/bin/webpack-dev-server
index c9672f6633..cf701102aa 100755
--- a/bin/webpack-dev-server
+++ b/bin/webpack-dev-server
@@ -1,68 +1,17 @@
#!/usr/bin/env ruby
-$stdout.sync = true
+# frozen_string_literal: true
+#
+# This file was generated by Bundler.
+#
+# The application 'webpack-dev-server' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
-require "shellwords"
-require "yaml"
-require "socket"
+require "pathname"
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
+ Pathname.new(__FILE__).realpath)
-ENV["RAILS_ENV"] ||= "development"
-RAILS_ENV = ENV["RAILS_ENV"]
+require "rubygems"
+require "bundler/setup"
-ENV["NODE_ENV"] ||= RAILS_ENV
-NODE_ENV = ENV["NODE_ENV"]
-
-APP_PATH = File.expand_path("../", __dir__)
-CONFIG_FILE = File.join(APP_PATH, "config/webpacker.yml")
-NODE_MODULES_PATH = File.join(APP_PATH, "node_modules")
-WEBPACK_CONFIG = File.join(APP_PATH, "config/webpack/#{NODE_ENV}.js")
-
-DEFAULT_LISTEN_HOST_ADDR = NODE_ENV == 'development' ? 'localhost' : '0.0.0.0'
-
-def args(key)
- index = ARGV.index(key)
- index ? ARGV[index + 1] : nil
-end
-
-begin
- dev_server = YAML.load_file(CONFIG_FILE)[RAILS_ENV]["dev_server"]
-
- HOSTNAME = args('--host') || dev_server["host"]
- PORT = args('--port') || dev_server["port"]
- HTTPS = ARGV.include?('--https') || dev_server["https"]
- DEV_SERVER_ADDR = "http#{"s" if HTTPS}://#{HOSTNAME}:#{PORT}"
- LISTEN_HOST_ADDR = args('--listen-host') || DEFAULT_LISTEN_HOST_ADDR
-
-rescue Errno::ENOENT, NoMethodError
- $stdout.puts "Webpack dev_server configuration not found in #{CONFIG_FILE}."
- $stdout.puts "Please run bundle exec rails webpacker:install to install webpacker"
- exit!
-end
-
-begin
- server = TCPServer.new(LISTEN_HOST_ADDR, PORT)
- server.close
-
-rescue Errno::EADDRINUSE
- $stdout.puts "Another program is running on port #{PORT}. Set a new port in #{CONFIG_FILE} for dev_server"
- exit!
-end
-
-# Delete supplied host, port and listen-host CLI arguments
-["--host", "--port", "--listen-host"].each do |arg|
- ARGV.delete(args(arg))
- ARGV.delete(arg)
-end
-
-env = { "NODE_PATH" => NODE_MODULES_PATH.shellescape }
-
-cmd = [
- "#{NODE_MODULES_PATH}/.bin/webpack-dev-server", "--progress", "--color",
- "--config", WEBPACK_CONFIG,
- "--host", LISTEN_HOST_ADDR,
- "--public", "#{HOSTNAME}:#{PORT}",
- "--port", PORT.to_s
-] + ARGV
-
-Dir.chdir(APP_PATH) do
- exec env, *cmd
-end
+load Gem.bin_path("webpacker", "webpack-dev-server")
diff --git a/config/brakeman.ignore b/config/brakeman.ignore
index f198eebac2..f7cf89dffa 100644
--- a/config/brakeman.ignore
+++ b/config/brakeman.ignore
@@ -10,7 +10,7 @@
"line": 122,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).inbox_url, Account.find(params[:id]).inbox_url)",
- "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":13,"file":"app/controllers/admin/accounts_controller.rb"}],
+ "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":15,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": {
"type": "template",
"template": "admin/accounts/show"
@@ -29,7 +29,7 @@
"line": 128,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).shared_inbox_url, Account.find(params[:id]).shared_inbox_url)",
- "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":13,"file":"app/controllers/admin/accounts_controller.rb"}],
+ "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":15,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": {
"type": "template",
"template": "admin/accounts/show"
@@ -48,7 +48,7 @@
"line": 35,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).url, Account.find(params[:id]).url)",
- "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":13,"file":"app/controllers/admin/accounts_controller.rb"}],
+ "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":15,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": {
"type": "template",
"template": "admin/accounts/show"
@@ -57,25 +57,6 @@
"confidence": "Weak",
"note": ""
},
- {
- "warning_type": "Dynamic Render Path",
- "warning_code": 15,
- "fingerprint": "3b0a20b08aef13cf8cf865384fae0cfd3324d8200a83262bf4abbc8091b5fec5",
- "check_name": "Render",
- "message": "Render path contains parameter value",
- "file": "app/views/admin/custom_emojis/index.html.haml",
- "line": 31,
- "link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
- "code": "render(action => filtered_custom_emojis.page(params[:page]), {})",
- "render_path": [{"type":"controller","class":"Admin::CustomEmojisController","method":"index","line":9,"file":"app/controllers/admin/custom_emojis_controller.rb"}],
- "location": {
- "type": "template",
- "template": "admin/custom_emojis/index"
- },
- "user_input": "params[:page]",
- "confidence": "Weak",
- "note": ""
- },
{
"warning_type": "Dynamic Render Path",
"warning_code": 15,
@@ -105,7 +86,7 @@
"line": 131,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).followers_url, Account.find(params[:id]).followers_url)",
- "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":13,"file":"app/controllers/admin/accounts_controller.rb"}],
+ "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":15,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": {
"type": "template",
"template": "admin/accounts/show"
@@ -124,7 +105,7 @@
"line": 106,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).salmon_url, Account.find(params[:id]).salmon_url)",
- "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":13,"file":"app/controllers/admin/accounts_controller.rb"}],
+ "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":15,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": {
"type": "template",
"template": "admin/accounts/show"
@@ -133,6 +114,25 @@
"confidence": "Weak",
"note": ""
},
+ {
+ "warning_type": "Dynamic Render Path",
+ "warning_code": 15,
+ "fingerprint": "8d843713d99e8403f7992f3e72251b633817cf9076ffcbbad5613859d2bbc127",
+ "check_name": "Render",
+ "message": "Render path contains parameter value",
+ "file": "app/views/admin/custom_emojis/index.html.haml",
+ "line": 31,
+ "link": "http://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
+ "code": "render(action => filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page]), {})",
+ "render_path": [{"type":"controller","class":"Admin::CustomEmojisController","method":"index","line":9,"file":"app/controllers/admin/custom_emojis_controller.rb"}],
+ "location": {
+ "type": "template",
+ "template": "admin/custom_emojis/index"
+ },
+ "user_input": "params[:page]",
+ "confidence": "Weak",
+ "note": ""
+ },
{
"warning_type": "SQL Injection",
"warning_code": 0,
@@ -140,7 +140,7 @@
"check_name": "SQL",
"message": "Possible SQL injection",
"file": "lib/mastodon/snowflake.rb",
- "line": 86,
+ "line": 87,
"link": "http://brakemanscanner.org/docs/warning_types/sql_injection/",
"code": "connection.execute(\" CREATE OR REPLACE FUNCTION timestamp_id(table_name text)\\n RETURNS bigint AS\\n $$\\n DECLARE\\n time_part bigint;\\n sequence_base bigint;\\n tail bigint;\\n BEGIN\\n time_part := (\\n -- Get the time in milliseconds\\n ((date_part('epoch', now()) * 1000))::bigint\\n -- And shift it over two bytes\\n << 16);\\n\\n sequence_base := (\\n 'x' ||\\n -- Take the first two bytes (four hex characters)\\n substr(\\n -- Of the MD5 hash of the data we documented\\n md5(table_name ||\\n '#{SecureRandom.hex(16)}' ||\\n time_part::text\\n ),\\n 1, 4\\n )\\n -- And turn it into a bigint\\n )::bit(16)::bigint;\\n\\n -- Finally, add our sequence number to our base, and chop\\n -- it to the last two bytes\\n tail := (\\n (sequence_base + nextval(table_name || '_id_seq'))\\n & 65535);\\n\\n -- Return the time part and the sequence part. OR appears\\n -- faster here than addition, but they're equivalent:\\n -- time_part has no trailing two bytes, and tail is only\\n -- the last two bytes.\\n RETURN time_part | tail;\\n END\\n $$ LANGUAGE plpgsql VOLATILE;\\n\")",
"render_path": null,
@@ -182,7 +182,7 @@
"line": 95,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).remote_url, Account.find(params[:id]).remote_url)",
- "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":13,"file":"app/controllers/admin/accounts_controller.rb"}],
+ "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":15,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": {
"type": "template",
"template": "admin/accounts/show"
@@ -240,7 +240,7 @@
"line": 125,
"link": "http://brakemanscanner.org/docs/warning_types/link_to_href",
"code": "link_to(Account.find(params[:id]).outbox_url, Account.find(params[:id]).outbox_url)",
- "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":13,"file":"app/controllers/admin/accounts_controller.rb"}],
+ "render_path": [{"type":"controller","class":"Admin::AccountsController","method":"show","line":15,"file":"app/controllers/admin/accounts_controller.rb"}],
"location": {
"type": "template",
"template": "admin/accounts/show"
@@ -269,6 +269,6 @@
"note": ""
}
],
- "updated": "2017-10-07 19:24:02 +0200",
+ "updated": "2017-10-20 00:00:54 +0900",
"brakeman_version": "4.0.1"
}
diff --git a/config/deploy.rb b/config/deploy.rb
index 33b88b109c..3fd149f21b 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-lock '3.8.2'
+lock '3.10.0'
set :repo_url, ENV.fetch('REPO', 'https://github.com/tootsuite/mastodon.git')
set :branch, ENV.fetch('BRANCH', 'master')
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index b35e5c09ae..08a96f727c 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -46,6 +46,7 @@ ignore_missing:
- 'terms.body_html'
- 'application_mailer.salutation'
- 'errors.500'
+
ignore_unused:
- 'activemodel.errors.*'
- 'activerecord.attributes.*'
@@ -58,3 +59,4 @@ ignore_unused:
- 'errors.messages.*'
- 'activerecord.errors.models.doorkeeper/*'
- 'errors.429'
+ - 'admin.accounts.roles.*'
diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb
index 2c82a91db9..14bd034e68 100644
--- a/config/initializers/paperclip.rb
+++ b/config/initializers/paperclip.rb
@@ -7,60 +7,76 @@ Paperclip.interpolates :filename do |attachment, style|
[basename(attachment, style), extension(attachment, style)].delete_if(&:blank?).join('.')
end
-Paperclip::Attachment.default_options[:use_timestamp] = false
+Paperclip::Attachment.default_options.merge!(
+ use_timestamp: false,
+ path: ':class/:attachment/:id_partition/:style/:filename',
+ storage: :fog
+)
if ENV['S3_ENABLED'] == 'true'
- Aws.eager_autoload!(services: %w(S3))
+ require 'fog/aws'
- Paperclip::Attachment.default_options[:storage] = :s3
- Paperclip::Attachment.default_options[:s3_protocol] = ENV.fetch('S3_PROTOCOL') { 'https' }
- Paperclip::Attachment.default_options[:url] = ':s3_domain_url'
- Paperclip::Attachment.default_options[:s3_host_name] = ENV.fetch('S3_HOSTNAME') { "s3-#{ENV.fetch('S3_REGION')}.amazonaws.com" }
- Paperclip::Attachment.default_options[:path] = '/:class/:attachment/:id_partition/:style/:filename'
- Paperclip::Attachment.default_options[:s3_headers] = { 'Cache-Control' => 'max-age=315576000' }
- Paperclip::Attachment.default_options[:s3_permissions] = ENV.fetch('S3_PERMISSION') { 'public-read' }
- Paperclip::Attachment.default_options[:s3_region] = ENV.fetch('S3_REGION') { 'us-east-1' }
+ s3_protocol = ENV.fetch('S3_PROTOCOL') { 'https' }
+ s3_hostname = ENV.fetch('S3_HOSTNAME') { "s3-#{ENV['S3_REGION']}.amazonaws.com" }
+ aws_signature_version = ENV['S3_SIGNATURE_VERSION'] == 's3' ? 2 : ENV['S3_SIGNATURE_VERSION'].to_i
+ aws_signature_version = 4 if aws_signature_version.zero?
- Paperclip::Attachment.default_options[:s3_credentials] = {
- bucket: ENV.fetch('S3_BUCKET'),
- access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
- secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
- }
-
- unless ENV['S3_ENDPOINT'].blank?
- Paperclip::Attachment.default_options[:s3_options] = {
- endpoint: ENV['S3_ENDPOINT'],
- signature_version: ENV['S3_SIGNATURE_VERSION'] || 'v4',
- force_path_style: true,
+ Paperclip::Attachment.default_options.merge!(
+ fog_credentials: {
+ provider: 'AWS',
+ aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
+ aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
+ aws_signature_version: aws_signature_version,
+ region: ENV.fetch('S3_REGION') { 'us-east-1' },
+ scheme: s3_protocol,
+ host: s3_hostname
+ },
+ fog_directory: ENV['S3_BUCKET'],
+ fog_options: {
+ acl: ENV.fetch('S3_PERMISSION') { 'public-read' },
+ cache_control: 'max-age=315576000',
}
+ )
- Paperclip::Attachment.default_options[:url] = ':s3_path_url'
+ if ENV.has_key?('S3_ENDPOINT')
+ Paperclip::Attachment.default_options[:fog_credentials].merge!(
+ endpoint: ENV['S3_ENDPOINT'],
+ path_style: true
+ )
+ Paperclip::Attachment.default_options[:fog_host] = "#{s3_protocol}://#{s3_hostname}/#{ENV['S3_BUCKET']}"
end
- unless ENV['S3_CLOUDFRONT_HOST'].blank?
- Paperclip::Attachment.default_options[:url] = ':s3_alias_url'
- Paperclip::Attachment.default_options[:s3_host_alias] = ENV['S3_CLOUDFRONT_HOST']
+ if ENV.has_key?('S3_CLOUDFRONT_HOST')
+ Paperclip::Attachment.default_options[:fog_host] = "#{s3_protocol}://#{ENV['S3_CLOUDFRONT_HOST']}"
end
elsif ENV['SWIFT_ENABLED'] == 'true'
+ require 'fog/openstack'
+
Paperclip::Attachment.default_options.merge!(
- path: ':class/:attachment/:id_partition/:style/:filename',
- storage: :fog,
fog_credentials: {
provider: 'OpenStack',
- openstack_username: ENV.fetch('SWIFT_USERNAME'),
- openstack_project_name: ENV.fetch('SWIFT_TENANT'),
- openstack_tenant: ENV.fetch('SWIFT_TENANT'), # Some OpenStack-v2 ignores project_name but needs tenant
- openstack_api_key: ENV.fetch('SWIFT_PASSWORD'),
- openstack_auth_url: ENV.fetch('SWIFT_AUTH_URL'),
- openstack_domain_name: ENV['SWIFT_DOMAIN_NAME'] || 'default',
+ openstack_username: ENV['SWIFT_USERNAME'],
+ openstack_project_name: ENV['SWIFT_TENANT'],
+ openstack_tenant: ENV['SWIFT_TENANT'], # Some OpenStack-v2 ignores project_name but needs tenant
+ openstack_api_key: ENV['SWIFT_PASSWORD'],
+ openstack_auth_url: ENV['SWIFT_AUTH_URL'],
+ openstack_domain_name: ENV.fetch('SWIFT_DOMAIN_NAME') { 'default' },
openstack_region: ENV['SWIFT_REGION'],
- openstack_cache_ttl: ENV['SWIFT_CACHE_TTL'] || 60,
+ openstack_cache_ttl: ENV.fetch('SWIFT_CACHE_TTL') { 60 },
},
- fog_directory: ENV.fetch('SWIFT_CONTAINER'),
+ fog_directory: ENV['SWIFT_CONTAINER'],
fog_host: ENV['SWIFT_OBJECT_URL'],
fog_public: true
)
else
- Paperclip::Attachment.default_options[:path] = (ENV['PAPERCLIP_ROOT_PATH'] || ':rails_root/public/system') + '/:class/:attachment/:id_partition/:style/:filename'
- Paperclip::Attachment.default_options[:url] = (ENV['PAPERCLIP_ROOT_URL'] || '/system') + '/:class/:attachment/:id_partition/:style/:filename'
+ require 'fog/local'
+
+ Paperclip::Attachment.default_options.merge!(
+ fog_credentials: {
+ provider: 'Local',
+ local_root: ENV.fetch('PAPERCLIP_ROOT_PATH') { Rails.root.join('public', 'system') },
+ },
+ fog_directory: '',
+ fog_host: ENV.fetch('PAPERCLIP_ROOT_URL') { '/system' }
+ )
end
diff --git a/config/initializers/statsd.rb b/config/initializers/statsd.rb
index 17a1761742..45702ac94d 100644
--- a/config/initializers/statsd.rb
+++ b/config/initializers/statsd.rb
@@ -4,7 +4,7 @@ if ENV['STATSD_ADDR'].present?
host, port = ENV['STATSD_ADDR'].split(':')
statsd = ::Statsd.new(host, port)
- statsd.namespace = ['Mastodon', Rails.env].join('.')
+ statsd.namespace = ENV.fetch('STATSD_NAMESPACE') { ['Mastodon', Rails.env].join('.') }
::NSA.inform_statsd(statsd) do |informant|
informant.collect(:action_controller, :web)
diff --git a/config/locales/activerecord.zh-CN.yml b/config/locales/activerecord.zh-CN.yml
new file mode 100644
index 0000000000..8628d6677b
--- /dev/null
+++ b/config/locales/activerecord.zh-CN.yml
@@ -0,0 +1,13 @@
+---
+zh-CN:
+ activerecord:
+ errors:
+ models:
+ account:
+ attributes:
+ username:
+ invalid: 只能使用字母、数字和下划线
+ status:
+ attributes:
+ reblog:
+ taken: 已经被转嘟过
diff --git a/config/locales/devise.oc.yml b/config/locales/devise.oc.yml
index 5cccb48ffc..266f873730 100644
--- a/config/locales/devise.oc.yml
+++ b/config/locales/devise.oc.yml
@@ -9,7 +9,7 @@ oc:
already_authenticated: Sètz ja connectat.
inactive: Vòstre compte es pas encara activat.
invalid: Corrièl o senhal invalid.
- last_attempt: Vos demòra un ensag abans que vòstre compte siasgue blocat.
+ last_attempt: Vos demòra un ensag abans que vòstre compte siasque blocat.
locked: Vòstre compte es blocat.
not_found_in_database: Corrièl o senhal invalid.
timeout: Vòstra session s’a acabat. Mercés de vos tornar connectar per contunhar.
diff --git a/config/locales/devise.zh-CN.yml b/config/locales/devise.zh-CN.yml
index 8cc814224c..0e40fcc902 100644
--- a/config/locales/devise.zh-CN.yml
+++ b/config/locales/devise.zh-CN.yml
@@ -2,24 +2,24 @@
zh-CN:
devise:
confirmations:
- confirmed: 成功验证您的邮箱地址。
- send_instructions: 您的电子邮箱将在几分钟后收到一封邮箱确认邮件。
- send_paranoid_instructions: 如果您的邮箱存在于我们的数据库中,您将收到一封确认帐号的邮件。
+ confirmed: 成功验证你的邮箱地址。
+ send_instructions: 你的电子邮箱将在几分钟后收到一封确认邮件。如果没有,请检查你的垃圾邮箱。
+ send_paranoid_instructions: 如果你的邮箱存在于我们的数据库中,你将收到一封确认注册的邮件。如果没有,请检查你的垃圾邮箱。
failure:
- already_authenticated: 您已经登录。
- inactive: 您还没有激活帐户。
+ already_authenticated: 你已经登录。
+ inactive: 你还没有激活帐户。
invalid: " %{authentication_keys} 或密码错误。"
- last_attempt: 您还有最后一次尝试机会,再次失败您的帐号将被锁定。
- locked: 您的帐号已被锁定。
+ last_attempt: 你还有最后一次尝试机会,再次失败你的帐户将被锁定。
+ locked: 你的帐户已被锁定。
not_found_in_database: "%{authentication_keys}或密码错误。"
- timeout: 您已登录超时,请重新登录。
+ timeout: 你已登录超时,请重新登录。
unauthenticated: 继续操作前请注册或者登录。
- unconfirmed: 继续操作前请先确认您的帐号。
+ unconfirmed: 继续操作前请先确认你的帐户。
mailer:
confirmation_instructions:
subject: Mastodon 帐户确认信息
email_changed:
- subject: Mastodon 电邮已被修改
+ subject: Mastodon 电子邮件地址已被修改
password_change:
subject: Mastodon 密码已被重置
reset_password_instructions:
@@ -30,33 +30,33 @@ zh-CN:
failure: 由于%{reason},无法从%{kind}获得授权。
success: 成功地从%{kind}获得授权。
passwords:
- no_token: 无重置邮件不可访问密码重置页面。如果您是从重置邮件来到了这个页面,请确保您输入的URL完整的。
- send_instructions: 几分钟后,您将收到重置密码的电子邮件。
- send_paranoid_instructions: 如果您的邮箱存在于我们的数据库中,您将收到一封找回密码的邮件。
- updated: 您的密码已修改成功,您现在已登录。
- updated_not_active: 您的密码已修改成功。
+ no_token: 你必须通过密码重置邮件才能访问这个页面。如果你确实如此,请确保你输入的 URL 是完整的。
+ send_instructions: 几分钟后,你将收到重置密码的电子邮件。如果没有,请检查你的垃圾邮箱。
+ send_paranoid_instructions: 如果你的邮箱存在于我们的数据库中,你将收到一封找回密码的邮件。如果没有,请检查你的垃圾邮箱。
+ updated: 你的密码已修改成功,你现在已登录。
+ updated_not_active: 你的密码已修改成功。
registrations:
- destroyed: 再见!您的帐户已成功注销。我们希望很快可以再见到您。
- signed_up: 欢迎!您已注册成功。
- signed_up_but_inactive: 您已注册,但尚未激活帐号。
- signed_up_but_locked: 您已注册,但帐号被锁定了。
- signed_up_but_unconfirmed: 一封带有确认链接的邮件已经发送至您的邮箱,请检查邮箱(包括垃圾邮箱),并点击该链接激活您的帐号。
- update_needs_confirmation: 信息更新成功,但我们需要验证您的新电子邮件地址,请检查邮箱(包括垃圾邮箱),并点击该链接激活您的帐号。
- updated: 帐号资料更新成功。
+ destroyed: 再见!你的帐户已成功注销。我们希望很快可以再见到你。
+ signed_up: 欢迎!你已注册成功。
+ signed_up_but_inactive: 你已注册,但尚未激活帐户。
+ signed_up_but_locked: 你已注册,但帐户被锁定了。
+ signed_up_but_unconfirmed: 一封带有确认链接的邮件已经发送至你的邮箱,请点击邮件中的链接以激活你的帐户。如果没有,请检查你的垃圾邮箱。
+ update_needs_confirmation: 信息更新成功,但我们需要验证你的新电子邮件地址,请点击邮件中的链接以确认。如果没有,请检查你的垃圾邮箱。
+ updated: 帐户资料更新成功。
sessions:
- already_signed_out: 已经退出成功。
+ already_signed_out: 已成功登出。
signed_in: 登录成功。
- signed_out: 退出成功。
+ signed_out: 登出成功。
unlocks:
- send_instructions: 几分钟后,您将收到一封解锁帐号的邮件。
- send_paranoid_instructions: 如果您的邮箱存在于我们的数据库中,您将收到一封解锁帐号的邮件。
- unlocked: 您的帐号已成功解锁,您现在已登录。
+ send_instructions: 几分钟后,你将收到一封解锁帐户的邮件。如果没有,请检查你的垃圾邮箱。
+ send_paranoid_instructions: 如果你的邮箱存在于我们的数据库中,你将收到一封解锁帐户的邮件。如果没有,请检查你的垃圾邮箱。
+ unlocked: 你的帐户已成功解锁。登录以继续。
errors:
messages:
already_confirmed: 已经确认,请重新登录。
- confirmation_period_expired: 注册帐号后须在%{period}以内确认。请重新注册。
+ confirmation_period_expired: 注册帐户后须在 %{period}以内确认。请重新注册。
expired: 邮件确认已过期,请重新注册。
not_found: 找不到。
not_locked: 未锁定。
not_saved:
- other: 发生%{count}个错误,导致%{resource}保存失败:
+ other: 发生 %{count} 个错误,导致%{resource}保存失败:
diff --git a/config/locales/doorkeeper.pl.yml b/config/locales/doorkeeper.pl.yml
index fa4324e4de..33f133c06f 100644
--- a/config/locales/doorkeeper.pl.yml
+++ b/config/locales/doorkeeper.pl.yml
@@ -59,7 +59,7 @@ pl:
error:
title: Wystapił błąd
new:
- able_to: Będzie w stanie
+ able_to: Uzyska
prompt: Aplikacja %{client_name} prosi o dostęp do Twojego konta
title: Wymagana jest autoryzacja
show:
@@ -114,6 +114,6 @@ pl:
application:
title: Uwierzytelnienie OAuth jest wymagane
scopes:
- follow: śledzenie, blokowanie, usuwanie blokady, anulowanie śledzenia kont
+ follow: możliwość śledzenia, blokowania, usuwania blokad, anulowania śledzenia kont
read: dostęp do odczytu danych konta
- write: publikowanie wpisów w Twoim imieniu
+ write: możliwość publikowania wpisów w Twoim imieniu
diff --git a/config/locales/doorkeeper.zh-CN.yml b/config/locales/doorkeeper.zh-CN.yml
index 12b38b81ff..c7e8f368d5 100644
--- a/config/locales/doorkeeper.zh-CN.yml
+++ b/config/locales/doorkeeper.zh-CN.yml
@@ -3,15 +3,16 @@ zh-CN:
activerecord:
attributes:
doorkeeper/application:
- name: 名称
- redirect_uri: 登录回调地址
+ name: 应用名称
+ redirect_uri: 重定向 URI
scopes: 权限范围
+ website: 应用网站
errors:
models:
doorkeeper/application:
attributes:
redirect_uri:
- fragment_present: 不能包含片段(#)
+ fragment_present: 不能包含网址片段(#)
invalid_uri: 必须是有效的 URL 格式
relative_uri: 必须是绝对的 URL 地址
secured_uri: 必须是 HTTPS/SSL 的 URL 地址
@@ -30,60 +31,65 @@ zh-CN:
form:
error: 抱歉! 提交信息的时候遇到了下面的错误
help:
- native_redirect_uri: 使用 %{native_redirect_uri} 作为本地测试
+ native_redirect_uri: 本地测试请使用 %{native_redirect_uri}
redirect_uri: 每行只能有一个 URL
- scopes: 用空格隔开权限范围,留空则使用默认设置
+ scopes: 用空格分割权限范围,留空则使用默认设置
index:
- callback_url: 登录回调地址
+ application: 应用
+ callback_url: 回调 URL
+ delete: 删除
name: 名称
new: 创建新应用
+ scopes: 权限范围
+ show: 显示
title: 你的应用
new:
title: 创建新应用
show:
actions: 操作
application_id: 应用 ID
- callback_urls: 登录回调地址
+ callback_urls: 回调 URL
scopes: 权限范围
- secret: 私钥
+ secret: 应用密钥
title: 应用:%{name}
authorizations:
buttons:
- authorize: 授权
- deny: 拒绝
+ authorize: 同意授权
+ deny: 拒绝授权
error:
- title: 存在错误
+ title: 发生错误
new:
- able_to: 此应用将会
- prompt: 授权 %{client_name} 使用你的帐号?
- title: 需要你授权
+ able_to: 此应用将能够
+ prompt: 授权 %{client_name} 使用你的帐户?
+ title: 需要授权
show:
- title: Copy this authorization code and paste it to the application.
+ title: 接下来请复制此处的授权代码并粘贴到应用中。
authorized_applications:
buttons:
- revoke: 注销
+ revoke: 撤销授权
confirmations:
- revoke: 确定要注销此应用的认证信息吗?
+ revoke: 确定要撤销对此应用的授权吗?
index:
application: 应用
created_at: 授权时间
date_format: "%Y-%m-%d %H:%M:%S"
- title: 你授权的应用列表
+ scopes: 权限范围
+ title: 已授权的应用列表
errors:
messages:
access_denied: 用户或服务器拒绝了请求
- credential_flow_not_configured: Resource Owner Password Credentials flow failed,原因是 Doorkeeper.configure.resource_owner_from_credentials 尚未设置。
- invalid_client: 由于未知、不支持或没有客户端,认证失败
+ credential_flow_not_configured: 由于 Doorkeeper.configure.resource_owner_from_credentials 尚未配置,应用验证授权流程失败。
+ invalid_client: 由于应用信息未知、未提交认证信息或使用了不支持的认证方式,认证失败
invalid_grant: 授权方式无效,或者登录回调地址无效、过期或已被撤销
invalid_redirect_uri: 无效的登录回调地址
- invalid_request: 这个请求缺少必要的参数,或者参数值、格式不正确
- invalid_resource_owner: 资源所有者认证无效或没有所有者
- invalid_scope: 请求范围无效、未知或格式不正确
+ invalid_request: 请求缺少必要的参数,或者参数值、格式不正确
+ invalid_resource_owner: 资源所有者认证无效,或找不到所有者
+ invalid_scope: 请求的权限范围无效、未知或格式不正确
invalid_token:
expired: 访问令牌已过期
revoked: 访问令牌已被吊销
unknown: 访问令牌无效
- resource_owner_authenticator_not_configured: Resource Owner find failed,原因是 Doorkeeper.configure.resource_owner_authenticator 尚未设置。
+ resource_owner_authenticator_not_configured: 由于 Doorkeeper.configure.resource_owner_authenticator 尚未配置,查找资源所有者失败。
server_error: 服务器异常,无法处理请求
temporarily_unavailable: 服务器维护中或负载过高,暂时无法处理请求
unauthorized_client: 未授权的应用,请求无法执行
@@ -99,16 +105,15 @@ zh-CN:
notice: 应用修改成功
authorized_applications:
destroy:
- notice: 已成功注销了应用的认证信息
+ notice: 已成功撤销对此应用的授权
layouts:
admin:
nav:
applications: 应用
- home: 首页
oauth2_provider: OAuth2 提供商
application:
- title: OAuth 认证
+ title: 需要 OAuth 认证
scopes:
- follow: 关注(或取消关注),屏蔽(或取消屏蔽)用户
- read: 读取你的账户数据
+ follow: 关注(或取消关注)、屏蔽(或取消屏蔽)用户
+ read: 读取你的帐户数据
write: 为你发表嘟文
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 45929e97dd..e941653172 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -43,7 +43,7 @@ en:
people_followed_by: People whom %{name} follows
people_who_follow: People who follow %{name}
posts: Toots
- posts_with_replies: Toots with replies
+ posts_with_replies: Toots and replies
remote_follow: Remote follow
reserved_username: The username is reserved
roles:
@@ -59,13 +59,19 @@ en:
destroyed_msg: Moderation note successfully destroyed!
accounts:
are_you_sure: Are you sure?
+ by_domain: Domain
confirm: Confirm
confirmed: Confirmed
+ demote: Demote
+ disable: Disable
disable_two_factor_authentication: Disable 2FA
+ disabled: Disabled
display_name: Display name
domain: Domain
edit: Edit
email: E-mail
+ enable: Enable
+ enabled: Enabled
feed_url: Feed URL
followers: Followers
followers_url: Followers URL
@@ -77,7 +83,9 @@ en:
local: Local
remote: Remote
title: Location
+ login_status: Login status
media_attachments: Media attachments
+ memorialize: Turn into memoriam
moderation:
all: All
silenced: Silenced
@@ -94,6 +102,7 @@ en:
outbox_url: Outbox URL
perform_full_suspension: Perform full suspension
profile_url: Profile URL
+ promote: Promote
protocol: Protocol
public: Public
push_subscription_expires: PuSH subscription expires
@@ -101,6 +110,11 @@ en:
reset: Reset
reset_password: Reset password
resubscribe: Resubscribe
+ role: Permissions
+ roles:
+ admin: Administrator
+ moderator: Moderator
+ user: User
salmon_url: Salmon URL
search: Search
shared_inbox_url: Shared Inbox URL
@@ -130,11 +144,16 @@ en:
enable: Enable
enabled_msg: Successfully enabled that emoji
image_hint: PNG up to 50KB
+ listed: Listed
new:
title: Add new custom emoji
+ overwrite: Overwrite
shortcode: Shortcode
shortcode_hint: At least 2 characters, only alphanumeric characters and underscores
title: Custom emojis
+ unlisted: Unlisted
+ update_failed_msg: Could not update that emoji
+ updated_msg: Emoji successfully updated!
upload: Upload
domain_blocks:
add_new: Add new
@@ -373,6 +392,7 @@ en:
following: Following list
muting: Muting list
upload: Upload
+ in_memoriam_html: In Memoriam.
landing_strip_html: "%{name} is a user on %{link_to_root_path}. You can follow them or interact with them if you have an account anywhere in the fediverse."
landing_strip_signup_html: If you don't, you can sign up here.
media_attachments:
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 0d9c227f37..55588d1115 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -437,7 +437,7 @@ fr:
action_favourite: Ajouter aux favoris
title: "%{name} vous a mentionné·e"
reblog:
- title: "%{name} a partagé⋅e votre statut"
+ title: "%{name} a partagé votre statut"
remote_follow:
acct: Entrez votre pseudo@instance depuis lequel vous voulez suivre ce⋅tte utilisateur⋅rice
missing_resource: L’URL de redirection n’a pas pu être trouvée
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 3915560403..82b642b5bc 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -59,13 +59,19 @@ ja:
destroyed_msg: モデレーションメモを削除しました
accounts:
are_you_sure: 本当に実行しますか?
+ by_domain: ドメイン
confirm: 確認
confirmed: 確認済み
+ demote: 降格
+ disable: 無効化
disable_two_factor_authentication: 二段階認証を無効にする
+ disabled: 無効
display_name: 表示名
domain: ドメイン
edit: 編集
email: E-mail
+ enable: 有効化
+ enabled: 有効
feed_url: フィードURL
followers: フォロワー数
followers_url: Followers URL
@@ -77,7 +83,9 @@ ja:
local: ローカル
remote: リモート
title: ロケーション
+ login_status: ログイン
media_attachments: 添付されたメディア
+ memorialize: 追悼アカウント化
moderation:
all: すべて
silenced: サイレンス中
@@ -94,6 +102,7 @@ ja:
outbox_url: Outbox URL
perform_full_suspension: 完全に活動停止させる
profile_url: プロフィールURL
+ promote: 昇格
protocol: プロトコル
public: パブリック
push_subscription_expires: PuSH購読期限
@@ -101,6 +110,11 @@ ja:
reset: リセット
reset_password: パスワード再設定
resubscribe: 再講読
+ role: 役割
+ roles:
+ admin: 管理者
+ moderator: モデレーター
+ user: ユーザー
salmon_url: Salmon URL
search: 検索
shared_inbox_url: Shared Inbox URL
@@ -130,11 +144,16 @@ ja:
enable: 有効化
enabled_msg: 絵文字を有効化しました
image_hint: 50KBまでのPNG画像を利用できます。
+ listed: 収載
new:
title: 新規カスタム絵文字の追加
+ overwrite: 上書き
shortcode: ショートコード
shortcode_hint: 2文字以上の半角英数字とアンダーバーのみ利用できます。
title: カスタム絵文字
+ unlisted: 未収載
+ update_failed_msg: 絵文字を更新できませんでした
+ updated_msg: 絵文字の更新に成功しました
upload: アップロード
domain_blocks:
add_new: 新規追加
@@ -373,6 +392,7 @@ ja:
following: フォロー中のアカウントリスト
muting: ミュートしたアカウントリスト
upload: アップロード
+ in_memoriam_html: 故人を偲んで
landing_strip_html: "%{name} さんはインスタンス %{link_to_root_path} のユーザーです。アカウントさえ持っていればフォローしたり会話したりできます。"
landing_strip_signup_html: もしお持ちでないなら こちら からサインアップできます。
media_attachments:
@@ -390,8 +410,8 @@ ja:
one: "新しい1件の通知 \U0001F418"
other: "新しい%{count}件の通知 \U0001F418"
favourite:
- body: 'あなたのトゥートが %{name} さんにお気に入り登録されました:'
- subject: "%{name} さんがあなたのトゥートをお気に入りに登録しました"
+ body: "%{name} さんにお気に入り登録された、あなたのトゥートがあります:"
+ subject: "%{name} さんにお気に入りに登録されました"
follow:
body: "%{name} さんにフォローされています"
subject: "%{name} さんにフォローされています"
@@ -402,8 +422,8 @@ ja:
body: "%{name} さんから返信がありました:"
subject: "%{name} さんに返信されました"
reblog:
- body: 'あなたのトゥートが %{name} さんにブーストされました:'
- subject: あなたのトゥートが %{name} さんにブーストされました
+ body: "%{name} さんにブーストされた、あなたのトゥートがあります:"
+ subject: "%{name} さんにブーストされました"
number:
human:
decimal_units:
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index 0d2a8c2f66..914cc7e9d6 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -59,13 +59,18 @@ oc:
destroyed_msg: Nòta de moderacion ben suprimida !
accounts:
are_you_sure: Sètz segur ?
+ by_domain: Domeni
confirm: Confirmar
confirmed: Confirmat
+ disable: Desactivar
disable_two_factor_authentication: Desactivar 2FA
+ disabled: Desactivat
display_name: Escais-nom
domain: Domeni
edit: Modificar
email: Corrièl
+ enable: Activar
+ enabled: Activat
feed_url: Flux URL
followers: Seguidors
followers_url: URL dels seguidors
@@ -77,7 +82,9 @@ oc:
local: Locals
remote: Alonhats
title: Emplaçament
+ login_status: Estat formulari de connexion
media_attachments: Mèdias ajustats
+ memorialize: Passar en memorial
moderation:
all: Tot
silenced: Rescondut
@@ -130,11 +137,16 @@ oc:
enable: Activar
enabled_msg: Aqueste emoji es ben activat
image_hint: PNG cap a 50Ko
+ listed: Listat
new:
title: Ajustar un nòu emoji personal
+ overwrite: Remplaçar
shortcode: Acorchi
shortcode_hint: Almens 2 caractèrs, solament alfanumerics e jonhent bas
title: Emojis personals
+ unlisted: Pas listat
+ update_failed_msg: Mesa a jorn de l’emoji fracasada
+ updated_msg: Emoji ben mes a jorn !
upload: Enviar
domain_blocks:
add_new: N’ajustar un nòu
@@ -451,6 +463,7 @@ oc:
following: Lista de mond que seguètz
muting: Lista de mond que volètz pas legir
upload: Importar
+ in_memoriam_html: En Memòria.
landing_strip_html: "%{name} utiliza %{link_to_root_path}. Podètz lo/la sègre o interagir amb el o ela s’avètz un compte ont que siasque sul fediverse."
landing_strip_signup_html: S’es pas lo cas, podètz vos marcar aquí.
media_attachments:
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index c58c1c2f8d..49dace354b 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -9,7 +9,7 @@ pl:
contact_missing: Nie ustawiono
contact_unavailable: Nie dotyczy
description_headline: Czym jest %{domain}?
- domain_count_after: instancji
+ domain_count_after: instancjami
domain_count_before: Serwer połączony z
extended_description_html: |
Dobre miejsce na zasady użytkowania
@@ -59,13 +59,19 @@ pl:
destroyed_msg: Pomyślnie usunięto notatkę moderacyjną!
accounts:
are_you_sure: Jesteś tego pewien?
+ by_domain: Domena
confirm: Potwierdź
confirmed: Potwierdzono
+ demote: Degraduj
+ disable: Dezaktywuj
disable_two_factor_authentication: Wyłącz uwierzytelnianie dwuetapowe
+ disabled: Dezaktywowano
display_name: Wyświetlana nazwa
domain: Domena
edit: Edytuj
email: Adres e-mail
+ enable: Aktywuj
+ enabled: Aktywowano
feed_url: Adres kanału
followers: Śledzący
followers_url: Adres śledzących
@@ -77,7 +83,9 @@ pl:
local: Lokalne
remote: Zdalne
title: Położenie
+ login_status: Stan logowania
media_attachments: Załączniki multimedialne
+ memorialize: Przełącz na „In Memoriam”
moderation:
all: Wszystkie
silenced: Wyciszone
@@ -94,6 +102,7 @@ pl:
outbox_url: Adres skrzynki nadawczej
perform_full_suspension: Całkowicie zawieś
profile_url: Adres profilu
+ promote: Podnieś uprawnienia
protocol: Protokół
public: Publiczne
push_subscription_expires: Subskrypcja PuSH wygasa
@@ -101,6 +110,11 @@ pl:
reset: Resetuj
reset_password: Resetuj hasło
resubscribe: Ponów subskrypcję
+ role: Uprawnienia
+ roles:
+ admin: Administrator
+ moderator: Moderator
+ user: Użytkownik
salmon_url: Adres Salmon
search: Szukaj
shared_inbox_url: Adres udostępnianej skrzynki
@@ -109,7 +123,7 @@ pl:
report: zgłoszeń
targeted_reports: Zgłoszenia dotyczące tego użytkownika
silence: Wycisz
- statuses: Statusy
+ statuses: Wpisy
subscribe: Subskrybuj
title: Konta
undo_silenced: Cofnij wyciszenie
@@ -130,12 +144,16 @@ pl:
enable: Włącz
enabled_msg: Pomyślnie przywrócono emoji
image_hint: Plik PNG ważący do 50KB
+ listed: Widoczne
new:
title: Dodaj nowe niestandardowe emoji
shortcode: Shortcode
shortcode_hint: Co najmniej 2 znaki, tylko znaki alfanumeryczne i podkreślniki
title: Niestandardowe emoji
- upload: Wyślij
+ unlisted: Niewidoczne
+ update_failed_msg: Nie udało się zaktualizować emoji
+ updated_msg: Pomyślnie zaktualizowano emoji
+ upload: Dodaj
domain_blocks:
add_new: Dodaj nową
created_msg: Blokada domen jest przetwarzana
@@ -203,7 +221,7 @@ pl:
reported_by: Zgłaszający
resolved: Rozwiązane
silence_account: Wycisz konto
- status: Status
+ status: Stan
suspend_account: Zawieś konto
target: Cel
title: Zgłoszenia
@@ -212,7 +230,7 @@ pl:
settings:
bootstrap_timeline_accounts:
desc_html: Oddzielaj nazwy użytkowników przecinkami. Działa tylko dla niezablokowanych kont w obrębie instancji. Jeżeli puste, zostaną użyte konta administratorów instancji.
- title: Domyślne obserwacje nowych użytkowników
+ title: Domyślnie obserwowani użytkownicy
contact_information:
email: Służbowy adres e-mail
username: Nazwa użytkownika do kontaktu
@@ -256,7 +274,7 @@ pl:
show: Pokaż zawartość multimedialną
title: Media
no_media: Bez zawartości multimedialnej
- title: Statusy konta
+ title: Wpisy konta
with_media: Z zawartością multimedialną
subscriptions:
callback_url: URL zwrotny
@@ -332,7 +350,7 @@ pl:
errors:
'403': Nie masz uprawnień, aby wyświetlić tę stronę.
'404': Strona, którą próbujesz odwiedzić, nie istnieje.
- '410': Strona, którą próbujesz odwiedzić, już nie istnieje.
+ '410': Strona, którą próbujesz odwiedzić, przestała istnieć.
'422':
content: Sprawdzanie bezpieczeństwa nie powiodło się. Czy blokujesz pliki cookie?
title: Sprawdzanie bezpieczeństwa nie powiodło się
@@ -349,7 +367,7 @@ pl:
storage: Urządzenie przechowujące dane
followers:
domain: Domena
- explanation_html: Jeżeli chcesz mieć pewność, kto może przeczytać Twoje statusy, musisz kontrolować, kto śledzi Twój profil. Twoje prywatne statusy są dostarczane na te instancje, na których jesteś śledzony. Możesz sprawdzać, kto Cię śledzi i blokować ich, jeśli nie ufasz właścicielom lub oprogramowaniu danej instancji.
+ explanation_html: Jeżeli chcesz mieć pewność, kto może przeczytać Twoje wpisy, musisz kontrolować, kto śledzi Twój profil. Twoje prywatne wpisy są dostarczane na te instancje, na których jesteś śledzony. Możesz sprawdzać, kto Cię śledzi i blokować ich, jeśli nie ufasz właścicielom lub oprogramowaniu danej instancji.
followers_count: Liczba śledzących
lock_link: Zablokuj swoje konto
purge: Przestań śledzić
@@ -357,7 +375,7 @@ pl:
one: W trakcie usuwania śledzących z jednej domeny…
other: W trakcie usuwania śledzących z %{count} domen…
true_privacy_html: Pamiętaj, że rzeczywista prywatność może zostać uzyskana wyłącznie dzięki szyfrowaniu end-to-end.
- unlocked_warning_html: Każdy może Cię śledzić, aby natychmiastowo zobaczyć twoje statusy. %{lock_link} aby móc kontrolować, kto Cię śledzi.
+ unlocked_warning_html: Każdy może Cię śledzić, aby natychmiastowo zobaczyć twoje wpisy. %{lock_link} aby móc kontrolować, kto Cię śledzi.
unlocked_warning_title: Twoje konto nie jest zablokowane
generic:
changes_saved_msg: Ustawienia zapisane!
@@ -374,11 +392,12 @@ pl:
following: Lista śledzonych
muting: Lista wyciszonych
upload: Załaduj
+ in_memoriam_html: Ku pamięci.
landing_strip_html: "%{name} ma konto na %{link_to_root_path}. Możesz je śledzić i wejść z nim w interakcję jeśli masz konto gdziekolwiek w Fediwersum."
landing_strip_signup_html: Jeśli jeszcze go nie masz, możesz stworzyć konto.
media_attachments:
validations:
- images_and_video: Nie możesz załączyć pliku wideo do statusu, który zawiera już zdjęcia
+ images_and_video: Nie możesz załączyć pliku wideo do wpisu, który zawiera już zdjęcia
too_many: Nie możesz załączyć więcej niż 4 plików
notification_mailer:
digest:
@@ -431,7 +450,7 @@ pl:
web: Sieć
push_notifications:
favourite:
- title: "%{name} dodał Twój status do ulubionych"
+ title: "%{name} dodał Twój wpis do ulubionych"
follow:
title: "%{name} zaczął Cię śledzić"
group:
@@ -442,7 +461,7 @@ pl:
action_favourite: Dodaj do ulubionych
title: "%{name} wspomniał o Tobie"
reblog:
- title: "%{name} podbił Twój status"
+ title: "%{name} podbił Twój wpis"
remote_follow:
acct: Podaj swój adres (nazwa@domena), z którego chcesz śledzić
missing_resource: Nie udało się znaleźć adresu przekierowania z Twojej domeny
@@ -610,7 +629,7 @@ pl:
manual_instructions: 'Jeżeli nie możesz zeskanować kodu QR, musisz wprowadzić ten kod ręcznie:'
recovery_codes: Przywróć kody zapasowe
recovery_codes_regenerated: Pomyślnie wygenerowano ponownie kody zapasowe
- recovery_instructions_html: Jeżeli kiedykolwiek utracisz dostęp do telefonu, możesz wykorzystać jeden z kodów zapasowych, aby odzyskać dostęp do konta. Trzymaj je w bezpiecznym miejscu. Na przykład, wydrukuj je i przechowuj z ważnymu dokumentami.
+ recovery_instructions_html: Jeżeli kiedykolwiek utracisz dostęp do telefonu, możesz wykorzystać jeden z kodów zapasowych, aby odzyskać dostęp do konta. Trzymaj je w bezpiecznym miejscu. Na przykład, wydrukuj je i przechowuj z ważnymi dokumentami.
setup: Skonfiguruj
wrong_code: Wprowadzony kod jest niepoprawny! Czy czas serwera i urządzenia jest poprawny?
users:
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 4b9ea152f8..f5c61c01ca 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -43,7 +43,7 @@ pt-BR:
people_followed_by: Pessoas que %{name} segue
people_who_follow: Pessoas que seguem %{name}
posts: Toots
- posts_with_replies: Toots com respostas
+ posts_with_replies: Toots e respostas
remote_follow: Siga remotamente
reserved_username: Este usuário está reservado
roles:
@@ -59,13 +59,19 @@ pt-BR:
destroyed_msg: Nota de moderação excluída com sucesso!
accounts:
are_you_sure: Você tem certeza?
+ by_domain: Domínio
confirm: Confirmar
confirmed: Confirmado
+ demote: Rebaixar
+ disable: Desativar
disable_two_factor_authentication: Desativar 2FA
+ disabled: Desativado
display_name: Nome de exibição
domain: Domínio
edit: Editar
email: E-mail
+ enable: Ativar
+ enabled: Ativado
feed_url: URL do feed
followers: Seguidores
followers_url: URL de seguidores
@@ -77,7 +83,9 @@ pt-BR:
local: Local
remote: Remoto
title: Localização
+ login_status: Status de login
media_attachments: Mídia(s) anexada(s)
+ memorialize: Tornar um memorial
moderation:
all: Todos
silenced: Silenciados
@@ -94,6 +102,7 @@ pt-BR:
outbox_url: URL da Outbox
perform_full_suspension: Efetue suspensão total
profile_url: URL do perfil
+ promote: Promover
protocol: Protocolo
public: Público
push_subscription_expires: Inscrição PuSH expira
@@ -101,6 +110,11 @@ pt-BR:
reset: Anular
reset_password: Modificar senha
resubscribe: Reinscrever-se
+ role: Permissões
+ roles:
+ admin: Administrador
+ moderator: Moderador
+ user: Usuário
salmon_url: Salmon URL
search: Pesquisar
shared_inbox_url: URL da Inbox Compartilhada
@@ -130,11 +144,16 @@ pt-BR:
enable: Habilitar
enabled_msg: Emoji habilitado com sucesso!
image_hint: PNG de até 50KB
+ listed: Listado
new:
title: Adicionar novo emoji customizado
+ overwrite: Sobrescrever
shortcode: Atalho
shortcode_hint: Pelo menos 2 caracteres, apenas caracteres alfanuméricos e underscores
title: Emojis customizados
+ unlisted: Não listado
+ update_failed_msg: Não foi possível atualizar esse emoji
+ updated_msg: Emoji atualizado com sucesso!
upload: Enviar
domain_blocks:
add_new: Adicionar novo
@@ -373,6 +392,7 @@ pt-BR:
following: Pessoas que você segue
muting: Lista de silêncio
upload: Enviar
+ in_memoriam_html: Em memória de
landing_strip_html: "%{name} é um usuário no %{link_to_root_path}. Você pode segui-lo ou interagir com ele se você tiver uma conta em qualquer lugar no fediverso."
landing_strip_signup_html: Se não, você pode se cadastrar aqui.
media_attachments:
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 9ca08831e0..7c9caec14c 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -1,39 +1,77 @@
---
ru:
about:
+ about_hashtag_html: Это публичные статусы, отмеченные хэштегом #%{hashtag}. Вы можете взаимодействовать с ними при наличии у Вас аккаунта в глобальной сети Mastodon.
about_mastodon_html: Mastodon - это свободная социальная сеть с открытым исходным кодом. Как децентрализованная альтернатива коммерческим платформам, Mastodon предотвращает риск монополизации Вашего общения одной компанией. Выберите сервер, которому Вы доверяете — что бы Вы ни выбрали, Вы сможете общаться со всеми остальными. Любой может запустить свой собственный узел Mastodon и участвовать в социальной сети совершенно бесшовно.
about_this: Об этом узле
closed_registrations: В данный момент регистрация на этом узле закрыта.
contact: Связаться
+ contact_missing: Не установлено
+ contact_unavailable: Недоступен
description_headline: Что такое %{domain}?
domain_count_after: другими узлами
domain_count_before: Связан с
+ extended_description_html: |
+ Хорошее место для правил
+ Расширенное описание еще не настроено.
+ features:
+ humane_approach_body: Наученный ошибками других проектов, Mastodon направлен на выбор этичных решений в борьбе со злоупотреблениями возможностями социальных сетей.
+ humane_approach_title: Человечный подход
+ not_a_product_body: Mastodon - не коммерческая сеть. Здесь нет рекламы, сбора данных, отгороженных мест. Здесь нет централизованного управления.
+ not_a_product_title: Вы - человек, а не продукт
+ real_conversation_body: С 500 символами в Вашем распоряжении и поддержкой предупреждений о содержании статусов Вы сможете выражать свои мысли так, как Вы этого хотите.
+ real_conversation_title: Создан для настоящего общения
+ within_reach_body: Различные приложения для iOS, Android и других платформ, написанные благодаря дружественной к разработчикам экосистеме API, позволят Вам держать связь с Вашими друзьями где угодно.
+ within_reach_title: Всегда под рукой
+ find_another_instance: Найти другой узел
+ generic_description: "%{domain} - один из серверов сети"
+ hosted_on: Mastodon размещен на %{domain}
+ learn_more: Узнать больше
other_instances: Другие узлы
source_code: Исходный код
status_count_after: статусов
status_count_before: Опубликовано
user_count_after: пользователей
user_count_before: Здесь живет
+ what_is_mastodon: Что такое Mastodon?
accounts:
follow: Подписаться
followers: Подписчики
following: Подписан(а)
+ media: Медиаконтент
nothing_here: Здесь ничего нет!
people_followed_by: Люди, на которых подписан(а) %{name}
people_who_follow: Подписчики %{name}
posts: Посты
+ posts_with_replies: Посты с ответами
remote_follow: Подписаться на удаленном узле
+ reserved_username: Имя пользователя зарезервировано
+ roles:
+ admin: Администратор
unfollow: Отписаться
admin:
+ account_moderation_notes:
+ account: Модератор
+ create: Создать
+ created_at: Дата
+ created_msg: Заметка модератора успешно создана!
+ delete: Удалить
+ destroyed_msg: Заметка модератора успешно удалена!
accounts:
are_you_sure: Вы уверены?
+ confirm: Подтвердить
+ confirmed: Подтверждено
+ disable_two_factor_authentication: Отключить 2FA
display_name: Отображаемое имя
domain: Домен
edit: Изменить
email: E-mail
feed_url: URL фида
followers: Подписчики
+ followers_url: URL подписчиков
follows: Подписки
+ inbox_url: URL входящих
+ ip: IP
location:
all: Все
local: Локальные
@@ -45,6 +83,7 @@ ru:
silenced: Заглушенные
suspended: Заблокированные
title: Модерация
+ moderation_notes: Заметки модератора
most_recent_activity: Последняя активность
most_recent_ip: Последний IP
not_subscribed: Не подписаны
@@ -52,19 +91,51 @@ ru:
alphabetic: По алфавиту
most_recent: По дате
title: Порядок
+ outbox_url: URL исходящих
perform_full_suspension: Полная блокировка
profile_url: URL профиля
+ protocol: Протокол
public: Публичный
push_subscription_expires: Подписка PuSH истекает
+ redownload: Обновить аватар
+ reset: Сбросить
reset_password: Сбросить пароль
+ resubscribe: Переподписаться
salmon_url: Salmon URL
+ search: Поиск
+ shared_inbox_url: URL общих входящих
+ show:
+ created_reports: Жалобы, отправленные этим аккаунтом
+ report: жалоба
+ targeted_reports: Жалобы на этот аккаунт
silence: Глушение
statuses: Статусы
+ subscribe: Подписаться
title: Аккаунты
undo_silenced: Снять глушение
undo_suspension: Снять блокировку
+ unsubscribe: Отписаться
username: Имя пользователя
web: WWW
+ custom_emojis:
+ copied_msg: Локальная копия эмодзи успешно создана
+ copy: Скопироват
+ copy_failed_msg: Не удалось создать локальную копию эмодзи
+ created_msg: Эмодзи успешно создано!
+ delete: Удалить
+ destroyed_msg: Эмодзи успешно удалено!
+ disable: Отключить
+ disabled_msg: Эмодзи успешно отключено
+ emoji: Эмодзи
+ enable: Включить
+ enabled_msg: Эмодзи успешно включено
+ image_hint: PNG до 50KB
+ new:
+ title: Добавить новое эмодзи
+ shortcode: Шорткод
+ shortcode_hint: Как минимум 2 символа, только алфавитно-цифровые символы и подчеркивания
+ title: Собственные эмодзи
+ upload: Загрузить
domain_blocks:
add_new: Добавить новую
created_msg: Блокировка домена обрабатывается
@@ -74,13 +145,15 @@ ru:
create: Создать блокировку
hint: Блокировка домена не предотвратит создание новых аккаунтов в базе данных, но ретроактивно и автоматически применит указанные методы модерации для этих аккаунтов.
severity:
- desc_html: "Глушение сделает статусы аккаунта невидимыми для всех, кроме их подписчиков. Блокировка удалит весь контент аккаунта, включая мультимедийные вложения и данные профиля."
+ desc_html: "Глушение сделает статусы аккаунта невидимыми для всех, кроме их подписчиков. Блокировка удалит весь контент аккаунта, включая мультимедийные вложения и данные профиля. Используйте Ничего, если хотите только запретить медиаконтент."
+ noop: Ничего
silence: Глушение
suspend: Блокировка
title: Новая доменная блокировка
reject_media: Запретить медиаконтент
reject_media_hint: Удаляет локально хранимый медиаконтент и запрещает его загрузку в будущем. Не имеет значения в случае блокировки.
severities:
+ noop: Ничего
silence: Глушение
suspend: Блокировка
severity: Строгость
@@ -97,13 +170,34 @@ ru:
undo: Отменить
title: Доменные блокировки
undo: Отемнить
+ email_domain_blocks:
+ add_new: Добавить новую
+ created_msg: Доменная блокировка еmail успешно создана
+ delete: Удалить
+ destroyed_msg: Доменная блокировка еmail успешно удалена
+ domain: Домен
+ new:
+ create: Создать блокировку
+ title: Новая доменная блокировка еmail
+ title: Доменная блокировка email
+ instances:
+ account_count: Известных аккаунтов
+ domain_name: Домен
+ reset: Сбросить
+ search: Поиск
+ title: Известные узлы
reports:
+ action_taken_by: 'Действие предпринято:'
+ are_you_sure: Вы уверены?
comment:
label: Комментарий
none: Нет
delete: Удалить
id: ID
mark_as_resolved: Отметить как разрешенную
+ nsfw:
+ 'false': Показать мультимедийные вложения
+ 'true': Скрыть мультимедийные вложения
report: 'Жалоба #%{id}'
reported_account: Аккаунт нарушителя
reported_by: Отправитель жалобы
@@ -116,6 +210,9 @@ ru:
unresolved: Неразрешенные
view: Просмотреть
settings:
+ bootstrap_timeline_accounts:
+ desc_html: Разделяйте имена пользователей запятыми. Сработает только для локальных незакрытых аккаунтов. По умолчанию включены все локальные администраторы.
+ title: Подписки по умолчанию для новых пользователей
contact_information:
email: Введите публичный e-mail
username: Введите имя пользователя
@@ -123,7 +220,11 @@ ru:
closed_message:
desc_html: Отображается на титульной странице, когда закрыта регистрация
Можно использовать HTML-теги
title: Сообщение о закрытой регистрации
+ deletion:
+ desc_html: Позволяет всем удалять собственные аккаунты
+ title: Разрешить удаление аккаунтов
open:
+ desc_html: Позволяет любому создавать аккаунт
title: Открыть регистрацию
site_description:
desc_html: Отображается в качестве параграфа на титульной странице и используется в качестве мета-тега.
Можно использовать HTML-теги, в особенности <a>
и <em>
.
@@ -131,8 +232,32 @@ ru:
site_description_extended:
desc_html: Отображается на странице дополнительной информации
Можно использовать HTML-теги
title: Расширенное описание сайта
+ site_terms:
+ desc_html: Вы можете добавить сюда собственную политику конфиденциальности, пользовательское соглашение и другие документы. Можно использовать теги HTML.
+ title: Условия использования
site_title: Название сайта
+ thumbnail:
+ desc_html: Используется для предпросмотра с помощью OpenGraph и API. Рекомендуется разрешение 1200x630px
+ title: Картинка узла
+ timeline_preview:
+ desc_html: Показывать публичную ленту на целевой странице
+ title: Предпросмотр ленты
title: Настройки сайта
+ statuses:
+ back_to_account: Назад к странице аккаунта
+ batch:
+ delete: Удалить
+ nsfw_off: Выключить NSFW
+ nsfw_on: Включить NSFW
+ execute: Выполнить
+ failed_to_execute: Не удалось выполнить
+ media:
+ hide: Скрыть медиаконтент
+ show: Показать медиаконтент
+ title: Медиаконтент
+ no_media: Без медиаконтента
+ title: Статусы аккаунта
+ with_media: С медиаконтентом
subscriptions:
callback_url: Callback URL
confirmed: Подтверждено
@@ -141,18 +266,31 @@ ru:
title: WebSub
topic: Тема
title: Администрирование
+ admin_mailer:
+ new_report:
+ body: "%{reporter} подал(а) жалобу на %{target}"
+ subject: Новая жалоба, узел %{instance} (#%{id})
application_mailer:
+ salutation: "%{name},"
settings: 'Изменить настройки e-mail: %{link}'
signature: Уведомления Mastodon от %{instance}
view: 'Просмотр:'
applications:
+ created: Приложение успешно создано
+ destroyed: Приложение успешно удалено
invalid_url: Введенный URL неверен
+ regenerate_token: Повторно сгенерировать токен доступа
+ token_regenerated: Токен доступа успешно сгенерирован
+ warning: Будьте очень внимательны с этими данными. Не делитесь ими ни с кем!
+ your_token: Ваш токен доступа
auth:
+ agreement_html: Создавая аккаунт, вы соглашаетесь с нашими правилами поведения и политикой конфиденциальности.
change_password: Изменить пароль
delete_account: Удалить аккаунт
delete_account_html: Если Вы хотите удалить свой аккаунт, вы можете перейти сюда. У Вас будет запрошено подтверждение.
didnt_get_confirmation: Не получили инструкцию для подтверждения?
forgot_password: Забыли пароль?
+ invalid_reset_password_token: Токен сброса пароля неверен или устарел. Пожалуйста, запросите новый.
login: Войти
logout: Выйти
register: Зарегистрироваться
@@ -162,6 +300,12 @@ ru:
authorize_follow:
error: К сожалению, при поиске удаленного аккаунта возникла ошибка
follow: Подписаться
+ follow_request: 'Вы отправили запрос на подписку:'
+ following: 'Ура! Теперь Вы подписаны на:'
+ post_follow:
+ close: Или просто закрыть это окно.
+ return: Вернуться к профилю пользователя
+ web: Перейти к WWW
title: Подписаться на %{acct}
datetime:
distance_in_words:
@@ -193,7 +337,10 @@ ru:
content: Проверка безопасности не удалась. Возможно, Вы блокируете cookies?
title: Проверка безопасности не удалась.
'429': Слишком много запросов
- noscript_html: Для работы с Mastodon, пожалуйста, включите JavaScript.
+ '500':
+ content: Приносим извинения, но на нашей стороне что-то пошло не так.
+ title: Страница неверна
+ noscript_html: Для работы с Mastodon, пожалуйста, включите JavaScript. Кроме того, вы можете использовать одно из приложений Mastodon для Вашей платформы.
exports:
blocks: Список блокировки
csv: CSV
@@ -265,23 +412,30 @@ ru:
number:
human:
decimal_units:
- format: "%n%u"
+ format: "%n %u"
units:
- billion: B
- million: M
+ billion: млрд
+ million: млн
quadrillion: Q
- thousand: K
- trillion: T
+ thousand: тыс
+ trillion: трлн
unit: ''
pagination:
next: След
prev: Пред
truncate: "…"
+ preferences:
+ languages: Языки
+ other: Другое
+ publishing: Публикация
+ web: WWW
push_notifications:
favourite:
title: Ваш статус понравился %{name}
follow:
title: "%{name} теперь подписан(а) на Вас"
+ group:
+ title: "%{count} уведомлений"
mention:
action_boost: Продвинуть
action_expand: Развернуть
@@ -335,16 +489,24 @@ ru:
authorized_apps: Авторизованные приложения
back: Назад в Mastodon
delete: Удаление аккаунта
+ development: Разработка
edit_profile: Изменить профиль
export: Экспорт данных
followers: Авторизованные подписчики
import: Импорт
+ notifications: Уведомления
preferences: Настройки
settings: Опции
two_factor_authentication: Двухфакторная аутентификация
+ your_apps: Ваши приложения
statuses:
open_in_web: Открыть в WWW
over_character_limit: превышен лимит символов (%{max})
+ pin_errors:
+ limit: Слишком много закрепленных статусов
+ ownership: Нельзя закрепить чужой статус
+ private: Нельзя закрепить непубличный статус
+ reblog: Нельзя закрепить продвинутый статус
show_more: Подробнее
visibilities:
private: Для подписчиков
@@ -359,6 +521,8 @@ ru:
sensitive_content: Чувствительный контент
terms:
title: Условия обслуживания и политика конфиденциальности %{instance}
+ themes:
+ default: Mastodon
time:
formats:
default: "%b %d, %Y, %H:%M"
@@ -367,11 +531,13 @@ ru:
description_html: При включении двухфакторной аутентификации, вход потребует от Вас использования Вашего телефона, который сгенерирует входные токены.
disable: Отключить
enable: Включить
+ enabled: Двухфакторная аутентификация включена
enabled_success: Двухфакторная аутентификация успешно включена
generate_recovery_codes: Сгенерировать коды восстановления
instructions_html: "Отсканируйте этот QR-код с помощью Google Authenticator или другого подобного приложения на Вашем телефоне. С этого момента приложение будет генерировать токены, которые будет необходимо ввести для входа."
lost_recovery_codes: Коды восстановления позволяют вернуть доступ к аккаунту в случае утери телефона. Если Вы потеряли Ваши коды восстановления, вы можете заново сгенерировать их здесь. Ваши старые коды восстановления будут аннулированы.
manual_instructions: 'Если Вы не можете отсканировать QR-код и хотите ввести его вручную, секрет представлен здесь открытым текстом:'
+ recovery_codes: Коды восстановления
recovery_codes_regenerated: Коды восстановления успешно сгенерированы
recovery_instructions_html: В случае утери доступа к Вашему телефону Вы можете использовать один из кодов восстановления, указанных ниже, чтобы вернуть доступ к аккаунту. Держите коды восстановления в безопасности, например, распечатав их и храня с другими важными документами.
setup: Настроить
@@ -379,3 +545,4 @@ ru:
users:
invalid_email: Введенный e-mail неверен
invalid_otp_token: Введен неверный код
+ signed_in_as: 'Выполнен вход под именем:'
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index aafae48cec..faf41f316c 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -54,6 +54,7 @@ en:
interactions:
must_be_follower: Block notifications from non-followers
must_be_following: Block notifications from people you don't follow
+ must_be_following_dm: Block direct messages from people you don't follow
notification_emails:
digest: Send digest e-mails
favourite: Send e-mail when someone favourites your status
diff --git a/config/locales/simple_form.oc.yml b/config/locales/simple_form.oc.yml
index d43c0d7eb1..f178d1857a 100644
--- a/config/locales/simple_form.oc.yml
+++ b/config/locales/simple_form.oc.yml
@@ -13,7 +13,7 @@ oc:
one: Demòra encara 1 caractèr
other: Demòran encara %{count} caractèrs
setting_noindex: Aquò es destinat a vòstre perfil public e vòstra pagina d’estatuts
- setting_theme: Aquò càmbia lo tèma grafic de Mastodon quand sètz connectat qualque siaque lo periferic.
+ setting_theme: Aquò càmbia lo tèma grafic de Mastodon quand sètz connectat qual que siasque lo periferic.
imports:
data: Fichièr CSV exportat d’una autra instància Mastodon
sessions:
diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml
index 68f84d1095..8b539662ca 100644
--- a/config/locales/simple_form.pl.yml
+++ b/config/locales/simple_form.pl.yml
@@ -58,6 +58,7 @@ pl:
interactions:
must_be_follower: Nie wyświetlaj powiadomień od osób, które Cię nie śledzą
must_be_following: Nie wyświetlaj powiadomień od osób, których nie śledzisz
+ must_be_following_dm: Nie wyświetlaj wiadomości bezpośrednich od osób, których nie śledzisz
notification_emails:
digest: Wysyłaj podsumowania e-mailem
favourite: Powiadamiaj mnie e-mailem, gdy ktoś polubi mój wpis
diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml
index 22cae52717..9d60e01711 100644
--- a/config/locales/simple_form.pt-BR.yml
+++ b/config/locales/simple_form.pt-BR.yml
@@ -4,6 +4,7 @@ pt-BR:
hints:
defaults:
avatar: PNG, GIF or JPG. Arquivos de até 2MB. Eles serão diminuídos para 120x120px
+ digest: Enviado após um longo período de inatividade com um resumo das menções que você recebeu em sua ausência.
display_name:
one: 1 caracter restante
other: %{count} caracteres restantes
@@ -13,6 +14,7 @@ pt-BR:
one: 1 caracter restante
other: %{count} caracteres restantes
setting_noindex: Afeta seu perfil público e as páginas de suas postagens
+ setting_theme: Afeta a aparência do Mastodon quando em sua conta em qualquer aparelho.
imports:
data: Arquivo CSV exportado de outra instância do Mastodon
sessions:
@@ -42,7 +44,9 @@ pt-BR:
setting_default_sensitive: Sempre marcar mídia como sensível
setting_delete_modal: Mostrar diálogo de confirmação antes de deletar uma postagem
setting_noindex: Não quero ser indexado por mecanismos de busca
+ setting_reduce_motion: Reduz movimento em animações
setting_system_font_ui: Usar a fonte padrão de seu sistema
+ setting_theme: Tema do site
setting_unfollow_modal: Mostrar diálogo de confirmação antes de deixar de seguir alguém
severity: Gravidade
type: Tipo de importação
diff --git a/config/locales/simple_form.ru.yml b/config/locales/simple_form.ru.yml
index 3bdb7870f4..1b780ac26d 100644
--- a/config/locales/simple_form.ru.yml
+++ b/config/locales/simple_form.ru.yml
@@ -4,6 +4,7 @@ ru:
hints:
defaults:
avatar: PNG, GIF или JPG. Максимально 2MB. Будет уменьшено до 120x120px
+ digest: Отсылается после долгого периода неактивности с общей информацией упоминаний, полученных в Ваше отсутствие
display_name:
few: Осталось %{count} символа
many: Осталось %{count} символов
@@ -17,6 +18,7 @@ ru:
one: Остался 1 символ
other: Осталось %{count} символов
setting_noindex: Относится к Вашему публичному профилю и страницам статусов
+ setting_theme: Влияет на внешний вид Mastodon при выполненном входе в аккаунт.
imports:
data: Файл CSV, экспортированный с другого узла Mastodon
sessions:
@@ -46,6 +48,8 @@ ru:
setting_default_sensitive: Всегда отмечать медиаконтент как чувствительный
setting_delete_modal: Показывать диалог подтверждения перед удалением
setting_noindex: Отказаться от индексации в поисковых машинах
+ setting_reduce_motion: Уменьшить движение в анимации
+ setting_site_theme: Тема сайта
setting_system_font_ui: Использовать шрифт системы по умолчанию
setting_unfollow_modal: Показывать диалог подтверждения перед тем, как отписаться от аккаунта
severity: Строгость
diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml
index eafaa972ec..f8c9461ad6 100644
--- a/config/locales/simple_form.zh-CN.yml
+++ b/config/locales/simple_form.zh-CN.yml
@@ -3,49 +3,60 @@ zh-CN:
simple_form:
hints:
defaults:
- avatar: 最大 2MB,限 PNG, GIF 或 JPG 格式,将缩到 120x120px
- display_name: 不起过 30 个字符
- header: 最大 2MB,限 PNG, GIF 或 JPG 格式,将缩到 700x335px
- locked: 默认仅向粉丝公开嘟文,需要手工批准粉丝关注请求。
- note: 最多 160 个字符
+ avatar: 文件大小限制 2MB,只支持 PNG、GIF 或 JPG 格式。图片分辨率将会压缩至 120×120px
+ digest: 在你长时间未登录的情况下,我们会向你发送一份含有提及你的嘟文的摘要邮件
+ display_name: 还能输入 %{count} 个字符
+ header: 文件大小限制 2MB,只支持 PNG、GIF 或 JPG 格式。图片分辨率将会压缩至 700×335px
+ locked: 你需要手动审核所有关注请求
+ note: 还能输入 %{count} 个字符
+ setting_noindex: 此设置会影响到你的公开个人资料以及嘟文页面
+ setting_theme: 此设置会影响到你从任意设备登录时 Mastodon 的显示样式
imports:
- data: 从其他服务器节点导出的 CSV 文件
+ data: 请上传从其他 Mastodon 实例导出的 CSV 文件
sessions:
- otp: 输入你手机生成的两步验证码,或者恢复代码。
+ otp: 输入你手机上生成的双重认证码,或者任意一个恢复代码。
user:
- filtered_languages: 下列被选择的语言的嘟文将不会出现在你的公共时间轴上。
+ filtered_languages: 勾选语言的嘟文将不会出现在你的公共时间轴上
labels:
defaults:
avatar: 头像
confirm_new_password: 确认新密码
confirm_password: 确认密码
current_password: 当前密码
- data: 数据
- display_name: 显示名
- email: 邮箱
- filtered_languages: 屏蔽下列语言的嘟文
- header: 个人页面顶部
+ data: 数据文件
+ display_name: 昵称
+ email: 电子邮件地址
+ filtered_languages: 语言过滤
+ header: 个人资料页横幅图片
locale: 语言
- locked: 隐私模式(锁嘟)
+ locked: 保护你的帐户(锁嘟)
new_password: 新密码
note: 简介
- otp_attempt: 两步认证码
+ otp_attempt: 双重认证代码
password: 密码
+ setting_auto_play_gif: 自动播放 GIF 动画
setting_boost_modal: 在转嘟前询问我
- setting_default_privacy: 嘟文默认隐私度
- severity: 等级
+ setting_default_privacy: 嘟文默认可见范围
+ setting_default_sensitive: 总是将我发送的媒体文件标记为敏感内容
+ setting_delete_modal: 在删除嘟文前询问我
+ setting_noindex: 禁止搜索引擎建立索引
+ setting_reduce_motion: 降低过渡动画效果
+ setting_system_font_ui: 使用系统默认字体
+ setting_theme: 站点主题
+ setting_unfollow_modal: 在取消关注前询问我
+ severity: 级别
type: 导入数据类型
username: 用户名
interactions:
- must_be_follower: 隐藏没有关注你的用户的通知
- must_be_following: 隐藏你不关注的用户的通知
+ must_be_follower: 屏蔽来自未关注你的用户的通知
+ must_be_following: 屏蔽来自你未关注的用户的通知
notification_emails:
digest: 发送摘要邮件
- favourite: 当有用户赞了你的嘟文时,发电邮通知
- follow: 当有用户关注你时,发电邮通知
- follow_request: 当有用户要求关注你时,发电邮通知
- mention: 当有用户在嘟文中提及你时,发电邮通知
- reblog: 当有用户转嘟了你的嘟文时,发电邮通知
+ favourite: 当有用户收藏了你的嘟文时,发送电子邮件提醒我
+ follow: 当有用户关注你时,发送电子邮件提醒我
+ follow_request: 当有用户向你发送关注请求时,发送电子邮件提醒我
+ mention: 当有用户在嘟文中提及你时,发送电子邮件提醒我
+ reblog: 当有用户转嘟了你的嘟文时,发送电子邮件提醒我
'no': 否
required:
mark: "*"
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index 44d0f38030..b50c34fd0c 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -1,196 +1,350 @@
---
zh-CN:
about:
- about_mastodon_html: Mastodon(长毛象)是一个自由、开放源码的社交网站。它是一个分布式的服务,避免你的通信被单一商业机构垄断操控。请你选择一家你信任的 Mastodon 实例,在上面创建帐号,然后你就可以和任一 Mastodon 实例上的用户互通,享受无缝的社交交流。
+ about_hashtag_html: 这里展示的是带有话题标签 #%{hashtag} 的公开嘟文。如果你在象毛世界中拥有一个帐户,就可以加入讨论。
+ about_mastodon_html: Mastodon(长毛象)是一个基于开放式网络协议和自由、开源软件建立的社交网络,有着类似于电子邮件的分布式设计。
about_this: 关于本实例
- closed_registrations: 这个实例目前不开放注册 _(:3」∠)_
+ closed_registrations: 这个实例目前没有开放注册。不过,你可以前往其他实例注册一个帐户,同样可以加入到这个网络中哦!
contact: 联络
+ contact_missing: 未设定
+ contact_unavailable: 未公开
description_headline: 关于 %{domain}
domain_count_after: 个其它实例
domain_count_before: 现已接入
- other_instances: 其它实例
+ extended_description_html: |
+ 这里可以写一些规定
+ 本站尚未设置详细介绍。
+ features:
+ humane_approach_body: Mastodon 从其他网络的失败经验中汲取了教训,致力于在与错误的社交媒体使用方式的斗争中做出符合伦理化设计的选择。
+ humane_approach_title: 更加以人为本
+ not_a_product_body: Mastodon 绝非一个商业网络。这里既没有广告,也没有数据挖掘,更没有围墙花园。中心机构在这里不复存在。
+ not_a_product_title: 作为用户,你并非一件商品
+ real_conversation_body: Mastodon 有着高达 500 字的字数限制,以及对内容的细化控制和媒体警告提示的支持,只为让你能够畅所欲言。
+ real_conversation_title: 为真正的交流而生
+ within_reach_body: 通过一个面向开发者友好的 API 生态系统,Mastodon 让你可以随时随地通过众多 iOS、Android 以及其他平台的应用与朋友们保持联系。
+ within_reach_title: 始终触手可及
+ find_another_instance: 寻找另一个实例
+ generic_description: "%{domain} 是这个庞大网络中的一台服务器"
+ hosted_on: 一个在 %{domain} 上运行的 Mastodon 实例
+ learn_more: 详细了解
+ other_instances: 其他实例
source_code: 源码
status_count_after: 条嘟文
status_count_before: 他们共嘟出了
user_count_after: 位用户
user_count_before: 这里共注册有
+ what_is_mastodon: Mastodon 是什么?
accounts:
follow: 关注
- followers: 粉丝
- following: 关注
- nothing_here: 神马都没有!
+ followers: 关注者
+ following: 正在关注
+ media: 媒体
+ nothing_here: 这里神马都没有!
people_followed_by: 正关注
people_who_follow: 粉丝
posts: 嘟文
+ posts_with_replies: 嘟文和回复
remote_follow: 跨站关注
+ reserved_username: 此用户名已保留
+ roles:
+ admin: 管理员
unfollow: 取消关注
admin:
+ account_moderation_notes:
+ account: 管理员
+ create: 新建
+ created_at: 日期
+ created_msg: 管理记录建立成功!
+ delete: 删除
+ destroyed_msg: 管理记录删除成功!
accounts:
are_you_sure: 你确定吗?
+ by_domain: 域名
confirm: 确认
confirmed: 已确认
- disable_two_factor_authentication: 两步认证无效
- display_name: 显示名称
+ demote: 降任
+ disable: 停用
+ disable_two_factor_authentication: 停用双重认证
+ disabled: 已停用
+ display_name: 昵称
domain: 域名
edit: 编辑
- email: 电邮地址
+ email: 电子邮件地址
+ enable: 启用
+ enabled: 已启用
feed_url: 订阅 URL
followers: 关注者
+ followers_url: 关注者(Followers)URL
follows: 正在关注
- ip: IP地址
+ inbox_url: 收件箱(Inbox)URL
+ ip: IP 地址
location:
all: 全部
local: 本地
remote: 远程
- title: 地点
+ title: 位置
+ login_status: 登录状态
media_attachments: 媒体文件
+ memorialize: 设置为追悼帐户
moderation:
all: 全部
- silenced: 被静音的
- suspended: 被停权的
- title: 管理操作
- most_recent_activity: 最新活动
- most_recent_ip: 最新 IP 地址
+ silenced: 已静音
+ suspended: 已封禁
+ title: 帐户状态
+ moderation_notes: 管理记录
+ most_recent_activity: 最后一次活跃的时间
+ most_recent_ip: 最后一次活跃的 IP 地址
not_subscribed: 未订阅
order:
alphabetic: 按字母
most_recent: 按时间
title: 排序
- perform_full_suspension: 实行完全暂停
- profile_url: 个人文件 URL
- public: 公共
- push_subscription_expires: 推送订阅过期
+ outbox_url: 发件箱(Outbox)URL
+ perform_full_suspension: 永久封禁
+ profile_url: 个人资料页面 URL
+ promote: 升任
+ protocol: 协议
+ public: 公开页面
+ push_subscription_expires: PuSH 订阅过期时间
+ redownload: 刷新头像
reset: 重置
reset_password: 重置密码
- salmon_url: Salmon 反馈 URL
+ resubscribe: 重新订阅
+ role: 用户组
+ roles:
+ admin: 管理员
+ moderator: 协管
+ user: 用户
+ salmon_url: Salmon URL
search: 搜索
+ shared_inbox_url: 公用收件箱(Shared Inbox)URL
show:
- created_reports: 这个帐户创建的报告
- report: 报告
- targeted_reports: 关于这个帐户的报告
+ created_reports: 这个帐户提交的举报
+ report: 个举报
+ targeted_reports: 针对这个帐户的举报
silence: 静音
statuses: 嘟文
+ subscribe: 订阅
title: 用户
undo_silenced: 解除静音
- undo_suspension: 解除停权
- username: 用户名称
- web: 用户页面
- domain_blocks:
- add_new: 添加
- created_msg: 正处理域名阻隔
- destroyed_msg: 已撤销域名阻隔
- domain: 域名阻隔
+ undo_suspension: 解除封禁
+ unsubscribe: 取消订阅
+ username: 用户名
+ web: 站内页面
+ custom_emojis:
+ copied_msg: 成功将表情复制到本地
+ copy: 复制
+ copy_failed_msg: 无法将表情复制到本地
+ created_msg: 表情添加成功!
+ delete: 删除
+ destroyed_msg: 表情删除成功!
+ disable: 停用
+ disabled_msg: 表情停用成功
+ emoji: 表情
+ enable: 启用
+ enabled_msg: 表情启用成功
+ image_hint: PNG 格式,最大 50KB
+ listed: 已显示
new:
- create: 添加域名阻隔
- hint: "「域名阻隔」不会隔绝该域名用户的嘟帐户入本站数据库,但会嘟文抵达后,自动套用特定的审批操作。"
+ title: 添加新的自定义表情
+ overwrite: 覆盖
+ shortcode: 短代码
+ shortcode_hint: 至少 2 个字符,只能使用字母、数字和下划线
+ title: 自定义表情
+ unlisted: 已隐藏
+ update_failed_msg: 表情更新失败!
+ updated_msg: 表情更新成功!
+ upload: 上传
+ domain_blocks:
+ add_new: 添加新条目
+ created_msg: 正在进行域名屏蔽
+ destroyed_msg: 域名屏蔽已撤销
+ domain: 域名
+ new:
+ create: 添加域名屏蔽
+ hint: 域名屏蔽不会阻止该域名下的帐户进入本站的数据库,但是会对来自这个域名的帐户自动进行预先设置的管理操作。
severity:
- desc_html: "「自动静音」令该域名用户的嘟文,设为只对关注者显示,没有关注的人会看不到。 「自动除名」会自动将该域名用户的嘟文、媒体文件、个人资料从本服务器实例删除。"
+ desc_html: 选择自动静音会将该域名下帐户发送的嘟文设置为仅关注者可见;选择自动封禁会将该域名下帐户发送的嘟文、媒体文件以及个人资料数据从本实例上删除;如果你只是想拒绝接收来自该域名的任何媒体文件,请选择无。
+ noop: 无
silence: 自动静音
- suspend: 自动除名
- title: 添加域名阻隔
- reject_media: 拒绝媒体文件
- reject_media_hint: 删除本地缓存的媒体文件,再也不在未来下载这个站点的文件。和自动除名无关。
+ suspend: 自动封禁
+ title: 添加域名屏蔽
+ reject_media: 拒绝接收媒体文件
+ reject_media_hint: 删除本地已缓存的媒体文件,并且不再接收来自该域名的任何媒体文件。此选项不影响封禁
severities:
+ noop: 无
silence: 自动静音
- suspend: 自动除名
- severity: 阻隔程度
+ suspend: 自动封禁
+ severity: 屏蔽级别
show:
- affected_accounts:
- one: 数据库中有1个帐户受影响
- other: 数据库中有%{count}个帐户受影响
+ affected_accounts: 将会影响到数据库中的 %{count} 个帐户
retroactive:
silence: 对此域名的所有帐户取消静音
- suspend: 对此域名的所有帐户取消除名
- title: 撤销 %{domain} 的域名阻隔
+ suspend: 对此域名的所有帐户取消封禁
+ title: 撤销对 %{domain} 的域名屏蔽
undo: 撤销
- title: 域名阻隔
+ title: 域名屏蔽
undo: 撤销
+ email_domain_blocks:
+ add_new: 添加新条目
+ created_msg: 电子邮件域名屏蔽添加成功
+ delete: 删除
+ destroyed_msg: 电子邮件域名屏蔽删除成功
+ domain: 域名
+ new:
+ create: 添加屏蔽
+ title: 添加电子邮件域名屏蔽
+ title: 电子邮件域名屏蔽
instances:
- account_count: 已知帐号
+ account_count: 已知帐户
domain_name: 域名
+ reset: 重置
+ search: 搜索
title: 已知实例
reports:
- are_you_sure: 你确定吗?
+ action_taken_by: 操作执行者
+ are_you_sure: 你确定吗?
comment:
label: 备注
none: 没有
delete: 删除
id: ID
- mark_as_resolved: 标示为「已处理」
+ mark_as_resolved: 标记为“已处理”
nsfw:
- 'false': NSFW无效
- 'true': NSFW有效
+ 'false': 取消 NSFW 标记
+ 'true': 添加 NSFW 标记
report: '举报 #%{id}'
+ report_contents: 内容
reported_account: 举报用户
- reported_by: 举报者
+ reported_by: 举报人
resolved: 已处理
- silence_account: 将用户静音
+ silence_account: 静音用户
status: 状态
- suspend_account: 将用户停权
- target: 对象
+ suspend_account: 封禁用户
+ target: 被举报人
title: 举报
unresolved: 未处理
view: 查看
settings:
+ bootstrap_timeline_accounts:
+ desc_html: 用半角逗号分隔多个用户名。只能添加来自本站且未开启保护的帐户。如果留空,则默认关注本站所有的管理员。
+ title: 新用户默认关注
contact_information:
- email: 输入一个公开的电邮地址
- username: 输入用户名称
+ email: 输入一个公开的电子邮件地址
+ username: 输入用户名
registrations:
closed_message:
- desc_html: 当本站暂停接受注册时,会显示这个消息。
可使用 HTML
- title: 暂停注册消息
+ desc_html: 本站关闭注册期间的提示信息。可以使用 HTML 标签
+ title: 关闭注册时的提示消息
+ deletion:
+ desc_html: 允许所有人删除自己的帐户
+ title: 开放删除帐户权限
open:
+ desc_html: 允许任何人建立一个帐户
title: 开放注册
site_description:
- desc_html: 在首页显示,及在 meta 标签中用作网站介绍。
你可以在此使用 HTML 标签,尤其是<a>
和 <em>
。
- title: 本站介绍
+ desc_html: 展示在首页以及 meta 标签中的网站简介。可以使用 HTML 标签,包括 <a>
和 <em>
。
+ title: 本站简介
site_description_extended:
- desc_html: 本站详细信息页的內容
你可在此使用 HTML
- title: 本站详细信息
+ desc_html: 可以填写行为守则、规定、指南或其他本站特有的内容。可以使用 HTML 标签
+ title: 本站详细介绍
+ site_terms:
+ desc_html: 可以填写自己的隐私权政策、使用条款或其他法律文本。可以使用 HTML 标签
+ title: 自定义使用条款
site_title: 本站名称
+ thumbnail:
+ desc_html: 用于在 OpenGraph 和 API 中显示预览图。推荐分辨率 1200×630px
+ title: 本站缩略图
+ timeline_preview:
+ desc_html: 在主页显示公开时间线
+ title: 时间线预览
title: 网站设置
+ statuses:
+ back_to_account: 返回帐户信息页
+ batch:
+ delete: 删除
+ nsfw_off: 取消 NSFW 标记
+ nsfw_on: 添加 NSFW 标记
+ execute: 执行
+ failed_to_execute: 执行失败
+ media:
+ hide: 隐藏媒体文件
+ show: 显示媒体文件
+ title: 媒体文件
+ no_media: 不含媒体文件
+ title: 帐户嘟文
+ with_media: 含有媒体文件
subscriptions:
callback_url: 回调 URL
- confirmed: 确定
- expires_in: 期限
- last_delivery: 数据最后送抵时间
- title: WebSub 订阅
- topic: 所订阅资源
+ confirmed: 已确认
+ expires_in: 失效时间
+ last_delivery: 最后一次接收数据的时间
+ title: WebSub
+ topic: Topic
title: 管理
+ admin_mailer:
+ new_report:
+ body: "%{reporter} 举报了 %{target}"
+ subject: 来自 %{instance} 的新举报(#%{id})
application_mailer:
- settings: 更改电邮设置︰%{link}
+ salutation: "%{name},"
+ settings: 更改电子邮件首选项:%{link}
signature: 来自 %{instance} 的 Mastodon 通知
view: 查看:
applications:
+ created: 应用创建成功
+ destroyed: 应用删除成功
invalid_url: URL 无效
+ regenerate_token: 重置访问令牌
+ token_regenerated: 访问令牌重置成功
+ warning: 一定小心,千万不要把它分享给任何人!
+ your_token: 你的访问令牌
auth:
- change_password: 登录凭据
+ agreement_html: 注册即表示你同意我们的使用条款和隐私权政策。
+ change_password: 帐户安全
+ delete_account: 删除帐户
+ delete_account_html: 如果你想删除你的帐户,请点击这里继续。你需要确认你的操作。
didnt_get_confirmation: 没有收到确认邮件?
forgot_password: 忘记密码?
+ invalid_reset_password_token: 密码重置令牌无效或已过期。请重新发起重置密码请求。
login: 登录
logout: 登出
register: 注册
- resend_confirmation: 重发确认邮件
+ resend_confirmation: 重新发送确认邮件
reset_password: 重置密码
set_new_password: 设置新密码
authorize_follow:
error: 对不起,寻找这个跨站用户时出错
follow: 关注
+ follow_request: 关注请求已发送给:
+ following: 成功!你正在关注:
+ post_follow:
+ close: 你也可以直接关闭这个窗口。
+ return: 返回至个人资料页
+ web: 返回本站
title: 关注 %{acct}
datetime:
distance_in_words:
- about_x_hours: "%{count} 小时"
+ about_x_hours: "%{count} 时"
about_x_months: "%{count} 个月"
about_x_years: "%{count} 年"
- almost_x_years: 接近 %{count} 年
+ almost_x_years: "%{count} 年"
half_a_minute: 刚刚
- less_than_x_minutes: "%{count} 分不到"
+ less_than_x_minutes: "%{count} 分"
less_than_x_seconds: 刚刚
- over_x_years: 超过 %{count} 年
+ over_x_years: "%{count} 年"
x_days: "%{count} 天"
x_minutes: "%{count} 分"
x_months: "%{count} 个月"
x_seconds: "%{count} 秒"
+ deletes:
+ bad_password_msg: 想得美,黑客!密码输入错误
+ confirm_password: 输入你当前的密码来验证身份
+ description_html: 继续操作将会永久地、不可撤销地删除你帐户中的内容,并冻结你的帐户。你的用户名将会被保留,以防有人冒用你的身份。
+ proceed: 删除帐户
+ success_msg: 你的帐户已经成功删除
+ warning_html: 我们只能保证本实例上的内容已经被彻底删除。对于已经被广泛传播的内容,它们在本实例以外的某些地方可能仍然可见。此外,失去连接的服务器以及停止接收订阅的服务器上的数据亦无法删除。
+ warning_title: 关于已传播的内容的警告
errors:
'403': 无权查看
'404': 找不到页面
@@ -199,68 +353,71 @@ zh-CN:
content: 无法确认登录信息。你是不是屏蔽了 Cookie?
title: 无法确认登录信息
'429': 被限制
+ '500':
+ content: 抱歉,我们这里出错了。
+ title: 这个页面不正确
+ noscript_html: 请启用 JavaScript 以便使用 Mastodon 网页版应用。你也可以选择适用于你的平台的 Mastodon 应用。
exports:
- blocks: 被你封锁的用户
+ blocks: 屏蔽的用户
csv: CSV
- follows: 你所关注的用户
- mutes: 你所静音的用户
- storage: 媒体容量大小
+ follows: 关注的用户
+ mutes: 静音的用户
+ storage: 媒体文件存储
followers:
domain: 域名
- explanation_html: 想要保护你的嘟文的话,请慎重考虑关注你的人。你的受保护的嘟文会发送到有你的关注者的所有实例上。你也许想要复查一下关注者列表来移除那些你无法信任的关注者。
+ explanation_html: 为保证你的嘟文的隐私安全,你应当时刻留意你的关注者列表。受保护的嘟文将会发送到所有关注者所在的实例上。有些实例使用的软件代码或其管理员可能不会尊重你的隐私设置,因此你应当复查一下关注者列表,并移除那些你无法信任的关注者。
followers_count: 关注者数量
- lock_link: 保护你的帐户
+ lock_link: 为你的帐户开启保护
purge: 从关注者中移除
- success: 从 %{count} 个域名中移除了关注者。
- true_privacy_html: "真正的隐私只能靠端到端加密来实现!"
- unlocked_warning_html: 任何人都可以关注你然后查看被保护的嘟文, %{lock_link} 可以复核和拒绝关注请求。
- unlocked_warning_title: 你的帐户没被保护
+ success: 正在从 %{count} 个域名中移除关注者……
+ true_privacy_html: 请始终铭记:真正的隐私只能靠端到端加密来实现!
+ unlocked_warning_html: 任何人都可以通过关注你来立即查看被保护的嘟文。%{lock_link},即可审核并拒绝关注请求。
+ unlocked_warning_title: 你的帐户未受到保护
generic:
- changes_saved_msg: 更改已被保存。
+ changes_saved_msg: 更改保存成功!
powered_by: 基于 %{link} 构建
- save_changes: 保存
+ save_changes: 保存更改
validation_errors:
- one: 出错啦!请确认以下出错的地方,修改之后再来一次:
- other: 出错啦!请确认以下 %{count} 处出错的地方,修改之后再来一次:
+ one: 出错啦!检查一下下面出错的地方吧
+ other: 出错啦!检查一下下面 %{count} 处出错的地方吧
imports:
- preface: 你可以在此导入你在其他服务器实例所导出的数据文件,包括︰你所关注、封锁的用户。
- success: 你已成功上载数据文件,我们正将数据导入,请稍候
+ preface: 你可以在此导入你在其他实例导出的数据,比如你所关注或屏蔽的用户列表。
+ success: 数据上传成功,正在处理中
types:
- blocking: 封锁名单
- following: 关注名单
- muting: 静音名单
- upload: 上载
- landing_strip_html: "%{name} 是一个在 %{link_to_root_path} 的用户。只要你是象毛世界里(Mastodon、GNU social)任一服务器实例的用户,便可以跨站关注此站用户并与其沟通。"
- landing_strip_signup_html: 如果你没有这类帐户,欢迎在此处登记。
+ blocking: 屏蔽列表
+ following: 关注列表
+ muting: 静音列表
+ upload: 上传
+ in_memoriam_html: 谨此悼念。
+ landing_strip_html: "%{name} 是一位来自 %{link_to_root_path} 的用户。如果你想关注这个人或者与这个人互动,你需要在任意一个 Mastodon 实例或与其兼容的网站上拥有一个帐户。"
+ landing_strip_signup_html: 还没有这种帐户?你可以在本站注册一个。
media_attachments:
validations:
- images_and_video: 无法添加视频到一个已经包含图片的嘟文中
- too_many: 最多只能添加4张图片
+ images_and_video: 无法在嘟文中同时插入视频和图片
+ too_many: 最多只能添加 4 张图片
notification_mailer:
digest:
- body: 自从你在%{since}使用%{instance}以后,错过了这些嘟嘟滴滴:
- mention: "%{name} 在此提及了你︰"
+ body: 自从你最后一次(时间是%{since})登录 %{instance} 以来,你错过了这些嘟嘟滴滴:
+ mention: "%{name} 在嘟文中提到了你:"
new_followers_summary:
- one: 有人关注你了!耶!
- other: 有 %{count} 个人关注了你!别激动!
- subject:
- one: "你有一个新通知 \U0001F418"
- other: "%{count} 个通知太多,赶快去看看 \U0001F418"
+ one: 有个人关注了你!耶!
+ other: 有 %{count} 个人关注了你!好棒!
+ subject: "自从你最后一次登录以来,你错过了 %{count} 条新通知 \U0001F418"
favourite:
- body: "%{name} 收藏了你"
- subject: "%{name} 给你点了收藏"
+ body: 你的嘟文被 %{name} 收藏了:
+ subject: "%{name} 收藏了你的嘟文"
follow:
- body: "%{name} 关注了你"
+ body: "%{name} 关注了你!"
subject: "%{name} 关注了你"
follow_request:
- body: "%{name} 要求关注你"
- subject: 等候关注你的用户︰ %{name}
+ body: "%{name} 请求关注你"
+ subject: 待审核的关注者:%{name}
mention:
- body: "%{name} 在文章中提及你︰"
- subject: "%{name} 在文章中提及你"
+ body: "%{name} 在嘟文中提到了你:"
+ subject: "%{name} 提到了你"
reblog:
- body: 你的嘟文得到 %{name} 的转嘟
- subject: "%{name} 转嘟(嘟嘟滴)了你的嘟文"
+ body: 你的嘟文被 %{name} 转嘟了:
+ subject: "%{name} 转嘟了你的嘟文"
number:
human:
decimal_units:
@@ -275,54 +432,197 @@ zh-CN:
pagination:
next: 下一页
prev: 上一页
- truncate: "……"
+ truncate: "…"
+ preferences:
+ languages: 语言
+ other: 其他
+ publishing: 发布
+ web: 站内
+ push_notifications:
+ favourite:
+ title: "%{name} 收藏了你的嘟文"
+ follow:
+ title: "%{name} 关注了你"
+ group:
+ title: "%{count} 条新通知"
+ mention:
+ action_boost: 转嘟
+ action_expand: 显示更多
+ action_favourite: 收藏
+ title: "%{name} 提到了你"
+ reblog:
+ title: "%{name} 转嘟了你的嘟文"
remote_follow:
- acct: 请输入你的︰用户名称@实例域名
- missing_resource: 无法找到您的帐户转接网址
- proceed: 下一步
- prompt: 你正准备关注︰
+ acct: 请输入你的“用户名@实例域名”
+ missing_resource: 无法确定你的帐户的跳转 URL
+ proceed: 确认关注
+ prompt: 你正准备关注:
+ sessions:
+ activity: 最后一次活跃的时间
+ browser: 浏览器
+ browsers:
+ alipay: 支付宝
+ blackberry: Blackberry
+ chrome: Chrome
+ edge: Microsoft Edge
+ firefox: Firefox
+ generic: 未知浏览器
+ ie: Internet Explorer
+ micro_messenger: 微信
+ nokia: Nokia S40 Ovi 浏览器
+ opera: Opera
+ phantom_js: PhantomJS
+ qq: QQ浏览器
+ safari: Safari
+ uc_browser: UC浏览器
+ weibo: 新浪微博
+ current_session: 当前会话
+ description: "%{platform} 上的 %{browser}"
+ explanation: 你的 Mastodon 帐户目前已在这些浏览器上登录。
+ ip: IP 地址
+ platforms:
+ adobe_air: Adobe Air
+ android: Android
+ blackberry: Blackberry
+ chrome_os: ChromeOS
+ firefox_os: Firefox OS
+ ios: iOS
+ linux: Linux
+ mac: Mac
+ other: 未知平台
+ windows: Windows
+ windows_mobile: Windows Mobile
+ windows_phone: Windows Phone
+ revoke: 注销
+ revoke_success: 会话注销成功
+ title: 会话
settings:
authorized_apps: 已授权的应用
back: 回到 Mastodon
+ delete: 删除帐户
+ development: 开发
edit_profile: 更改个人信息
export: 导出
followers: 授权的关注者
import: 导入
+ notifications: 通知
preferences: 首选项
settings: 设置
- two_factor_authentication: 两步认证
+ two_factor_authentication: 双重认证
+ your_apps: 你的应用
statuses:
- open_in_web: 打开网页
+ open_in_web: 在站内打开
over_character_limit: 超过了 %{max} 字的限制
+ pin_errors:
+ limit: 置顶的嘟文条数超出限制
+ ownership: 不能置顶他人的嘟文
+ private: 不能置顶非公开的嘟文
+ reblog: 不能置顶转嘟
show_more: 显示更多
visibilities:
- private: 限关注者
- private_long: 仅向关注者公开
+ private: 仅关注者
+ private_long: 只有关注你的用户能看到
public: 公开
- public_long: 向所有人公开
- unlisted: 于公共时间线中隐藏
- unlisted_long: 公开,但不显示在公共时间线中
+ public_long: 所有人可见,并会出现在公共时间轴上
+ unlisted: 不公开
+ unlisted_long: 所有人可见,但不会出现在公共时间轴上
stream_entries:
- click_to_show: 显示
+ click_to_show: 点击显示
+ pinned: 置顶嘟文
reblogged: 转嘟
sensitive_content: 敏感内容
+ terms:
+ body_html: |
+ 隐私权政策
+
+ 我们收集什么信息?
+
+ 我们从你在我们站点注册开始从你那开始收集信息,并收集关于你在论坛的阅读和写作的数据,并评估分享的内容。
+
+ 当在我们站点注册时,你可能被要求输入你的名字和邮件地址。然而你可以在不用注册的情况下访问站点。你的邮件地将通过一个独一无二的链接验证。如果链接被访问了,我们就知道你控制了该邮件地址。
+
+ 当已注册和发帖时,我们记录发布帖子时的 IP 地址。我们也可能保留服务器日志,其中包括了每一个向我们服务器的请求。
+
+ 我们如何使用你的信息?
+
+ 从你那收集的任何数据将以以下方式使用:
+
+
+ - 改进你的个人体验 — 你的信息帮助我们更好地满足你的个人需求。
+ - 改进我们的站点 — 我们基于信息和我们从你那收到的反馈不断地试图改进我们的站点。
+ - 改善我们的客户服务 — 你的信息帮助我们更有效地回应用户服务请求和支持。
+ - 用于发送阶段性的邮件 — 你提供的邮件地址可能用于接受信息、你想看到的通知或与你用户名有关的回复和询问,或是其他的请求和问题。
+
+
+ 我们如何保护你的信息?
+
+ 我们实现了一系列的安全措施保证你输入、提交或者访问你个人信息的数据安全。
+
+ 数据保存政策是什么?
+
+ 我们将善意地:
+
+
+ - 保存 90 天内的所有向服务器的包含 IP 地址的请求。
+ - 保存 5 年内已注册用户和与他们的帖子有关的 IP 地址。
+
+
+ 我们使用 Cookie 吗?
+
+ 是的。Cookie 是网站或它的服务商通过网页浏览器存储在你电脑硬盘上的小文件(如果你同意)。这些 Cookie 使站点能分辨你的浏览器,并且,如果你注册了一个账户,与你的注册账户关联。
+
+ 我们使用 Cookie 为之后的访问和编译一小段关于站点流量和交互的数据来判断并保存你的个人设置,这样我们可以在之后提供更好的站点体验和工具。我们可能使用第三方服务商来帮助我们更好地理解我们的站点访客。这些服务商是不允许代表我们使用收集的信息,除非是在帮助我们执行和改进我们的站点。
+
+ 我们会在站外提供任何信息吗?
+
+ 我们绝不销售、交易或任何向外转移你个人信息的行为。这不包括帮助我们管理站点、改进站点或给你提供服务的第三方团体,这些团体需要保证对这些信息保密。当我们认为提交你的信息符合法律、我们的站点政策或保护我们或其他人的权利、知识产权或安全时,我们也可能提交你的信息。然而,非个人访问信息可能供其他团体使用,用于市场、广告或其他用途。
+
+ 第三方链接
+
+ 偶尔地,根据我们的判断,我们可能在我们的站点上包括或提供第三方团体的产品或服务。这些第三方站点用于独立和不同的隐私政策。因此我们对链接到的站点或活动没有责任和权利。尽管如此,我们寻求保护我们的整个站点并且欢迎你给这些站点反馈。
+
+ 儿童在线隐私保护法案合规
+
+ 我们的站点、产品和服务提供给 13 岁以上的人们。如果服务器位于美国,并且你小于 13 岁,根据儿童在线隐私保护法案合规,不要使用这个站点。
+
+ 仅用于在线隐私政策
+
+ 这个线上隐私政策只适用于通过我们站点收集到的信息,并不包括线下收集的信息。
+
+ 你的同意
+
+ 你使用站点的同时,代表你同意了我们网站的隐私政策。
+
+ 隐私政策的更改
+
+ 如果我们决定更改我们的隐私政策,我们将在此页更新这些改变。
+
+ 文档以 CC-BY-SA 发布。最后更新时间为2013年5月31日。
+
+ 原文出自 Discourse 隐私权政策。
+ title: "%{instance} 使用条款和隐私权政策"
+ themes:
+ default: Mastodon
time:
formats:
default: "%Y年%-m月%d日 %H:%M"
two_factor_authentication:
- code_hint: 请输入你认证器产生的代码,以确认设置
- description_html: 当你启用两步认证后,你登录时将额外需要使用手机或其他认证器生成的代码。
+ code_hint: 输入你的认证器生成的代码以确认
+ description_html: 启用双重认证后,你需要输入手机认证器生成的代码才能登录
disable: 停用
enable: 启用
- enabled_success: 已成功启用两步认证
+ enabled: 双重认证已启用
+ enabled_success: 双重认证启用成功
generate_recovery_codes: 生成恢复代码
- instructions_html: "请用你手机的认证器应用(如 Google Authenticator、Authy),扫描这里的 QR 二维码。在两步认证启用后,你登录时将需要使用此应用程序产生的认证码。"
- lost_recovery_codes: 如果你丢了手机,你可以用恢复代码重新访问你的帐户。如果你丢了恢复代码,也可以在这里重新生成一个,不过以前的恢复代码就失效了。(废话)
- manual_instructions: 如果你无法扫描 QR 二维码,请手动输入这个文本密码︰
- recovery_codes_regenerated: 已成功重新生成恢复代码
- recovery_instructions_html: 如果你的手机无法使用,你可以使用下面的任何恢复代码来恢复你的帐号。请保管好你的恢复代码以防泄漏(例如你可以打印好它们并和重要文档一起保存)。
+ instructions_html: "请使用 Google 身份验证器或其他 TOTP 双重认证手机应用扫描此处的二维码。启用双重认证后,你需要输入该应用生成的代码来登录你的帐户。"
+ lost_recovery_codes: 如果你的手机不慎丢失,你可以使用恢复代码来重新获得对帐户的访问权。如果你遗失了恢复代码,可以在此处重新生成。之前使用的恢复代码将会失效。
+ manual_instructions: 如果你无法扫描二维码,请手动输入下列文本:
+ recovery_codes: 备份恢复代码
+ recovery_codes_regenerated: 恢复代码重新生成成功
+ recovery_instructions_html: 如果你的手机无法使用,你可以使用下列任意一个恢复代码来重新获得对帐户的访问权。请妥善保管好你的恢复代码(例如,你可以将它们打印出来,然后和其他重要的文件放在一起)。
setup: 设置
- wrong_code: 你输入的认证码并不正确!可能服务器时间和你手机不一致,请检查你手机的时钟,或与本站管理员联系。
+ wrong_code: 输入的认证码无效!请检查你设备上显示的时间是否正确,如果正确,你可能需要联系管理员以检查服务器的时间是否正确。
users:
- invalid_email: 邮箱格式有误
- invalid_otp_token: 两步认证码有误
+ invalid_email: 输入的电子邮件地址无效
+ invalid_otp_token: 输入的双重认证代码无效
+ signed_in_as: 当前登录的帐户:
diff --git a/config/navigation.rb b/config/navigation.rb
index 50bfbd4801..5b4800f076 100644
--- a/config/navigation.rb
+++ b/config/navigation.rb
@@ -20,16 +20,16 @@ SimpleNavigation::Configuration.run do |navigation|
development.item :your_apps, safe_join([fa_icon('list fw'), t('settings.your_apps')]), settings_applications_url, highlights_on: %r{/settings/applications}
end
- primary.item :admin, safe_join([fa_icon('cogs fw'), t('admin.title')]), admin_reports_url, if: proc { current_user.admin? } do |admin|
+ primary.item :admin, safe_join([fa_icon('cogs fw'), t('admin.title')]), admin_reports_url, if: proc { current_user.staff? } do |admin|
admin.item :reports, safe_join([fa_icon('flag fw'), t('admin.reports.title')]), admin_reports_url, highlights_on: %r{/admin/reports}
admin.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_url, highlights_on: %r{/admin/accounts}
- admin.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url, highlights_on: %r{/admin/instances}
- admin.item :subscriptions, safe_join([fa_icon('paper-plane-o fw'), t('admin.subscriptions.title')]), admin_subscriptions_url
- admin.item :domain_blocks, safe_join([fa_icon('lock fw'), t('admin.domain_blocks.title')]), admin_domain_blocks_url, highlights_on: %r{/admin/domain_blocks}
- admin.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_url, highlights_on: %r{/admin/email_domain_blocks}
- admin.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }
- admin.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }
- admin.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), edit_admin_settings_url
+ admin.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url, highlights_on: %r{/admin/instances}, if: -> { current_user.admin? }
+ admin.item :subscriptions, safe_join([fa_icon('paper-plane-o fw'), t('admin.subscriptions.title')]), admin_subscriptions_url, if: -> { current_user.admin? }
+ admin.item :domain_blocks, safe_join([fa_icon('lock fw'), t('admin.domain_blocks.title')]), admin_domain_blocks_url, highlights_on: %r{/admin/domain_blocks}, if: -> { current_user.admin? }
+ admin.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_url, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.admin? }
+ admin.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }, if: -> { current_user.admin? }
+ admin.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }, if: -> { current_user.admin? }
+ admin.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), edit_admin_settings_url, if: -> { current_user.admin? }
admin.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_url, highlights_on: %r{/admin/custom_emojis}
end
diff --git a/config/routes.rb b/config/routes.rb
index 5a6351f779..9301a4e507 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -126,7 +126,10 @@ Rails.application.routes.draw do
member do
post :subscribe
post :unsubscribe
+ post :enable
+ post :disable
post :redownload
+ post :memorialize
end
resource :reset, only: [:create]
@@ -134,13 +137,20 @@ Rails.application.routes.draw do
resource :suspension, only: [:create, :destroy]
resource :confirmation, only: [:create]
resources :statuses, only: [:index, :create, :update, :destroy]
+
+ resource :role do
+ member do
+ post :promote
+ post :demote
+ end
+ end
end
resources :users, only: [] do
resource :two_factor_authentication, only: [:destroy]
end
- resources :custom_emojis, only: [:index, :new, :create, :destroy] do
+ resources :custom_emojis, only: [:index, :new, :create, :update, :destroy] do
member do
post :copy
post :enable
diff --git a/config/settings.yml b/config/settings.yml
index 11681d7ec7..a4df4094de 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -36,6 +36,7 @@ defaults: &defaults
interactions:
must_be_follower: false
must_be_following: false
+ must_be_following_dm: false
reserved_usernames:
- admin
- support
diff --git a/config/webpack/production.js b/config/webpack/production.js
index cd1dd91dc7..e2d7f11dc5 100644
--- a/config/webpack/production.js
+++ b/config/webpack/production.js
@@ -9,6 +9,16 @@ const OfflinePlugin = require('offline-plugin');
const { publicPath } = require('./configuration.js');
const path = require('path');
+let compressionAlgorithm;
+try {
+ const zopfli = require('node-zopfli');
+ compressionAlgorithm = (content, options, fn) => {
+ zopfli.gzip(content, options, fn);
+ };
+} catch (error) {
+ compressionAlgorithm = 'gzip';
+}
+
module.exports = merge(sharedConfig, {
output: {
filename: '[name]-[chunkhash].js',
@@ -33,7 +43,7 @@ module.exports = merge(sharedConfig, {
}),
new CompressionPlugin({
asset: '[path].gz[query]',
- algorithm: 'gzip',
+ algorithm: compressionAlgorithm,
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/,
}),
new BundleAnalyzerPlugin({ // generates report.html and stats.json
@@ -48,7 +58,37 @@ module.exports = merge(sharedConfig, {
}),
new OfflinePlugin({
publicPath: publicPath, // sw.js must be served from the root to avoid scope issues
- caches: { }, // do not cache things, we only use it for push notifications for now
+ caches: {
+ main: [':rest:'],
+ additional: [':externals:'],
+ optional: [
+ '**/locale_*.js', // don't fetch every locale; the user only needs one
+ '**/*_polyfills-*.js', // the user may not need polyfills
+ '**/*.woff2', // the user may have system-fonts enabled
+ // images/audio can be cached on-demand
+ '**/*.png',
+ '**/*.jpg',
+ '**/*.jpeg',
+ '**/*.svg',
+ '**/*.mp3',
+ '**/*.ogg',
+ ],
+ },
+ externals: [
+ '/emoji/1f602.svg', // used for emoji picker dropdown
+ '/emoji/sheet.png', // used in emoji-mart
+ ],
+ excludes: [
+ '**/*.gz',
+ '**/*.map',
+ 'stats.json',
+ 'report.html',
+ // any browser that supports ServiceWorker will support woff2
+ '**/*.eot',
+ '**/*.ttf',
+ '**/*-webfont-*.svg',
+ '**/*.woff',
+ ],
ServiceWorker: {
entry: path.join(__dirname, '../../app/javascript/mastodon/service_worker/entry.js'),
cacheName: 'mastodon',
diff --git a/config/webpack/shared.js b/config/webpack/shared.js
index cd642a28ab..50fa481759 100644
--- a/config/webpack/shared.js
+++ b/config/webpack/shared.js
@@ -12,27 +12,24 @@ const localePackPaths = require('./generateLocalePacks');
const extensionGlob = `**/*{${settings.extensions.join(',')}}*`;
const entryPath = join(settings.source_path, settings.source_entry_path);
const packPaths = sync(join(entryPath, extensionGlob));
-const entryPacks = [...packPaths, ...localePackPaths].filter(path => path !== join(entryPath, 'custom.js'));
-
-const themePaths = Object.keys(themes).reduce(
- (themePaths, name) => {
- themePaths[name] = resolve(join(settings.source_path, themes[name]));
- return themePaths;
- }, {});
module.exports = {
entry: Object.assign(
- entryPacks.reduce(
- (map, entry) => {
- const localMap = map;
- let namespace = relative(join(entryPath), dirname(entry));
- if (namespace === join('..', '..', '..', 'tmp', 'packs')) {
- namespace = ''; // generated by generateLocalePacks.js
- }
- localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry);
- return localMap;
- }, {}
- ), themePaths
+ packPaths.reduce((map, entry) => {
+ const localMap = map;
+ const namespace = relative(join(entryPath), dirname(entry));
+ localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry);
+ return localMap;
+ }, {}),
+ localePackPaths.reduce((map, entry) => {
+ const localMap = map;
+ localMap[basename(entry, extname(entry, extname(entry)))] = resolve(entry);
+ return localMap;
+ }, {}),
+ Object.keys(themes).reduce((themePaths, name) => {
+ themePaths[name] = resolve(join(settings.source_path, themes[name]));
+ return themePaths;
+ }, {})
),
output: {
@@ -55,7 +52,7 @@ module.exports = {
resource.request = resource.request.replace(/^history/, 'history/es');
}
),
- new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[hash].css' : '[name].css'),
+ new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[contenthash].css' : '[name].css'),
new ManifestPlugin({
publicPath: output.publicPath,
writeToFileEmit: true,
diff --git a/db/migrate/20170920032311_fix_reblogs_in_feeds.rb b/db/migrate/20170920032311_fix_reblogs_in_feeds.rb
index c813ecd469..439c5fca08 100644
--- a/db/migrate/20170920032311_fix_reblogs_in_feeds.rb
+++ b/db/migrate/20170920032311_fix_reblogs_in_feeds.rb
@@ -3,48 +3,62 @@ class FixReblogsInFeeds < ActiveRecord::Migration[5.1]
redis = Redis.current
fm = FeedManager.instance
+ # Old scheme:
+ # Each user's feed zset had a series of score:value entries,
+ # where "regular" statuses had the same score and value (their
+ # ID). Reblogs had a score of the reblogging status' ID, and a
+ # value of the reblogged status' ID.
+
+ # New scheme:
+ # The feed contains only entries with the same score and value.
+ # Reblogs result in the reblogging status being added to the
+ # feed, with an entry in a reblog tracking zset (where the score
+ # is once again set to the reblogging status' ID, and the value
+ # is set to the reblogged status' ID). This is safe for Redis'
+ # float coersion because in this reblog tracking zset, we only
+ # need the rebloggging status' ID to be able to stop tracking
+ # entries after they have gotten too far down the feed, which
+ # does not require an exact value.
+
+ # This process reads all feeds and writes 3 times for each reblogs.
+ # So we use Lua script to avoid overhead between Ruby and Redis.
+ script = <<-LUA
+ local timeline_key = KEYS[1]
+ local reblog_key = KEYS[2]
+
+ -- So, first, we iterate over the user's feed to find any reblogs.
+ local items = redis.call('zrange', timeline_key, 0, -1, 'withscores')
+
+ for i = 1, #items, 2 do
+ local reblogged_id = items[i]
+ local reblogging_id = items[i + 1]
+ if (reblogged_id ~= reblogging_id) then
+
+ -- The score and value don't match, so this is a reblog.
+ -- (note that we're transitioning from IDs < 53 bits so we
+ -- don't have to worry about the loss of precision)
+
+ -- Remove the old entry
+ redis.call('zrem', timeline_key, reblogged_id)
+
+ -- Add a new one for the reblogging status
+ redis.call('zadd', timeline_key, reblogging_id, reblogging_id)
+
+ -- Track the fact that this was a reblog
+ redis.call('zadd', reblog_key, reblogging_id, reblogged_id)
+ end
+ end
+ LUA
+ script_hash = redis.script(:load, script)
+
# find_each is batched on the database side.
User.includes(:account).find_each do |user|
account = user.account
- # Old scheme:
- # Each user's feed zset had a series of score:value entries,
- # where "regular" statuses had the same score and value (their
- # ID). Reblogs had a score of the reblogging status' ID, and a
- # value of the reblogged status' ID.
-
- # New scheme:
- # The feed contains only entries with the same score and value.
- # Reblogs result in the reblogging status being added to the
- # feed, with an entry in a reblog tracking zset (where the score
- # is once again set to the reblogging status' ID, and the value
- # is set to the reblogged status' ID). This is safe for Redis'
- # float coersion because in this reblog tracking zset, we only
- # need the rebloggging status' ID to be able to stop tracking
- # entries after they have gotten too far down the feed, which
- # does not require an exact value.
-
- # So, first, we iterate over the user's feed to find any reblogs.
timeline_key = fm.key(:home, account.id)
reblog_key = fm.key(:home, account.id, 'reblogs')
- redis.zrange(timeline_key, 0, -1, with_scores: true).each do |entry|
- next if entry[0] == entry[1]
- # The score and value don't match, so this is a reblog.
- # (note that we're transitioning from IDs < 53 bits so we
- # don't have to worry about the loss of precision)
-
- reblogged_id, reblogging_id = entry
-
- # Remove the old entry
- redis.zrem(timeline_key, reblogged_id)
-
- # Add a new one for the reblogging status
- redis.zadd(timeline_key, reblogging_id, reblogging_id)
-
- # Track the fact that this was a reblog
- redis.zadd(reblog_key, reblogging_id, reblogged_id)
- end
+ redis.evalsha(script_hash, [timeline_key, reblog_key])
end
end
diff --git a/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb b/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb
new file mode 100644
index 0000000000..60a2871015
--- /dev/null
+++ b/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb
@@ -0,0 +1,7 @@
+class AddVisibleInPickerToCustomEmoji < ActiveRecord::Migration[5.1]
+ def change
+ safety_assured {
+ add_column :custom_emojis, :visible_in_picker, :boolean, default: true, null: false
+ }
+ end
+end
diff --git a/db/migrate/20171107143332_add_memorial_to_accounts.rb b/db/migrate/20171107143332_add_memorial_to_accounts.rb
new file mode 100644
index 0000000000..f3e012ce8b
--- /dev/null
+++ b/db/migrate/20171107143332_add_memorial_to_accounts.rb
@@ -0,0 +1,15 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddMemorialToAccounts < ActiveRecord::Migration[5.1]
+ include Mastodon::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ safety_assured { add_column_with_default :accounts, :memorial, :bool, default: false }
+ end
+
+ def down
+ remove_column :accounts, :memorial
+ end
+end
diff --git a/db/migrate/20171107143624_add_disabled_to_users.rb b/db/migrate/20171107143624_add_disabled_to_users.rb
new file mode 100644
index 0000000000..a71cac1c61
--- /dev/null
+++ b/db/migrate/20171107143624_add_disabled_to_users.rb
@@ -0,0 +1,15 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddDisabledToUsers < ActiveRecord::Migration[5.1]
+ include Mastodon::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ safety_assured { add_column_with_default :users, :disabled, :bool, default: false }
+ end
+
+ def down
+ remove_column :users, :disabled
+ end
+end
diff --git a/db/migrate/20171109012327_add_moderator_to_accounts.rb b/db/migrate/20171109012327_add_moderator_to_accounts.rb
new file mode 100644
index 0000000000..ddd87583a7
--- /dev/null
+++ b/db/migrate/20171109012327_add_moderator_to_accounts.rb
@@ -0,0 +1,15 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddModeratorToAccounts < ActiveRecord::Migration[5.1]
+ include Mastodon::MigrationHelpers
+
+ disable_ddl_transaction!
+
+ def up
+ safety_assured { add_column_with_default :users, :moderator, :bool, default: false }
+ end
+
+ def down
+ remove_column :users, :moderator
+ end
+end
diff --git a/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb b/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb
new file mode 100644
index 0000000000..84a341510a
--- /dev/null
+++ b/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb
@@ -0,0 +1,8 @@
+class AddIndexDomainToEmailDomainBlocks < ActiveRecord::Migration[5.1]
+ disable_ddl_transaction!
+
+ def change
+ add_index :email_domain_blocks, :domain, algorithm: :concurrently, unique: true
+ change_column_default :email_domain_blocks, :domain, from: nil, to: ''
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 939e7c7028..2d763e2f4f 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20171010025614) do
+ActiveRecord::Schema.define(version: 20171114080328) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -71,6 +71,7 @@ ActiveRecord::Schema.define(version: 20171010025614) do
t.string "shared_inbox_url", default: "", null: false
t.string "followers_url", default: "", null: false
t.integer "protocol", default: 0, null: false
+ t.boolean "memorial", default: false, null: false
t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin
t.index "lower((username)::text), lower((domain)::text)", name: "index_accounts_on_username_and_domain_lower"
t.index ["uri"], name: "index_accounts_on_uri"
@@ -111,6 +112,7 @@ ActiveRecord::Schema.define(version: 20171010025614) do
t.boolean "disabled", default: false, null: false
t.string "uri"
t.string "image_remote_url"
+ t.boolean "visible_in_picker", default: true, null: false
t.index ["shortcode", "domain"], name: "index_custom_emojis_on_shortcode_and_domain", unique: true
end
@@ -124,9 +126,10 @@ ActiveRecord::Schema.define(version: 20171010025614) do
end
create_table "email_domain_blocks", force: :cascade do |t|
- t.string "domain", null: false
+ t.string "domain", default: "", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.index ["domain"], name: "index_email_domain_blocks_on_domain", unique: true
end
create_table "favourites", force: :cascade do |t|
@@ -435,6 +438,8 @@ ActiveRecord::Schema.define(version: 20171010025614) do
t.string "otp_backup_codes", array: true
t.string "filtered_languages", default: [], null: false, array: true
t.bigint "account_id", null: false
+ t.boolean "disabled", default: false, null: false
+ t.boolean "moderator", default: false, null: false
t.index ["account_id"], name: "index_users_on_account_id"
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["email"], name: "index_users_on_email", unique: true
diff --git a/lib/paperclip/gif_transcoder.rb b/lib/paperclip/gif_transcoder.rb
index cbe53b27b3..629e37581e 100644
--- a/lib/paperclip/gif_transcoder.rb
+++ b/lib/paperclip/gif_transcoder.rb
@@ -10,6 +10,7 @@ module Paperclip
unless options[:style] == :original && num_frames > 1
tmp_file = Paperclip::TempfileFactory.new.generate(attachment.instance.file_file_name)
tmp_file << file.read
+ tmp_file.flush
return tmp_file
end
diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake
index 5614ddf48f..995cf0d6f0 100644
--- a/lib/tasks/mastodon.rake
+++ b/lib/tasks/mastodon.rake
@@ -10,14 +10,41 @@ namespace :mastodon do
desc 'Turn a user into an admin, identified by the USERNAME environment variable'
task make_admin: :environment do
include RoutingHelper
+
account_username = ENV.fetch('USERNAME')
- user = User.joins(:account).where(accounts: { username: account_username })
+ user = User.joins(:account).where(accounts: { username: account_username })
if user.present?
user.update(admin: true)
puts "Congrats! #{account_username} is now an admin. \\o/\nNavigate to #{edit_admin_settings_url} to get started"
else
- puts "User could not be found; please make sure an Account with the `#{account_username}` username exists."
+ puts "User could not be found; please make sure an account with the `#{account_username}` username exists."
+ end
+ end
+
+ desc 'Turn a user into a moderator, identified by the USERNAME environment variable'
+ task make_mod: :environment do
+ account_username = ENV.fetch('USERNAME')
+ user = User.joins(:account).where(accounts: { username: account_username })
+
+ if user.present?
+ user.update(moderator: true)
+ puts "Congrats! #{account_username} is now a moderator \\o/"
+ else
+ puts "User could not be found; please make sure an account with the `#{account_username}` username exists."
+ end
+ end
+
+ desc 'Remove admin and moderator privileges from user identified by the USERNAME environment variable'
+ task revoke_staff: :environment do
+ account_username = ENV.fetch('USERNAME')
+ user = User.joins(:account).where(accounts: { username: account_username })
+
+ if user.present?
+ user.update(moderator: false, admin: false)
+ puts "#{account_username} is no longer admin or moderator."
+ else
+ puts "User could not be found; please make sure an account with the `#{account_username}` username exists."
end
end
@@ -81,7 +108,7 @@ namespace :mastodon do
task remove_remote: :environment do
time_ago = ENV.fetch('NUM_DAYS') { 7 }.to_i.days.ago
- MediaAttachment.where.not(remote_url: '').where('created_at < ?', time_ago).find_each do |media|
+ MediaAttachment.where.not(remote_url: '').where.not(file_file_name: nil).where('created_at < ?', time_ago).find_each do |media|
media.file.destroy
media.save
end
diff --git a/package.json b/package.json
index df74547587..cd088e5c0c 100644
--- a/package.json
+++ b/package.json
@@ -19,14 +19,13 @@
"private": true,
"dependencies": {
"array-includes": "^3.0.3",
- "autoprefixer": "^7.1.2",
- "axios": "^0.16.2",
+ "autoprefixer": "^7.1.6",
+ "axios": "~0.16.2",
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-plugin-lodash": "^3.2.11",
- "babel-plugin-preval": "^1.3.2",
+ "babel-plugin-preval": "^1.6.1",
"babel-plugin-react-intl": "^2.3.1",
- "babel-plugin-react-transform": "^2.0.2",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
@@ -35,30 +34,30 @@
"babel-plugin-transform-react-inline-elements": "^6.22.0",
"babel-plugin-transform-react-jsx-self": "^6.22.0",
"babel-plugin-transform-react-jsx-source": "^6.22.0",
- "babel-plugin-transform-react-remove-prop-types": "^0.4.6",
+ "babel-plugin-transform-react-remove-prop-types": "^0.4.10",
"babel-plugin-transform-runtime": "^6.23.0",
- "babel-preset-env": "^1.6.0",
+ "babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"classnames": "^2.2.5",
- "compression-webpack-plugin": "^0.4.0",
- "cross-env": "^5.0.1",
+ "compression-webpack-plugin": "^1.0.1",
+ "cross-env": "^5.1.1",
"css-loader": "^0.28.4",
"detect-passive-events": "^1.0.2",
"dotenv": "^4.0.0",
"emoji-mart": "Gargron/emoji-mart#build",
"es6-symbol": "^3.1.1",
"escape-html": "^1.0.3",
- "express": "^4.15.2",
- "extract-text-webpack-plugin": "^2.1.2",
+ "express": "^4.16.2",
+ "extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^0.11.2",
"font-awesome": "^4.7.0",
"glob": "^7.1.1",
"http-link-header": "^0.8.0",
- "immutable": "^3.8.1",
+ "immutable": "^3.8.2",
"intersection-observer": "^0.4.0",
"intl": "^1.2.5",
"intl-messageformat": "^2.1.0",
- "intl-relativeformat": "^2.0.0",
+ "intl-relativeformat": "^2.1.0",
"is-nan": "^1.2.1",
"js-yaml": "^3.9.0",
"lodash": "^4.17.4",
@@ -72,7 +71,7 @@
"offline-plugin": "^4.8.3",
"path-complete-extname": "^0.1.0",
"pg": "^6.4.0",
- "postcss-loader": "^2.0.6",
+ "postcss-loader": "^2.0.8",
"postcss-object-fit-images": "^1.1.2",
"postcss-smart-import": "^0.7.5",
"precss": "^2.0.0",
@@ -83,15 +82,15 @@
"react-dom": "^16.0.0",
"react-hotkeys": "^0.10.0",
"react-immutable-proptypes": "^2.1.0",
- "react-immutable-pure-component": "^1.0.0",
+ "react-immutable-pure-component": "^1.1.1",
"react-intl": "^2.4.0",
- "react-motion": "^0.5.0",
- "react-notification": "^6.7.1",
- "react-overlays": "^0.8.1",
+ "react-motion": "^0.5.2",
+ "react-notification": "^6.8.2",
+ "react-overlays": "^0.8.3",
"react-redux": "^5.0.4",
- "react-redux-loading-bar": "^2.9.2",
+ "react-redux-loading-bar": "^2.9.3",
"react-router-dom": "^4.1.1",
- "react-router-scroll": "Gargron/react-router-scroll#build",
+ "react-router-scroll-4": "^1.0.0-beta.1",
"react-swipeable-views": "^0.12.3",
"react-textarea-autosize": "^5.0.7",
"react-toggle": "^4.0.1",
@@ -101,17 +100,17 @@
"redux-thunk": "^2.2.0",
"requestidlecallback": "^0.3.0",
"reselect": "^3.0.1",
- "resolve-url-loader": "^2.1.0",
+ "resolve-url-loader": "^2.2.0",
"rimraf": "^2.6.1",
"sass-loader": "^6.0.6",
"stringz": "^0.2.2",
- "style-loader": "^0.18.2",
+ "style-loader": "^0.19.0",
"substring-trie": "^1.0.2",
"throng": "^4.0.0",
"tiny-queue": "^0.2.1",
"uuid": "^3.1.0",
"uws": "^8.14.0",
- "webpack": "^3.4.1",
+ "webpack": "^3.8.1",
"webpack-bundle-analyzer": "^2.8.3",
"webpack-manifest-plugin": "^1.2.1",
"webpack-merge": "^4.1.0",
@@ -120,19 +119,20 @@
"devDependencies": {
"babel-eslint": "^7.2.3",
"enzyme": "^3.0.0",
- "enzyme-adapter-react-16": "^1.0.0",
+ "enzyme-adapter-react-16": "^1.0.2",
"eslint": "^3.19.0",
- "eslint-plugin-import": "^2.7.0",
+ "eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "^4.0.0",
"eslint-plugin-react": "^6.10.3",
"jest": "^21.2.1",
"raf": "^3.4.0",
"react-intl-translations-manager": "^5.0.0",
"react-test-renderer": "^16.0.0",
- "webpack-dev-server": "^2.6.1",
+ "webpack-dev-server": "^2.9.3",
"yargs": "^8.0.2"
},
"optionalDependencies": {
- "fsevents": "*"
+ "fsevents": "*",
+ "node-zopfli": "^2.0.2"
}
}
diff --git a/public/sounds/boop.mp3 b/public/sounds/boop.mp3
index 02a035d91b..bf9c3c1aaf 100644
Binary files a/public/sounds/boop.mp3 and b/public/sounds/boop.mp3 differ
diff --git a/public/sounds/boop.ogg b/public/sounds/boop.ogg
index a2124e1167..a6551c9fdd 100644
Binary files a/public/sounds/boop.ogg and b/public/sounds/boop.ogg differ
diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb
index 92f8885907..a8ade790cd 100644
--- a/spec/controllers/accounts_controller_spec.rb
+++ b/spec/controllers/accounts_controller_spec.rb
@@ -4,6 +4,7 @@ RSpec.describe AccountsController, type: :controller do
render_views
let(:alice) { Fabricate(:account, username: 'alice') }
+ let(:eve) { Fabricate(:user) }
describe 'GET #show' do
let!(:status1) { Status.create!(account: alice, text: 'Hello world') }
@@ -19,93 +20,123 @@ RSpec.describe AccountsController, type: :controller do
let!(:status_pin3) { StatusPin.create!(account: alice, status: status7, created_at: 10.minutes.ago) }
before do
+ alice.block!(eve.account)
status3.media_attachments.create!(account: alice, file: fixture_file_upload('files/attachment.jpg', 'image/jpeg'))
end
- context 'atom' do
+ shared_examples 'responses' do
before do
- get :show, params: { username: alice.username, max_id: status4.stream_entry.id, since_id: status1.stream_entry.id }, format: 'atom'
+ sign_in(current_user) if defined? current_user
+ get :show, params: {
+ username: alice.username,
+ max_id: (max_id if defined? max_id),
+ since_id: (since_id if defined? since_id),
+ current_user: (current_user if defined? current_user),
+ }, format: format
end
it 'assigns @account' do
expect(assigns(:account)).to eq alice
end
- it 'assigns @entries' do
- entries = assigns(:entries).to_a
- expect(entries.size).to eq 2
- expect(entries[0].status).to eq status3
- expect(entries[1].status).to eq status2
+ it 'returns http success' do
+ expect(response).to have_http_status(:success)
end
- it 'returns http success with Atom' do
- expect(response).to have_http_status(:success)
+ it 'returns correct format' do
+ expect(response.content_type).to eq content_type
+ end
+ end
+
+ context 'atom' do
+ let(:format) { 'atom' }
+ let(:content_type) { 'application/atom+xml' }
+
+ shared_examples 'responsed streams' do
+ it 'assigns @entries' do
+ entries = assigns(:entries).to_a
+ expect(entries.size).to eq expected_statuses.size
+ entries.each.zip(expected_statuses.each) do |entry, expected_status|
+ expect(entry.status).to eq expected_status
+ end
+ end
+ end
+
+ include_examples 'responses'
+
+ context 'without max_id nor since_id' do
+ let(:expected_statuses) { [status7, status6, status5, status4, status3, status2, status1] }
+
+ include_examples 'responsed streams'
+ end
+
+ context 'with max_id and since_id' do
+ let(:max_id) { status4.stream_entry.id }
+ let(:since_id) { status1.stream_entry.id }
+ let(:expected_statuses) { [status3, status2] }
+
+ include_examples 'responsed streams'
end
end
context 'activitystreams2' do
- before do
- get :show, params: { username: alice.username }, format: 'json'
- end
+ let(:format) { 'json' }
+ let(:content_type) { 'application/activity+json' }
- it 'assigns @account' do
- expect(assigns(:account)).to eq alice
- end
-
- it 'returns http success with Activity Streams 2.0' do
- expect(response).to have_http_status(:success)
- end
-
- it 'returns application/activity+json' do
- expect(response.content_type).to eq 'application/activity+json'
- end
+ include_examples 'responses'
end
- context 'html without since_id nor max_id' do
- before do
- get :show, params: { username: alice.username }
+ context 'html' do
+ let(:format) { nil }
+ let(:content_type) { 'text/html' }
+
+ shared_examples 'responsed statuses' do
+ it 'assigns @pinned_statuses' do
+ pinned_statuses = assigns(:pinned_statuses).to_a
+ expect(pinned_statuses.size).to eq expected_pinned_statuses.size
+ pinned_statuses.each.zip(expected_pinned_statuses.each) do |pinned_status, expected_pinned_status|
+ expect(pinned_status).to eq expected_pinned_status
+ end
+ end
+
+ it 'assigns @statuses' do
+ statuses = assigns(:statuses).to_a
+ expect(statuses.size).to eq expected_statuses.size
+ statuses.each.zip(expected_statuses.each) do |status, expected_status|
+ expect(status).to eq expected_status
+ end
+ end
end
- it 'assigns @account' do
- expect(assigns(:account)).to eq alice
+ include_examples 'responses'
+
+ context 'with anonymous visitor' do
+ context 'without since_id nor max_id' do
+ let(:expected_statuses) { [status7, status6, status5, status4, status3, status2, status1] }
+ let(:expected_pinned_statuses) { [status7, status5, status6] }
+
+ include_examples 'responsed statuses'
+ end
+
+ context 'with since_id nor max_id' do
+ let(:max_id) { status4.id }
+ let(:since_id) { status1.id }
+ let(:expected_statuses) { [status3, status2] }
+ let(:expected_pinned_statuses) { [] }
+
+ include_examples 'responsed statuses'
+ end
end
- it 'assigns @pinned_statuses' do
- pinned_statuses = assigns(:pinned_statuses).to_a
- expect(pinned_statuses.size).to eq 3
- expect(pinned_statuses[0]).to eq status7
- expect(pinned_statuses[1]).to eq status5
- expect(pinned_statuses[2]).to eq status6
- end
+ context 'with blocked visitor' do
+ let(:current_user) { eve }
- it 'returns http success' do
- expect(response).to have_http_status(:success)
- end
- end
+ context 'without since_id nor max_id' do
+ let(:expected_statuses) { [] }
+ let(:expected_pinned_statuses) { [] }
- context 'html with since_id and max_id' do
- before do
- get :show, params: { username: alice.username, max_id: status4.id, since_id: status1.id }
- end
-
- it 'assigns @account' do
- expect(assigns(:account)).to eq alice
- end
-
- it 'assigns @statuses' do
- statuses = assigns(:statuses).to_a
- expect(statuses.size).to eq 2
- expect(statuses[0]).to eq status3
- expect(statuses[1]).to eq status2
- end
-
- it 'assigns an empty array to @pinned_statuses' do
- pinned_statuses = assigns(:pinned_statuses).to_a
- expect(pinned_statuses.size).to eq 0
- end
-
- it 'returns http success' do
- expect(response).to have_http_status(:success)
+ include_examples 'responsed statuses'
+ end
end
end
end
diff --git a/spec/fabricators/session_activation_fabricator.rb b/spec/fabricators/session_activation_fabricator.rb
index 46050bdab1..526faaec2b 100644
--- a/spec/fabricators/session_activation_fabricator.rb
+++ b/spec/fabricators/session_activation_fabricator.rb
@@ -1,4 +1,4 @@
Fabricator(:session_activation) do
- user_id 1
+ user
session_id "MyString"
end
diff --git a/spec/fabricators/setting_fabricator.rb b/spec/fabricators/setting_fabricator.rb
new file mode 100644
index 0000000000..336d7c3551
--- /dev/null
+++ b/spec/fabricators/setting_fabricator.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+Fabricator(:setting) do
+end
diff --git a/spec/fixtures/files/mini-static.gif b/spec/fixtures/files/mini-static.gif
new file mode 100644
index 0000000000..fe597b2155
Binary files /dev/null and b/spec/fixtures/files/mini-static.gif differ
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
index aef0c30821..9c1492c90e 100644
--- a/spec/models/account_spec.rb
+++ b/spec/models/account_spec.rb
@@ -93,21 +93,44 @@ RSpec.describe Account, type: :model do
end
describe '#save_with_optional_media!' do
- it 'sets default avatar, header, avatar_remote_url, and header_remote_url if some of them are invalid' do
+ before do
stub_request(:get, 'https://remote/valid_avatar').to_return(request_fixture('avatar.txt'))
stub_request(:get, 'https://remote/invalid_avatar').to_return(request_fixture('feed.txt'))
- account = Fabricate(:account,
- avatar_remote_url: 'https://remote/valid_avatar',
- header_remote_url: 'https://remote/valid_avatar')
+ end
- account.avatar_remote_url = 'https://remote/invalid_avatar'
- account.save_with_optional_media!
+ let(:account) do
+ Fabricate(:account,
+ avatar_remote_url: 'https://remote/valid_avatar',
+ header_remote_url: 'https://remote/valid_avatar')
+ end
- account.reload
- expect(account.avatar_remote_url).to eq ''
- expect(account.header_remote_url).to eq ''
- expect(account.avatar_file_name).to eq nil
- expect(account.header_file_name).to eq nil
+ let!(:expectation) { account.dup }
+
+ context 'with valid properties' do
+ before do
+ account.save_with_optional_media!
+ end
+
+ it 'unchanges avatar, header, avatar_remote_url, and header_remote_url' do
+ expect(account.avatar_remote_url).to eq expectation.avatar_remote_url
+ expect(account.header_remote_url).to eq expectation.header_remote_url
+ expect(account.avatar_file_name).to eq expectation.avatar_file_name
+ expect(account.header_file_name).to eq expectation.header_file_name
+ end
+ end
+
+ context 'with invalid properties' do
+ before do
+ account.avatar_remote_url = 'https://remote/invalid_avatar'
+ account.save_with_optional_media!
+ end
+
+ it 'sets default avatar, header, avatar_remote_url, and header_remote_url' do
+ expect(account.avatar_remote_url).to eq ''
+ expect(account.header_remote_url).to eq ''
+ expect(account.avatar_file_name).to eq nil
+ expect(account.header_file_name).to eq nil
+ end
end
end
@@ -123,6 +146,61 @@ RSpec.describe Account, type: :model do
end
end
+ describe '#possibly_stale?' do
+ let(:account) { Fabricate(:account, last_webfingered_at: last_webfingered_at) }
+
+ context 'last_webfingered_at is nil' do
+ let(:last_webfingered_at) { nil }
+
+ it 'returns true' do
+ expect(account.possibly_stale?).to be true
+ end
+ end
+
+ context 'last_webfingered_at is more than 24 hours before' do
+ let(:last_webfingered_at) { 25.hours.ago }
+
+ it 'returns true' do
+ expect(account.possibly_stale?).to be true
+ end
+ end
+
+ context 'last_webfingered_at is less than 24 hours before' do
+ let(:last_webfingered_at) { 23.hours.ago }
+
+ it 'returns false' do
+ expect(account.possibly_stale?).to be false
+ end
+ end
+ end
+
+ describe '#refresh!' do
+ let(:account) { Fabricate(:account, domain: domain) }
+ let(:acct) { account.acct }
+
+ context 'domain is nil' do
+ let(:domain) { nil }
+
+ it 'returns nil' do
+ expect(account.refresh!).to be_nil
+ end
+
+ it 'calls not ResolveRemoteAccountService#call' do
+ expect_any_instance_of(ResolveRemoteAccountService).not_to receive(:call).with(acct)
+ account.refresh!
+ end
+ end
+
+ context 'domain is present' do
+ let(:domain) { 'example.com' }
+
+ it 'calls ResolveRemoteAccountService#call' do
+ expect_any_instance_of(ResolveRemoteAccountService).to receive(:call).with(acct).once
+ account.refresh!
+ end
+ end
+ end
+
describe '#to_param' do
it 'returns username' do
account = Fabricate(:account, username: 'alice')
diff --git a/spec/models/custom_emoji_spec.rb b/spec/models/custom_emoji_spec.rb
index cb51e9519c..bb150b8376 100644
--- a/spec/models/custom_emoji_spec.rb
+++ b/spec/models/custom_emoji_spec.rb
@@ -1,6 +1,35 @@
require 'rails_helper'
RSpec.describe CustomEmoji, type: :model do
+ describe '#local?' do
+ let(:custom_emoji) { Fabricate(:custom_emoji, domain: domain) }
+
+ subject { custom_emoji.local? }
+
+ context 'domain is nil' do
+ let(:domain) { nil }
+
+ it 'returns true' do
+ is_expected.to be true
+ end
+ end
+
+ context 'domain is present' do
+ let(:domain) { 'example.com' }
+
+ it 'returns false' do
+ is_expected.to be false
+ end
+ end
+ end
+
+ describe '#object_type' do
+ it 'returns :emoji' do
+ custom_emoji = Fabricate(:custom_emoji)
+ expect(custom_emoji.object_type).to be :emoji
+ end
+ end
+
describe '.from_text' do
let!(:emojo) { Fabricate(:custom_emoji) }
diff --git a/spec/models/email_domain_block_spec.rb b/spec/models/email_domain_block_spec.rb
index 5f5d189d9d..efd2853a96 100644
--- a/spec/models/email_domain_block_spec.rb
+++ b/spec/models/email_domain_block_spec.rb
@@ -13,9 +13,10 @@ RSpec.describe EmailDomainBlock, type: :model do
Fabricate(:email_domain_block, domain: 'example.com')
expect(EmailDomainBlock.block?('nyarn@example.com')).to eq true
end
+
it 'returns true if the domain is not registed' do
- Fabricate(:email_domain_block, domain: 'domain')
- expect(EmailDomainBlock.block?('example')).to eq false
+ Fabricate(:email_domain_block, domain: 'example.com')
+ expect(EmailDomainBlock.block?('nyarn@example.net')).to eq false
end
end
end
diff --git a/spec/models/follow_request_spec.rb b/spec/models/follow_request_spec.rb
index cc6f8ee626..1436501e99 100644
--- a/spec/models/follow_request_spec.rb
+++ b/spec/models/follow_request_spec.rb
@@ -1,25 +1,16 @@
require 'rails_helper'
RSpec.describe FollowRequest, type: :model do
- describe '#authorize!'
- describe '#reject!'
+ describe '#authorize!' do
+ let(:follow_request) { Fabricate(:follow_request, account: account, target_account: target_account) }
+ let(:account) { Fabricate(:account) }
+ let(:target_account) { Fabricate(:account) }
- describe 'validations' do
- it 'has a valid fabricator' do
- follow_request = Fabricate.build(:follow_request)
- expect(follow_request).to be_valid
- end
-
- it 'is invalid without an account' do
- follow_request = Fabricate.build(:follow_request, account: nil)
- follow_request.valid?
- expect(follow_request).to model_have_error_on_field(:account)
- end
-
- it 'is invalid without a target account' do
- follow_request = Fabricate.build(:follow_request, target_account: nil)
- follow_request.valid?
- expect(follow_request).to model_have_error_on_field(:target_account)
+ it 'calls Account#follow!, MergeWorker.perform_async, and #destroy!' do
+ expect(account).to receive(:follow!).with(target_account)
+ expect(MergeWorker).to receive(:perform_async).with(target_account.id, account.id)
+ expect(follow_request).to receive(:destroy!)
+ follow_request.authorize!
end
end
end
diff --git a/spec/models/media_attachment_spec.rb b/spec/models/media_attachment_spec.rb
index 9fce5bc4fb..b40a641f70 100644
--- a/spec/models/media_attachment_spec.rb
+++ b/spec/models/media_attachment_spec.rb
@@ -1,6 +1,83 @@
require 'rails_helper'
RSpec.describe MediaAttachment, type: :model do
+ describe 'local?' do
+ let(:media_attachment) { Fabricate(:media_attachment, remote_url: remote_url) }
+
+ subject { media_attachment.local? }
+
+ context 'remote_url is blank' do
+ let(:remote_url) { '' }
+
+ it 'returns true' do
+ is_expected.to be true
+ end
+ end
+
+ context 'remote_url is present' do
+ let(:remote_url) { 'remote_url' }
+
+ it 'returns false' do
+ is_expected.to be false
+ end
+ end
+ end
+
+ describe 'needs_redownload?' do
+ let(:media_attachment) { Fabricate(:media_attachment, remote_url: remote_url, file: file) }
+
+ subject { media_attachment.needs_redownload? }
+
+ context 'file is blank' do
+ let(:file) { nil }
+
+ context 'remote_url is blank' do
+ let(:remote_url) { '' }
+
+ it 'returns false' do
+ is_expected.to be false
+ end
+ end
+
+ context 'remote_url is present' do
+ let(:remote_url) { 'remote_url' }
+
+ it 'returns true' do
+ is_expected.to be true
+ end
+ end
+ end
+
+ context 'file is present' do
+ let(:file) { attachment_fixture('avatar.gif') }
+
+ context 'remote_url is blank' do
+ let(:remote_url) { '' }
+
+ it 'returns false' do
+ is_expected.to be false
+ end
+ end
+
+ context 'remote_url is present' do
+ let(:remote_url) { 'remote_url' }
+
+ it 'returns true' do
+ is_expected.to be false
+ end
+ end
+ end
+ end
+
+ describe '#to_param' do
+ let(:media_attachment) { Fabricate(:media_attachment) }
+ let(:shortcode) { media_attachment.shortcode }
+
+ it 'returns shortcode' do
+ expect(media_attachment.to_param).to eq shortcode
+ end
+ end
+
describe 'animated gif conversion' do
let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('avatar.gif')) }
@@ -20,20 +97,29 @@ RSpec.describe MediaAttachment, type: :model do
end
describe 'non-animated gif non-conversion' do
- let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('attachment.gif')) }
+ fixtures = [
+ { filename: 'attachment.gif', width: 600, height: 400, aspect: 1.5 },
+ { filename: 'mini-static.gif', width: 32, height: 32, aspect: 1.0 },
+ ]
- it 'sets type to image' do
- expect(media.type).to eq 'image'
- end
+ fixtures.each do |fixture|
+ context fixture[:filename] do
+ let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture(fixture[:filename])) }
- it 'leaves original file as-is' do
- expect(media.file_content_type).to eq 'image/gif'
- end
+ it 'sets type to image' do
+ expect(media.type).to eq 'image'
+ end
- it 'sets meta' do
- expect(media.file.meta["original"]["width"]).to eq 600
- expect(media.file.meta["original"]["height"]).to eq 400
- expect(media.file.meta["original"]["aspect"]).to eq 1.5
+ it 'leaves original file as-is' do
+ expect(media.file_content_type).to eq 'image/gif'
+ end
+
+ it 'sets meta' do
+ expect(media.file.meta["original"]["width"]).to eq fixture[:width]
+ expect(media.file.meta["original"]["height"]).to eq fixture[:height]
+ expect(media.file.meta["original"]["aspect"]).to eq fixture[:aspect]
+ end
+ end
end
end
diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb
index 97e8095cd5..763b1523fd 100644
--- a/spec/models/notification_spec.rb
+++ b/spec/models/notification_spec.rb
@@ -5,6 +5,74 @@ RSpec.describe Notification, type: :model do
pending
end
+ describe '#target_status' do
+ before do
+ allow(notification).to receive(:type).and_return(type)
+ allow(notification).to receive(:activity).and_return(activity)
+ end
+
+ let(:notification) { Fabricate(:notification) }
+ let(:status) { instance_double('Status') }
+ let(:favourite) { instance_double('Favourite') }
+ let(:mention) { instance_double('Mention') }
+
+ context 'type is :reblog' do
+ let(:type) { :reblog }
+ let(:activity) { status }
+
+ it 'calls activity.reblog' do
+ expect(activity).to receive(:reblog)
+ notification.target_status
+ end
+ end
+
+ context 'type is :favourite' do
+ let(:type) { :favourite }
+ let(:activity) { favourite }
+
+ it 'calls activity.status' do
+ expect(activity).to receive(:status)
+ notification.target_status
+ end
+ end
+
+ context 'type is :mention' do
+ let(:type) { :mention }
+ let(:activity) { mention }
+
+ it 'calls activity.status' do
+ expect(activity).to receive(:status)
+ notification.target_status
+ end
+ end
+ end
+
+ describe '#browserable?' do
+ let(:notification) { Fabricate(:notification) }
+
+ subject { notification.browserable? }
+
+ context 'type is :follow_request' do
+ before do
+ allow(notification).to receive(:type).and_return(:follow_request)
+ end
+
+ it 'returns false' do
+ is_expected.to be false
+ end
+ end
+
+ context 'type is not :follow_request' do
+ before do
+ allow(notification).to receive(:type).and_return(:else)
+ end
+
+ it 'returns true' do
+ is_expected.to be true
+ end
+ end
+ end
+
describe '#type' do
it 'returns :reblog for a Status' do
notification = Notification.new(activity: Status.new)
@@ -26,4 +94,49 @@ RSpec.describe Notification, type: :model do
expect(notification.type).to eq :follow
end
end
+
+ describe '.reload_stale_associations!' do
+ context 'account_ids are empty' do
+ let(:cached_items) { [] }
+
+ subject { described_class.reload_stale_associations!(cached_items) }
+
+ it 'returns nil' do
+ is_expected.to be nil
+ end
+ end
+
+ context 'account_ids are present' do
+ before do
+ allow(accounts_with_ids).to receive(:[]).with(stale_account1.id).and_return(account1)
+ allow(accounts_with_ids).to receive(:[]).with(stale_account2.id).and_return(account2)
+ allow(Account).to receive_message_chain(:where, :map, :to_h).and_return(accounts_with_ids)
+ end
+
+ let(:cached_items) do
+ [
+ Fabricate(:notification, activity: Fabricate(:status)),
+ Fabricate(:notification, activity: Fabricate(:follow)),
+ ]
+ end
+
+ let(:stale_account1) { cached_items[0].from_account }
+ let(:stale_account2) { cached_items[1].from_account }
+
+ let(:account1) { Fabricate(:account) }
+ let(:account2) { Fabricate(:account) }
+
+ let(:accounts_with_ids) { { account1.id => account1, account2.id => account2 } }
+
+ it 'reloads associations' do
+ expect(cached_items[0].from_account).to be stale_account1
+ expect(cached_items[1].from_account).to be stale_account2
+
+ described_class.reload_stale_associations!(cached_items)
+
+ expect(cached_items[0].from_account).to be account1
+ expect(cached_items[1].from_account).to be account2
+ end
+ end
+ end
end
diff --git a/spec/models/remote_follow_spec.rb b/spec/models/remote_follow_spec.rb
new file mode 100644
index 0000000000..7a4597ee7f
--- /dev/null
+++ b/spec/models/remote_follow_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe RemoteFollow do
+ before do
+ stub_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no').to_return(request_fixture('webfinger.txt'))
+ end
+
+ let(:attrs) { nil }
+ let(:remote_follow) { described_class.new(attrs) }
+
+ describe '.initialize' do
+ subject { remote_follow.acct }
+
+ context 'attrs with acct' do
+ let(:attrs) { { acct: 'gargron@quitter.no' } }
+
+ it 'returns acct' do
+ is_expected.to eq 'gargron@quitter.no'
+ end
+ end
+
+ context 'attrs without acct' do
+ let(:attrs) { {} }
+
+ it do
+ is_expected.to be_nil
+ end
+ end
+ end
+
+ describe '#valid?' do
+ subject { remote_follow.valid? }
+
+ context 'attrs with acct' do
+ let(:attrs) { { acct: 'gargron@quitter.no' }}
+
+ it do
+ is_expected.to be true
+ end
+ end
+
+ context 'attrs without acct' do
+ let(:attrs) { { } }
+
+ it do
+ is_expected.to be false
+ end
+ end
+ end
+
+ describe '#subscribe_address_for' do
+ before do
+ remote_follow.valid?
+ end
+
+ let(:attrs) { { acct: 'gargron@quitter.no' } }
+ let(:account) { Fabricate(:account, username: 'alice') }
+
+ subject { remote_follow.subscribe_address_for(account) }
+
+ it 'returns subscribe address' do
+ is_expected.to eq 'https://quitter.no/main/ostatussub?profile=alice%40cb6e6126.ngrok.io'
+ end
+ end
+end
diff --git a/spec/models/remote_profile_spec.rb b/spec/models/remote_profile_spec.rb
new file mode 100644
index 0000000000..da5048f0a4
--- /dev/null
+++ b/spec/models/remote_profile_spec.rb
@@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe RemoteProfile do
+ let(:remote_profile) { RemoteProfile.new(body) }
+ let(:body) do
+ <<-XML
+
+ John
+ XML
+ end
+
+ describe '.initialize' do
+ it 'calls Nokogiri::XML.parse' do
+ expect(Nokogiri::XML).to receive(:parse).with(body, nil, 'utf-8')
+ RemoteProfile.new(body)
+ end
+
+ it 'sets document' do
+ remote_profile = RemoteProfile.new(body)
+ expect(remote_profile).not_to be nil
+ end
+ end
+
+ describe '#root' do
+ let(:document) { remote_profile.document }
+
+ it 'callse document.at_xpath' do
+ expect(document).to receive(:at_xpath).with(
+ '/atom:feed|/atom:entry',
+ atom: OStatus::TagManager::XMLNS
+ )
+
+ remote_profile.root
+ end
+ end
+
+ describe '#author' do
+ let(:root) { remote_profile.root }
+
+ it 'calls root.at_xpath' do
+ expect(root).to receive(:at_xpath).with(
+ './atom:author|./dfrn:owner',
+ atom: OStatus::TagManager::XMLNS,
+ dfrn: OStatus::TagManager::DFRN_XMLNS
+ )
+
+ remote_profile.author
+ end
+ end
+
+ describe '#hub_link' do
+ let(:root) { remote_profile.root }
+
+ it 'calls #link_href_from_xml' do
+ expect(remote_profile).to receive(:link_href_from_xml).with(root, 'hub')
+ remote_profile.hub_link
+ end
+ end
+
+ describe '#display_name' do
+ let(:author) { remote_profile.author }
+
+ it 'calls author.at_xpath.content' do
+ expect(author).to receive_message_chain(:at_xpath, :content).with(
+ './poco:displayName',
+ poco: OStatus::TagManager::POCO_XMLNS
+ ).with(no_args)
+
+ remote_profile.display_name
+ end
+ end
+
+ describe '#note' do
+ let(:author) { remote_profile.author }
+
+ it 'calls author.at_xpath.content' do
+ expect(author).to receive_message_chain(:at_xpath, :content).with(
+ './atom:summary|./poco:note',
+ atom: OStatus::TagManager::XMLNS,
+ poco: OStatus::TagManager::POCO_XMLNS
+ ).with(no_args)
+
+ remote_profile.note
+ end
+ end
+
+ describe '#scope' do
+ let(:author) { remote_profile.author }
+
+ it 'calls author.at_xpath.content' do
+ expect(author).to receive_message_chain(:at_xpath, :content).with(
+ './mastodon:scope',
+ mastodon: OStatus::TagManager::MTDN_XMLNS
+ ).with(no_args)
+
+ remote_profile.scope
+ end
+ end
+
+ describe '#avatar' do
+ let(:author) { remote_profile.author }
+
+ it 'calls #link_href_from_xml' do
+ expect(remote_profile).to receive(:link_href_from_xml).with(author, 'avatar')
+ remote_profile.avatar
+ end
+ end
+
+ describe '#header' do
+ let(:author) { remote_profile.author }
+
+ it 'calls #link_href_from_xml' do
+ expect(remote_profile).to receive(:link_href_from_xml).with(author, 'header')
+ remote_profile.header
+ end
+ end
+
+ describe '#locked?' do
+ before do
+ allow(remote_profile).to receive(:scope).and_return(scope)
+ end
+
+ subject { remote_profile.locked? }
+
+ context 'scope is private' do
+ let(:scope) { 'private' }
+
+ it 'returns true' do
+ is_expected.to be true
+ end
+ end
+
+ context 'scope is not private' do
+ let(:scope) { 'public' }
+
+ it 'returns false' do
+ is_expected.to be false
+ end
+ end
+ end
+end
diff --git a/spec/models/session_activation_spec.rb b/spec/models/session_activation_spec.rb
index 49c72fbd4e..2aa6950370 100644
--- a/spec/models/session_activation_spec.rb
+++ b/spec/models/session_activation_spec.rb
@@ -1,5 +1,127 @@
+# frozen_string_literal: true
+
require 'rails_helper'
RSpec.describe SessionActivation, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
+ describe '#detection' do
+ let(:session_activation) { Fabricate(:session_activation, user_agent: 'Chrome/62.0.3202.89') }
+
+ it 'sets a Browser instance as detection' do
+ expect(session_activation.detection).to be_kind_of Browser::Chrome
+ end
+ end
+
+ describe '#browser' do
+ before do
+ allow(session_activation).to receive(:detection).and_return(detection)
+ end
+
+ let(:detection) { double(id: 1) }
+ let(:session_activation) { Fabricate(:session_activation) }
+
+ it 'returns detection.id' do
+ expect(session_activation.browser).to be 1
+ end
+ end
+
+ describe '#platform' do
+ before do
+ allow(session_activation).to receive(:detection).and_return(detection)
+ end
+
+ let(:session_activation) { Fabricate(:session_activation) }
+ let(:detection) { double(platform: double(id: 1)) }
+
+ it 'returns detection.platform.id' do
+ expect(session_activation.platform).to be 1
+ end
+ end
+
+ describe '.active?' do
+ subject { described_class.active?(id) }
+
+ context 'id is absent' do
+ let(:id) { nil }
+
+ it 'returns nil' do
+ is_expected.to be nil
+ end
+ end
+
+ context 'id is present' do
+ let(:id) { '1' }
+ let!(:session_activation) { Fabricate(:session_activation, session_id: id) }
+
+ context 'id exists as session_id' do
+ it 'returns true' do
+ is_expected.to be true
+ end
+ end
+
+ context 'id does not exist as session_id' do
+ before do
+ session_activation.update!(session_id: '2')
+ end
+
+ it 'returns false' do
+ is_expected.to be false
+ end
+ end
+ end
+ end
+
+ describe '.activate' do
+ let(:options) { { user: Fabricate(:user), session_id: '1' } }
+
+ it 'calls create! and purge_old' do
+ expect(described_class).to receive(:create!).with(options)
+ expect(described_class).to receive(:purge_old)
+ described_class.activate(options)
+ end
+
+ it 'returns an instance of SessionActivation' do
+ expect(described_class.activate(options)).to be_kind_of SessionActivation
+ end
+ end
+
+ describe '.deactivate' do
+ context 'id is absent' do
+ let(:id) { nil }
+
+ it 'returns nil' do
+ expect(described_class.deactivate(id)).to be nil
+ end
+ end
+
+ context 'id exists' do
+ let(:id) { '1' }
+
+ it 'calls where.destroy_all' do
+ expect(described_class).to receive_message_chain(:where, :destroy_all)
+ .with(session_id: id).with(no_args)
+
+ described_class.deactivate(id)
+ end
+ end
+ end
+
+ describe '.purge_old' do
+ it 'calls order.offset.destroy_all' do
+ expect(described_class).to receive_message_chain(:order, :offset, :destroy_all)
+ .with('created_at desc').with(Rails.configuration.x.max_session_activations).with(no_args)
+
+ described_class.purge_old
+ end
+ end
+
+ describe '.exclusive' do
+ let(:id) { '1' }
+
+ it 'calls where.destroy_all' do
+ expect(described_class).to receive_message_chain(:where, :destroy_all)
+ .with('session_id != ?', id).with(no_args)
+
+ described_class.exclusive(id)
+ end
+ end
end
diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb
new file mode 100644
index 0000000000..e99dfc0d73
--- /dev/null
+++ b/spec/models/setting_spec.rb
@@ -0,0 +1,184 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe Setting, type: :model do
+ describe '#to_param' do
+ let(:setting) { Fabricate(:setting, var: var) }
+ let(:var) { 'var' }
+
+ it 'returns setting.var' do
+ expect(setting.to_param).to eq var
+ end
+ end
+
+ describe '.[]' do
+ before do
+ allow(described_class).to receive(:rails_initialized?).and_return(rails_initialized)
+ end
+
+ let(:key) { 'key' }
+
+ context 'rails_initialized? is falsey' do
+ let(:rails_initialized) { false }
+
+ it 'calls RailsSettings::Base#[]' do
+ expect(RailsSettings::Base).to receive(:[]).with(key)
+ described_class[key]
+ end
+ end
+
+ context 'rails_initialized? is truthy' do
+ before do
+ allow(RailsSettings::Base).to receive(:cache_key).with(key, nil).and_return(cache_key)
+ end
+
+ let(:rails_initialized) { true }
+ let(:cache_key) { 'cache-key' }
+ let(:cache_value) { 'cache-value' }
+
+ it 'calls not RailsSettings::Base#[]' do
+ expect(RailsSettings::Base).not_to receive(:[]).with(key)
+ described_class[key]
+ end
+
+ it 'calls Rails.cache.fetch' do
+ expect(Rails).to receive_message_chain(:cache, :fetch).with(cache_key)
+ described_class[key]
+ end
+
+ context 'Rails.cache does not exists' do
+ before do
+ allow(RailsSettings::Settings).to receive(:object).with(key).and_return(object)
+ allow(described_class).to receive(:default_settings).and_return(default_settings)
+ allow_any_instance_of(Settings::ScopedSettings).to receive(:thing_scoped).and_return(records)
+ Rails.cache.clear(cache_key)
+ end
+
+ let(:object) { nil }
+ let(:default_value) { 'default_value' }
+ let(:default_settings) { { key => default_value } }
+ let(:records) { [Fabricate(:setting, var: key, value: nil)] }
+
+ it 'calls RailsSettings::Settings.object' do
+ expect(RailsSettings::Settings).to receive(:object).with(key)
+ described_class[key]
+ end
+
+ context 'RailsSettings::Settings.object returns truthy' do
+ let(:object) { db_val }
+ let(:db_val) { double(value: 'db_val') }
+
+ context 'default_value is a Hash' do
+ let(:default_value) { { default_value: 'default_value' } }
+
+ it 'calls default_value.with_indifferent_access.merge!' do
+ expect(default_value).to receive_message_chain(:with_indifferent_access, :merge!)
+ .with(db_val.value)
+
+ described_class[key]
+ end
+ end
+
+ context 'default_value is not a Hash' do
+ let(:default_value) { 'default_value' }
+
+ it 'returns db_val.value' do
+ expect(described_class[key]).to be db_val.value
+ end
+ end
+ end
+
+ context 'RailsSettings::Settings.object returns falsey' do
+ let(:object) { nil }
+
+ it 'returns default_settings[key]' do
+ expect(described_class[key]).to be default_settings[key]
+ end
+ end
+ end
+
+ context 'Rails.cache exists' do
+ before do
+ Rails.cache.write(cache_key, cache_value)
+ end
+
+ it 'returns the cached value' do
+ expect(described_class[key]).to eq cache_value
+ end
+ end
+ end
+ end
+
+ describe '.all_as_records' do
+ before do
+ allow_any_instance_of(Settings::ScopedSettings).to receive(:thing_scoped).and_return(records)
+ allow(described_class).to receive(:default_settings).and_return(default_settings)
+ end
+
+ let(:key) { 'key' }
+ let(:default_value) { 'default_value' }
+ let(:default_settings) { { key => default_value } }
+ let(:original_setting) { Fabricate(:setting, var: key, value: nil) }
+ let(:records) { [original_setting] }
+
+ it 'returns a Hash' do
+ expect(described_class.all_as_records).to be_kind_of Hash
+ end
+
+ context 'records includes Setting with var as the key' do
+ let(:records) { [original_setting] }
+
+ it 'includes the original Setting' do
+ setting = described_class.all_as_records[key]
+ expect(setting).to eq original_setting
+ end
+ end
+
+ context 'records includes nothing' do
+ let(:records) { [] }
+
+ context 'default_value is not a Hash' do
+ it 'includes Setting with value of default_value' do
+ setting = described_class.all_as_records[key]
+
+ expect(setting).to be_kind_of Setting
+ expect(setting).to have_attributes(var: key)
+ expect(setting).to have_attributes(value: 'default_value')
+ end
+ end
+
+ context 'default_value is a Hash' do
+ let(:default_value) { { 'foo' => 'fuga' } }
+
+ it 'returns {}' do
+ expect(described_class.all_as_records).to eq({})
+ end
+ end
+ end
+ end
+
+ describe '.default_settings' do
+ before do
+ allow(RailsSettings::Default).to receive(:enabled?).and_return(enabled)
+ end
+
+ subject { described_class.default_settings }
+
+ context 'RailsSettings::Default.enabled? is false' do
+ let(:enabled) { false }
+
+ it 'returns {}' do
+ is_expected.to eq({})
+ end
+ end
+
+ context 'RailsSettings::Settings.enabled? is true' do
+ let(:enabled) { true }
+
+ it 'returns instance of RailsSettings::Default' do
+ is_expected.to be_kind_of RailsSettings::Default
+ end
+ end
+ end
+end
diff --git a/spec/models/site_upload_spec.rb b/spec/models/site_upload_spec.rb
index 8745d54b8f..f7ea069213 100644
--- a/spec/models/site_upload_spec.rb
+++ b/spec/models/site_upload_spec.rb
@@ -1,5 +1,13 @@
+# frozen_string_literal: true
+
require 'rails_helper'
RSpec.describe SiteUpload, type: :model do
+ describe '#cache_key' do
+ let(:site_upload) { SiteUpload.new(var: 'var') }
+ it 'returns cache_key' do
+ expect(site_upload.cache_key).to eq 'site_uploads/var'
+ end
+ end
end
diff --git a/spec/models/stream_entry_spec.rb b/spec/models/stream_entry_spec.rb
index 3b7ff5143d..8f8bfbd583 100644
--- a/spec/models/stream_entry_spec.rb
+++ b/spec/models/stream_entry_spec.rb
@@ -6,6 +6,121 @@ RSpec.describe StreamEntry, type: :model do
let(:status) { Fabricate(:status, account: alice) }
let(:reblog) { Fabricate(:status, account: bob, reblog: status) }
let(:reply) { Fabricate(:status, account: bob, thread: status) }
+ let(:stream_entry) { Fabricate(:stream_entry, activity: activity) }
+ let(:activity) { reblog }
+
+ describe '#object_type' do
+ before do
+ allow(stream_entry).to receive(:orphaned?).and_return(orphaned)
+ allow(stream_entry).to receive(:targeted?).and_return(targeted)
+ end
+
+ subject { stream_entry.object_type }
+
+ context 'orphaned? is true' do
+ let(:orphaned) { true }
+ let(:targeted) { false }
+
+ it 'returns :activity' do
+ is_expected.to be :activity
+ end
+ end
+
+ context 'targeted? is true' do
+ let(:orphaned) { false }
+ let(:targeted) { true }
+
+ it 'returns :activity' do
+ is_expected.to be :activity
+ end
+ end
+
+ context 'orphaned? and targeted? are false' do
+ let(:orphaned) { false }
+ let(:targeted) { false }
+
+ context 'activity is reblog' do
+ let(:activity) { reblog }
+
+ it 'returns :note' do
+ is_expected.to be :note
+ end
+ end
+
+ context 'activity is reply' do
+ let(:activity) { reply }
+
+ it 'returns :comment' do
+ is_expected.to be :comment
+ end
+ end
+ end
+ end
+
+ describe '#verb' do
+ before do
+ allow(stream_entry).to receive(:orphaned?).and_return(orphaned)
+ end
+
+ subject { stream_entry.verb }
+
+ context 'orphaned? is true' do
+ let(:orphaned) { true }
+
+ it 'returns :delete' do
+ is_expected.to be :delete
+ end
+ end
+
+ context 'orphaned? is false' do
+ let(:orphaned) { false }
+
+ context 'activity is reblog' do
+ let(:activity) { reblog }
+
+ it 'returns :share' do
+ is_expected.to be :share
+ end
+ end
+
+ context 'activity is reply' do
+ let(:activity) { reply }
+
+ it 'returns :post' do
+ is_expected.to be :post
+ end
+ end
+ end
+ end
+
+ describe '#mentions' do
+ before do
+ allow(stream_entry).to receive(:orphaned?).and_return(orphaned)
+ end
+
+ subject { stream_entry.mentions }
+
+ context 'orphaned? is true' do
+ let(:orphaned) { true }
+
+ it 'returns []' do
+ is_expected.to eq []
+ end
+ end
+
+ context 'orphaned? is false' do
+ before do
+ reblog.mentions << Fabricate(:mention, account: alice)
+ reblog.mentions << Fabricate(:mention, account: bob)
+ end
+
+ let(:orphaned) { false }
+
+ it 'returns [Account] includes alice and bob' do
+ is_expected.to eq [alice, bob]
+ end
+ end
+ end
describe '#targeted?' do
it 'returns true for a reblog' do
diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb
index 7088ae9d1a..fad0dd3695 100644
--- a/spec/services/notify_service_spec.rb
+++ b/spec/services/notify_service_spec.rb
@@ -48,6 +48,39 @@ RSpec.describe NotifyService do
is_expected.to_not change(Notification, :count)
end
+ context 'for direct messages' do
+ let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct)) }
+
+ before do
+ user.settings.interactions = user.settings.interactions.merge('must_be_following_dm' => enabled)
+ end
+
+ context 'if recipient is supposed to be following sender' do
+ let(:enabled) { true }
+
+ it 'does not notify' do
+ is_expected.to_not change(Notification, :count)
+ end
+
+ context 'if the message chain initiated by recipient' do
+ let(:reply_to) { Fabricate(:status, account: recipient) }
+ let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct, thread: reply_to)) }
+
+ it 'does notify' do
+ is_expected.to change(Notification, :count)
+ end
+ end
+ end
+
+ context 'if recipient is NOT supposed to be following sender' do
+ let(:enabled) { false }
+
+ it 'does notify' do
+ is_expected.to change(Notification, :count)
+ end
+ end
+ end
+
context do
let(:asshole) { Fabricate(:account, username: 'asshole') }
let(:reply_to) { Fabricate(:status, account: asshole) }
diff --git a/yarn.lock b/yarn.lock
index 57860218c6..b7aa18a017 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3,23 +3,16 @@
"@types/node@^6.0.46":
- version "6.0.89"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.89.tgz#154be0e6a823760cd6083aa8c48f952e2e63e0b0"
+ version "6.0.90"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.90.tgz#0ed74833fa1b73dcdb9409dcb1c97ec0a8b13b02"
abab@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d"
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
abbrev@1:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
-
-accepts@~1.3.3:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca"
- dependencies:
- mime-types "~2.1.11"
- negotiator "0.6.1"
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
accepts@~1.3.4:
version "1.3.4"
@@ -54,9 +47,9 @@ acorn@^4.0.3, acorn@^4.0.4:
version "4.0.13"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
-acorn@^5.0.0, acorn@^5.0.1, acorn@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75"
+acorn@^5.0.0, acorn@^5.1.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7"
adjust-sourcemap-loader@^1.1.0:
version "1.1.0"
@@ -75,8 +68,8 @@ ajv-keywords@^1.0.0:
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
ajv-keywords@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.0.tgz#a296e17f7bfae7c1ce4f7e0de53d29cb32162df0"
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
ajv@^4.7.0, ajv@^4.9.1:
version "4.11.8"
@@ -85,14 +78,14 @@ ajv@^4.7.0, ajv@^4.9.1:
co "^4.6.0"
json-stable-stringify "^1.0.1"
-ajv@^5.0.0, ajv@^5.1.5:
- version "5.2.2"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39"
+ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda"
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
+ fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
- json-stable-stringify "^1.0.1"
align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4"
@@ -134,13 +127,7 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
-ansi-styles@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750"
- dependencies:
- color-convert "^1.0.0"
-
-ansi-styles@^3.2.0:
+ansi-styles@^3.1.0, ansi-styles@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
dependencies:
@@ -151,15 +138,11 @@ any-promise@^0.1.0:
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-0.1.0.tgz#830b680aa7e56f33451d4b049f3bd8044498ee27"
anymatch@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
dependencies:
- arrify "^1.0.0"
micromatch "^2.1.5"
-
-ap@~0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/ap/-/ap-0.2.0.tgz#ae0942600b29912f0d2b14ec60c45e8f330b6110"
+ normalize-path "^2.0.0"
append-transform@^0.4.0:
version "0.4.0"
@@ -168,8 +151,8 @@ append-transform@^0.4.0:
default-require-extensions "^1.0.0"
aproba@^1.0.3:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
are-we-there-yet@~1.1.2:
version "1.1.4"
@@ -294,15 +277,17 @@ async-foreach@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542"
-async@0.2.x:
- version "0.2.10"
- resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
+async@2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7"
+ dependencies:
+ lodash "^4.14.0"
async@^1.4.0, async@^1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
-async@^2.1.2, async@^2.1.4, async@^2.1.5:
+async@^2.1.2, async@^2.1.4, async@^2.1.5, async@^2.4.1:
version "2.5.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d"
dependencies:
@@ -327,41 +312,45 @@ autoprefixer@^6.3.1:
postcss "^5.2.16"
postcss-value-parser "^3.2.3"
-autoprefixer@^7.1.2:
- version "7.1.4"
- resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.4.tgz#960847dbaa4016bc8e8e52ec891cbf8f1257a748"
+autoprefixer@^7.1.6:
+ version "7.1.6"
+ resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.6.tgz#fb933039f74af74a83e71225ce78d9fd58ba84d7"
dependencies:
- browserslist "^2.4.0"
- caniuse-lite "^1.0.30000726"
+ browserslist "^2.5.1"
+ caniuse-lite "^1.0.30000748"
normalize-range "^0.1.2"
num2fraction "^1.2.2"
- postcss "^6.0.11"
+ postcss "^6.0.13"
postcss-value-parser "^3.2.3"
aws-sign2@~0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
-aws4@^1.2.1:
+aws-sign2@~0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
+
+aws4@^1.2.1, aws4@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
-axios@^0.16.2:
+axios@~0.16.2:
version "0.16.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d"
dependencies:
follow-redirects "^1.2.3"
is-buffer "^1.1.5"
-babel-code-frame@^6.11.0, babel-code-frame@^6.16.0, babel-code-frame@^6.22.0:
- version "6.22.0"
- resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
+babel-code-frame@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-7.0.0-beta.0.tgz#418a7b5f3f7dc9a4670e61b1158b4c5661bec98d"
dependencies:
- chalk "^1.1.0"
+ chalk "^2.0.0"
esutils "^2.0.2"
js-tokens "^3.0.0"
-babel-code-frame@^6.26.0:
+babel-code-frame@^6.11.0, babel-code-frame@^6.16.0, babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
dependencies:
@@ -402,6 +391,15 @@ babel-eslint@^7.2.3:
babel-types "^6.23.0"
babylon "^6.17.0"
+babel-eslint@^8.0.1:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.0.1.tgz#5d718be7a328625d006022eb293ed3008cbd6346"
+ dependencies:
+ babel-code-frame "7.0.0-beta.0"
+ babel-traverse "7.0.0-beta.0"
+ babel-types "7.0.0-beta.0"
+ babylon "7.0.0-beta.22"
+
babel-generator@^6.18.0, babel-generator@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5"
@@ -424,12 +422,12 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
babel-types "^6.24.1"
babel-helper-builder-react-jsx@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.24.1.tgz#0ad7917e33c8d751e646daca4e77cc19377d2cbc"
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0"
dependencies:
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
- esutils "^2.0.0"
+ babel-runtime "^6.26.0"
+ babel-types "^6.26.0"
+ esutils "^2.0.2"
babel-helper-call-delegate@^6.24.1:
version "6.24.1"
@@ -441,13 +439,13 @@ babel-helper-call-delegate@^6.24.1:
babel-types "^6.24.1"
babel-helper-define-map@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz#7a9747f258d8947d32d515f6aa1c7bd02204a080"
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f"
dependencies:
babel-helper-function-name "^6.24.1"
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
- lodash "^4.2.0"
+ babel-runtime "^6.26.0"
+ babel-types "^6.26.0"
+ lodash "^4.17.4"
babel-helper-explode-assignable-expression@^6.24.1:
version "6.24.1"
@@ -457,6 +455,15 @@ babel-helper-explode-assignable-expression@^6.24.1:
babel-traverse "^6.24.1"
babel-types "^6.24.1"
+babel-helper-function-name@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-7.0.0-beta.0.tgz#d1b6779b647e5c5c31ebeb05e13b998e4d352d56"
+ dependencies:
+ babel-helper-get-function-arity "7.0.0-beta.0"
+ babel-template "7.0.0-beta.0"
+ babel-traverse "7.0.0-beta.0"
+ babel-types "7.0.0-beta.0"
+
babel-helper-function-name@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
@@ -467,6 +474,12 @@ babel-helper-function-name@^6.24.1:
babel-traverse "^6.24.1"
babel-types "^6.24.1"
+babel-helper-get-function-arity@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-beta.0.tgz#9d1ab7213bb5efe1ef1638a8ea1489969b5a8b6e"
+ dependencies:
+ babel-types "7.0.0-beta.0"
+
babel-helper-get-function-arity@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d"
@@ -489,12 +502,12 @@ babel-helper-optimise-call-expression@^6.24.1:
babel-types "^6.24.1"
babel-helper-regex@^6.24.1:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz#d36e22fab1008d79d88648e32116868128456ce8"
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72"
dependencies:
- babel-runtime "^6.22.0"
- babel-types "^6.24.1"
- lodash "^4.2.0"
+ babel-runtime "^6.26.0"
+ babel-types "^6.26.0"
+ lodash "^4.17.4"
babel-helper-remap-async-to-generator@^6.24.1:
version "6.24.1"
@@ -539,9 +552,15 @@ babel-loader@^7.1.1:
loader-utils "^1.0.2"
mkdirp "^0.5.1"
-babel-macros@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/babel-macros/-/babel-macros-1.0.2.tgz#04475889990243cc58a0afb5ea3308ec6b89e797"
+babel-macros@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/babel-macros/-/babel-macros-1.2.0.tgz#39e47ed6d286d4a98f1948d8bab45dac17e4e2d4"
+ dependencies:
+ cosmiconfig "3.1.0"
+
+babel-messages@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-7.0.0-beta.0.tgz#6df01296e49fc8fbd0637394326a167f36da817b"
babel-messages@^6.23.0:
version "6.23.0"
@@ -574,15 +593,15 @@ babel-plugin-lodash@^3.2.11:
glob "^7.1.1"
lodash "^4.17.2"
-babel-plugin-preval@^1.3.2:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-preval/-/babel-plugin-preval-1.5.0.tgz#be4e3353ce6ec4fd0c6b199701193306033bf54b"
+babel-plugin-preval@^1.6.1:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-preval/-/babel-plugin-preval-1.6.1.tgz#c33fd124f9cb9281550cae35ff0ea6065e32261d"
dependencies:
babel-core "^6.26.0"
- babel-macros "^1.0.0"
+ babel-macros "^1.1.1"
babel-register "^6.26.0"
babylon "^6.18.0"
- require-from-string "^1.2.1"
+ require-from-string "^2.0.1"
babel-plugin-react-intl@^2.3.1:
version "2.3.1"
@@ -592,12 +611,6 @@ babel-plugin-react-intl@^2.3.1:
intl-messageformat-parser "^1.2.0"
mkdirp "^0.5.1"
-babel-plugin-react-transform@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/babel-plugin-react-transform/-/babel-plugin-react-transform-2.0.2.tgz#515bbfa996893981142d90b1f9b1635de2995109"
- dependencies:
- lodash "^4.6.1"
-
babel-plugin-syntax-async-functions@^6.8.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
@@ -672,14 +685,14 @@ babel-plugin-transform-es2015-block-scoped-functions@^6.22.0:
babel-runtime "^6.22.0"
babel-plugin-transform-es2015-block-scoping@^6.23.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576"
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f"
dependencies:
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
- babel-traverse "^6.24.1"
- babel-types "^6.24.1"
- lodash "^4.2.0"
+ babel-runtime "^6.26.0"
+ babel-template "^6.26.0"
+ babel-traverse "^6.26.0"
+ babel-types "^6.26.0"
+ lodash "^4.17.4"
babel-plugin-transform-es2015-classes@^6.23.0:
version "6.24.1"
@@ -743,16 +756,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015
babel-runtime "^6.22.0"
babel-template "^6.24.1"
-babel-plugin-transform-es2015-modules-commonjs@^6.23.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe"
- dependencies:
- babel-plugin-transform-strict-mode "^6.24.1"
- babel-runtime "^6.22.0"
- babel-template "^6.24.1"
- babel-types "^6.24.1"
-
-babel-plugin-transform-es2015-modules-commonjs@^6.24.1:
+babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a"
dependencies:
@@ -892,17 +896,15 @@ babel-plugin-transform-react-jsx@^6.24.1:
babel-plugin-syntax-jsx "^6.8.0"
babel-runtime "^6.22.0"
-babel-plugin-transform-react-remove-prop-types@^0.4.6:
- version "0.4.8"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.8.tgz#0aff04bc1d6564ec49cf23bcffb99c11881958db"
- dependencies:
- babel-traverse "^6.25.0"
+babel-plugin-transform-react-remove-prop-types@^0.4.10:
+ version "0.4.10"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.10.tgz#3c7f3a03ad8aa6bb8c00e93fd13a433910444545"
babel-plugin-transform-regenerator@^6.22.0:
- version "6.24.1"
- resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418"
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f"
dependencies:
- regenerator-transform "0.9.11"
+ regenerator-transform "^0.10.0"
babel-plugin-transform-runtime@^6.23.0:
version "6.23.0"
@@ -917,9 +919,9 @@ babel-plugin-transform-strict-mode@^6.24.1:
babel-runtime "^6.22.0"
babel-types "^6.24.1"
-babel-preset-env@^1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.0.tgz#2de1c782a780a0a5d605d199c957596da43c44e4"
+babel-preset-env@^1.6.1:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48"
dependencies:
babel-plugin-check-es2015-constants "^6.22.0"
babel-plugin-syntax-trailing-function-commas "^6.22.0"
@@ -988,21 +990,23 @@ babel-register@^6.26.0:
mkdirp "^0.5.1"
source-map-support "^0.4.15"
-babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0:
- version "6.23.0"
- resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b"
- dependencies:
- core-js "^2.4.0"
- regenerator-runtime "^0.10.0"
-
-babel-runtime@^6.26.0:
+babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
dependencies:
core-js "^2.4.0"
regenerator-runtime "^0.11.0"
-babel-template@^6.16.0, babel-template@^6.26.0:
+babel-template@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-7.0.0-beta.0.tgz#85083cf9e4395d5e48bf5154d7a8d6991cafecfb"
+ dependencies:
+ babel-traverse "7.0.0-beta.0"
+ babel-types "7.0.0-beta.0"
+ babylon "7.0.0-beta.22"
+ lodash "^4.2.0"
+
+babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.3.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02"
dependencies:
@@ -1012,17 +1016,21 @@ babel-template@^6.16.0, babel-template@^6.26.0:
babylon "^6.18.0"
lodash "^4.17.4"
-babel-template@^6.24.1, babel-template@^6.3.0:
- version "6.25.0"
- resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071"
+babel-traverse@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-7.0.0-beta.0.tgz#da14be9b762f62a2f060db464eaafdd8cd072a41"
dependencies:
- babel-runtime "^6.22.0"
- babel-traverse "^6.25.0"
- babel-types "^6.25.0"
- babylon "^6.17.2"
+ babel-code-frame "7.0.0-beta.0"
+ babel-helper-function-name "7.0.0-beta.0"
+ babel-messages "7.0.0-beta.0"
+ babel-types "7.0.0-beta.0"
+ babylon "7.0.0-beta.22"
+ debug "^3.0.1"
+ globals "^10.0.0"
+ invariant "^2.2.0"
lodash "^4.2.0"
-babel-traverse@^6.18.0, babel-traverse@^6.26.0:
+babel-traverse@^6.18.0, babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-traverse@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
dependencies:
@@ -1036,21 +1044,15 @@ babel-traverse@^6.18.0, babel-traverse@^6.26.0:
invariant "^2.2.2"
lodash "^4.17.4"
-babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-traverse@^6.25.0:
- version "6.25.0"
- resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1"
+babel-types@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.0.tgz#eb8b6e556470e6dcc4aef982d79ad229469b5169"
dependencies:
- babel-code-frame "^6.22.0"
- babel-messages "^6.23.0"
- babel-runtime "^6.22.0"
- babel-types "^6.25.0"
- babylon "^6.17.2"
- debug "^2.2.0"
- globals "^9.0.0"
- invariant "^2.2.0"
+ esutils "^2.0.2"
lodash "^4.2.0"
+ to-fast-properties "^2.0.0"
-babel-types@^6.18.0, babel-types@^6.26.0:
+babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
dependencies:
@@ -1059,20 +1061,11 @@ babel-types@^6.18.0, babel-types@^6.26.0:
lodash "^4.17.4"
to-fast-properties "^1.0.3"
-babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.25.0:
- version "6.25.0"
- resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e"
- dependencies:
- babel-runtime "^6.22.0"
- esutils "^2.0.2"
- lodash "^4.2.0"
- to-fast-properties "^1.0.1"
+babylon@7.0.0-beta.22:
+ version "7.0.0-beta.22"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.22.tgz#74f0ad82ed7c7c3cfeab74cf684f815104161b65"
-babylon@^6.17.0, babylon@^6.17.2:
- version "6.17.4"
- resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a"
-
-babylon@^6.18.0:
+babylon@^6.17.0, babylon@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
@@ -1109,12 +1102,12 @@ bcrypt-pbkdf@^1.0.0:
tweetnacl "^0.14.3"
big.js@^3.1.3:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978"
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
binary-extensions@^1.0.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774"
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.10.0.tgz#9aeb9a6c5e88638aad171e167f5900abe24835d0"
block-stream@*:
version "0.0.9"
@@ -1123,8 +1116,8 @@ block-stream@*:
inherits "~2.0.0"
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
- version "4.11.7"
- resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.7.tgz#ddb048e50d9482790094c13eb3fcfc833ce7ab46"
+ version "4.11.8"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
body-parser@1.18.2:
version "1.18.2"
@@ -1162,6 +1155,18 @@ boom@2.x.x:
dependencies:
hoek "2.x.x"
+boom@4.x.x:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
+ dependencies:
+ hoek "4.x.x"
+
+boom@5.x.x:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
+ dependencies:
+ hoek "4.x.x"
+
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
@@ -1188,14 +1193,15 @@ browser-resolve@^1.11.2:
resolve "1.1.7"
browserify-aes@^1.0.0, browserify-aes@^1.0.4:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.6.tgz#5e7725dbdef1fd5930d4ebab48567ce451c48a0a"
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f"
dependencies:
- buffer-xor "^1.0.2"
+ buffer-xor "^1.0.3"
cipher-base "^1.0.0"
create-hash "^1.1.0"
- evp_bytestokey "^1.0.0"
+ evp_bytestokey "^1.0.3"
inherits "^2.0.1"
+ safe-buffer "^5.0.1"
browserify-cipher@^1.0.0:
version "1.0.0"
@@ -1245,19 +1251,12 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6:
caniuse-db "^1.0.30000639"
electron-to-chromium "^1.2.7"
-browserslist@^2.1.2:
- version "2.1.5"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.1.5.tgz#e882550df3d1cd6d481c1a3e0038f2baf13a4711"
+browserslist@^2.1.2, browserslist@^2.5.1:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.6.1.tgz#cc65a05ad6131ebda26f076f2822ba1bc826376b"
dependencies:
- caniuse-lite "^1.0.30000684"
- electron-to-chromium "^1.3.14"
-
-browserslist@^2.4.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.4.0.tgz#693ee93d01e66468a6348da5498e011f578f87f8"
- dependencies:
- caniuse-lite "^1.0.30000718"
- electron-to-chromium "^1.3.18"
+ caniuse-lite "^1.0.30000755"
+ electron-to-chromium "^1.3.27"
bser@^2.0.0:
version "2.0.0"
@@ -1266,14 +1265,14 @@ bser@^2.0.0:
node-int64 "^0.4.0"
buffer-indexof@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.0.tgz#f54f647c4f4e25228baa656a2e57e43d5f270982"
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
buffer-writer@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-1.0.1.tgz#22a936901e3029afcd7547eb4487ceb697a3bf08"
-buffer-xor@^1.0.2:
+buffer-xor@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
@@ -1293,10 +1292,6 @@ builtin-status-codes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
-bytes@2.5.0:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.5.0.tgz#4c9423ea2d252c270c41b2bdefeff9bb6b62c06a"
-
bytes@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
@@ -1352,16 +1347,12 @@ caniuse-api@^1.5.2:
lodash.uniq "^4.5.0"
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
- version "1.0.30000700"
- resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000700.tgz#97cfc483865eea8577dc7a3674929b9abf553095"
+ version "1.0.30000755"
+ resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000755.tgz#a08c547c39dbe4ad07dcca9763fcbbff0c891de0"
-caniuse-lite@^1.0.30000684:
- version "1.0.30000700"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000700.tgz#6084871ec75c6fa62327de97622514f95d9db26a"
-
-caniuse-lite@^1.0.30000718, caniuse-lite@^1.0.30000726:
- version "1.0.30000740"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000740.tgz#f2c4c04d6564eb812e61006841700ad557f6f973"
+caniuse-lite@^1.0.30000748, caniuse-lite@^1.0.30000755:
+ version "1.0.30000755"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000755.tgz#9ce5f6e06bd75ec8209abe8853c3beef02248d65"
caseless@~0.12.0:
version "0.12.0"
@@ -1378,7 +1369,7 @@ chain-function@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc"
-chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
+chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
@@ -1388,17 +1379,9 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
-chalk@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.0.1.tgz#dbec49436d2ae15f536114e76d14656cdbc0f44d"
- dependencies:
- ansi-styles "^3.1.0"
- escape-string-regexp "^1.0.5"
- supports-color "^4.0.0"
-
-chalk@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e"
+chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
dependencies:
ansi-styles "^3.1.0"
escape-string-regexp "^1.0.5"
@@ -1442,12 +1425,12 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
safe-buffer "^5.0.1"
circular-json@^0.3.1:
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d"
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
clap@^1.0.9:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.0.tgz#59c90fe3e137104746ff19469a27a634ff68c857"
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51"
dependencies:
chalk "^1.1.3"
@@ -1462,8 +1445,8 @@ cli-cursor@^1.0.1:
restore-cursor "^1.0.1"
cli-width@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
cliui@^2.1.0:
version "2.1.0"
@@ -1508,15 +1491,15 @@ code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
-color-convert@^1.0.0, color-convert@^1.3.0, color-convert@^1.9.0:
+color-convert@^1.3.0, color-convert@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
dependencies:
color-name "^1.1.1"
color-name@^1.0.0, color-name@^1.1.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d"
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
color-string@^0.3.0:
version "0.3.0"
@@ -1566,32 +1549,30 @@ complex.js@2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.4.tgz#d8e7cfb9652d1e853e723386421c1a0ca7a48373"
-compressible@~2.0.10:
- version "2.0.10"
- resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.10.tgz#feda1c7f7617912732b29bf8cf26252a20b9eecd"
+compressible@~2.0.11:
+ version "2.0.12"
+ resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.12.tgz#c59a5c99db76767e9876500e271ef63b3493bd66"
dependencies:
- mime-db ">= 1.27.0 < 2"
+ mime-db ">= 1.30.0 < 2"
-compression-webpack-plugin@^0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-0.4.0.tgz#811de04215f811ea6a12d4d8aed8457d758f13ac"
+compression-webpack-plugin@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-1.0.1.tgz#7f0a2af9f642b4f87b5989516a3b9e9b41bb4b3f"
dependencies:
- async "0.2.x"
- webpack-sources "^0.1.0"
- optionalDependencies:
- node-zopfli "^2.0.0"
+ async "2.4.1"
+ webpack-sources "^1.0.1"
compression@^1.5.2:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.0.tgz#030c9f198f1643a057d776a738e922da4373012d"
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.1.tgz#eff2603efc2e22cf86f35d2eb93589f9875373db"
dependencies:
- accepts "~1.3.3"
- bytes "2.5.0"
- compressible "~2.0.10"
- debug "2.6.8"
+ accepts "~1.3.4"
+ bytes "3.0.0"
+ compressible "~2.0.11"
+ debug "2.6.9"
on-headers "~1.0.1"
safe-buffer "5.1.1"
- vary "~1.1.1"
+ vary "~1.1.2"
concat-map@0.0.1:
version "0.0.1"
@@ -1606,8 +1587,8 @@ concat-stream@^1.5.2:
typedarray "^0.0.6"
connect-history-api-fallback@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz#e51d17f8f0ef0db90a64fdb47de3051556e9f169"
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.4.0.tgz#3db24f973f4b923b0e82f619ce0df02411ca623d"
console-browserify@^1.1.0:
version "1.1.0"
@@ -1632,12 +1613,8 @@ content-disposition@0.5.2:
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
content-type-parser@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.1.tgz#c3e56988c53c65127fb46d4032a3a900246fdc94"
-
-content-type@~1.0.2:
version "1.0.2"
- resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed"
+ resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7"
content-type@~1.0.4:
version "1.0.4"
@@ -1663,21 +1640,26 @@ core-js@^1.0.0:
version "1.2.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
-core-js@^2.4.0:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
-
-core-js@^2.5.0:
+core-js@^2.4.0, core-js@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
-core-util-is@~1.0.0:
+core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+cosmiconfig@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-3.1.0.tgz#640a94bf9847f321800403cd273af60665c73397"
+ dependencies:
+ is-directory "^0.3.1"
+ js-yaml "^3.9.0"
+ parse-json "^3.0.0"
+ require-from-string "^2.0.1"
+
cosmiconfig@^2.1.0, cosmiconfig@^2.1.1:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.1.3.tgz#952771eb0dddc1cb3fa2f6fbe51a522e93b3ee0a"
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.2.2.tgz#6173cebd56fac042c1f4390edf7af6c07c7cb892"
dependencies:
is-directory "^0.3.1"
js-yaml "^3.4.3"
@@ -1694,7 +1676,7 @@ create-ecdh@^4.0.0:
bn.js "^4.1.0"
elliptic "^6.0.0"
-create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2:
+create-hash@^1.1.0, create-hash@^1.1.2:
version "1.1.3"
resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd"
dependencies:
@@ -1722,9 +1704,9 @@ create-react-class@^15.5.2:
loose-envify "^1.3.1"
object-assign "^4.1.1"
-cross-env@^5.0.1:
- version "5.0.5"
- resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.0.5.tgz#4383d364d9660873dd185b398af3bfef5efffef3"
+cross-env@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.1.1.tgz#b6d8ab97f304c0f71dae7277b75fe424c08dfa74"
dependencies:
cross-spawn "^5.1.0"
is-windows "^1.0.0"
@@ -1736,14 +1718,7 @@ cross-spawn@^3.0.0:
lru-cache "^4.0.1"
which "^1.2.9"
-cross-spawn@^4.0.0:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41"
- dependencies:
- lru-cache "^4.0.1"
- which "^1.2.9"
-
-cross-spawn@^5.1.0:
+cross-spawn@^5.0.1, cross-spawn@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
dependencies:
@@ -1757,6 +1732,12 @@ cryptiles@2.x.x:
dependencies:
boom "2.x.x"
+cryptiles@3.x.x:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
+ dependencies:
+ boom "5.x.x"
+
crypto-browserify@^3.11.0:
version "3.11.1"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.1.tgz#948945efc6757a400d6e5e5af47194d10064279f"
@@ -1773,12 +1754,12 @@ crypto-browserify@^3.11.0:
randombytes "^2.0.0"
css-color-function@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/css-color-function/-/css-color-function-1.3.0.tgz#72c767baf978f01b8a8a94f42f17ba5d22a776fc"
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/css-color-function/-/css-color-function-1.3.3.tgz#8ed24c2c0205073339fafa004bc8c141fccb282e"
dependencies:
balanced-match "0.1.0"
color "^0.11.0"
- debug "~0.7.4"
+ debug "^3.1.0"
rgb "~0.1.0"
css-color-names@0.0.4:
@@ -1948,27 +1929,17 @@ date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
-debug@2.6.7:
- version "2.6.7"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e"
- dependencies:
- ms "2.0.0"
-
-debug@2.6.8, debug@^2.1.1, debug@^2.2.0, debug@^2.4.5, debug@^2.6.6, debug@^2.6.8:
- version "2.6.8"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
- dependencies:
- ms "2.0.0"
-
-debug@2.6.9, debug@^2.6.3:
+debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
ms "2.0.0"
-debug@~0.7.4:
- version "0.7.4"
- resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39"
+debug@^3.0.1, debug@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
+ dependencies:
+ ms "2.0.0"
decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2:
version "1.2.0"
@@ -2044,10 +2015,6 @@ delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
-depd@1.1.0, depd@~1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3"
-
depd@1.1.1, depd@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"
@@ -2098,8 +2065,8 @@ dns-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
dns-packet@^1.0.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.1.1.tgz#2369d45038af045f3898e6fa56862aed3f40296c"
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.2.2.tgz#a8a26bec7646438963fc86e06f8f8b16d6c8bf7a"
dependencies:
ip "^1.1.0"
safe-buffer "^5.0.1"
@@ -2124,7 +2091,7 @@ doctrine@^2.0.0:
esutils "^2.0.2"
isarray "^1.0.0"
-dom-helpers@^3.0.0, dom-helpers@^3.2.0, dom-helpers@^3.2.1:
+dom-helpers@^3.2.0, dom-helpers@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a"
@@ -2190,16 +2157,12 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
ejs@^2.3.4, ejs@^2.5.6:
- version "2.5.6"
- resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.6.tgz#479636bfa3fe3b1debd52087f0acb204b4f19c88"
+ version "2.5.7"
+ resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a"
-electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.14:
- version "1.3.15"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.15.tgz#08397934891cbcfaebbd18b82a95b5a481138369"
-
-electron-to-chromium@^1.3.18:
- version "1.3.24"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz#9b7b88bb05ceb9fa016a177833cc2dde388f21b6"
+electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.27:
+ version "1.3.27"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz#78ecb8a399066187bb374eede35d9c70565a803d"
elliptic@^6.0.0:
version "6.4.0"
@@ -2218,8 +2181,8 @@ emoji-mart@Gargron/emoji-mart#build:
resolved "https://codeload.github.com/Gargron/emoji-mart/tar.gz/a5e1afe5ebcf2841e611d20d261b029581cbe051"
emoji-regex@^6.1.0:
- version "6.4.3"
- resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.4.3.tgz#6ac2ac58d4b78def5e39b33fcbf395688af3076c"
+ version "6.5.1"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2"
emojis-list@^2.0.0:
version "2.1.0"
@@ -2248,15 +2211,16 @@ entities@^1.1.1, entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
-enzyme-adapter-react-16@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.1.tgz#066cb1735e65d8d95841a023f94dab3ce6109e17"
+enzyme-adapter-react-16@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.2.tgz#8c6f431f17c69e1e9eeb25ca4bd92f31971eb2dd"
dependencies:
enzyme-adapter-utils "^1.0.0"
lodash "^4.17.4"
object.assign "^4.0.4"
object.values "^1.0.4"
prop-types "^15.5.10"
+ react-test-renderer "^16.0.0-0"
enzyme-adapter-utils@^1.0.0:
version "1.0.1"
@@ -2287,13 +2251,13 @@ errno@^0.1.3, errno@^0.1.4:
dependencies:
prr "~0.0.0"
-error-ex@^1.2.0:
+error-ex@^1.2.0, error-ex@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
dependencies:
is-arrayish "^0.2.1"
-es-abstract@^1.6.1:
+es-abstract@^1.6.1, es-abstract@^1.7.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227"
dependencies:
@@ -2303,15 +2267,6 @@ es-abstract@^1.6.1:
is-callable "^1.1.3"
is-regex "^1.0.4"
-es-abstract@^1.7.0:
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c"
- dependencies:
- es-to-primitive "^1.1.1"
- function-bind "^1.1.0"
- is-callable "^1.1.3"
- is-regex "^1.0.3"
-
es-to-primitive@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
@@ -2320,20 +2275,20 @@ es-to-primitive@^1.1.1:
is-date-object "^1.0.1"
is-symbol "^1.0.1"
-es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14:
- version "0.10.24"
- resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.24.tgz#a55877c9924bc0c8d9bd3c2cbe17495ac1709b14"
+es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14:
+ version "0.10.35"
+ resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.35.tgz#18ee858ce6a3c45c7d79e91c15fcca9ec568494f"
dependencies:
- es6-iterator "2"
- es6-symbol "~3.1"
+ es6-iterator "~2.0.1"
+ es6-symbol "~3.1.1"
-es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512"
+es6-iterator@^2.0.1, es6-iterator@~2.0.1:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
dependencies:
d "1"
- es5-ext "^0.10.14"
- es6-symbol "^3.1"
+ es5-ext "^0.10.35"
+ es6-symbol "^3.1.1"
es6-map@^0.1.3:
version "0.1.5"
@@ -2356,7 +2311,7 @@ es6-set@~0.1.5:
es6-symbol "3.1.1"
event-emitter "~0.3.5"
-es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1:
+es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
dependencies:
@@ -2381,15 +2336,15 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
escodegen@^1.6.1:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018"
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.0.tgz#9811a2f265dc1cd3894420ee3717064b632b8852"
dependencies:
- esprima "^2.7.1"
- estraverse "^1.9.1"
+ esprima "^3.1.3"
+ estraverse "^4.2.0"
esutils "^2.0.2"
optionator "^0.8.1"
optionalDependencies:
- source-map "~0.2.0"
+ source-map "~0.5.6"
escope@^3.6.0:
version "3.6.0"
@@ -2414,9 +2369,9 @@ eslint-module-utils@^2.1.1:
debug "^2.6.8"
pkg-dir "^1.0.0"
-eslint-plugin-import@^2.7.0:
- version "2.7.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz#21de33380b9efb55f5ef6d2e210ec0e07e7fa69f"
+eslint-plugin-import@^2.8.0:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz#fa1b6ef31fcb3c501c09859c1b86f1fc5b986894"
dependencies:
builtin-modules "^1.1.1"
contains-path "^0.1.0"
@@ -2491,16 +2446,20 @@ eslint@^3.19.0:
user-home "^2.0.0"
espree@^3.4.0:
- version "3.4.3"
- resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.3.tgz#2910b5ccd49ce893c2ffffaab4fd8b3a31b82374"
+ version "3.5.1"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.1.tgz#0c988b8ab46db53100a1954ae4ba995ddd27d87e"
dependencies:
- acorn "^5.0.1"
+ acorn "^5.1.1"
acorn-jsx "^3.0.0"
-esprima@^2.6.0, esprima@^2.7.1:
+esprima@^2.6.0:
version "2.7.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
+esprima@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
+
esprima@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
@@ -2518,22 +2477,14 @@ esrecurse@^4.1.0:
estraverse "^4.1.0"
object-assign "^4.0.1"
-estraverse@^1.9.1:
- version "1.9.3"
- resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
-
estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
-esutils@^2.0.0, esutils@^2.0.2:
+esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
-etag@~1.8.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051"
-
etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
@@ -2559,11 +2510,12 @@ eventsource@0.1.6:
dependencies:
original ">=0.0.5"
-evp_bytestokey@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz#497b66ad9fef65cd7c08a6180824ba1476b66e53"
+evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02"
dependencies:
- create-hash "^1.1.1"
+ md5.js "^1.3.4"
+ safe-buffer "^5.1.1"
exec-sh@^0.2.0:
version "0.2.1"
@@ -2571,12 +2523,12 @@ exec-sh@^0.2.0:
dependencies:
merge "^1.1.3"
-execa@^0.5.0:
- version "0.5.1"
- resolved "https://registry.yarnpkg.com/execa/-/execa-0.5.1.tgz#de3fb85cb8d6e91c85bcbceb164581785cb57b36"
+execa@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
dependencies:
- cross-spawn "^4.0.0"
- get-stream "^2.2.0"
+ cross-spawn "^5.0.1"
+ get-stream "^3.0.0"
is-stream "^1.1.0"
npm-run-path "^2.0.0"
p-finally "^1.0.0"
@@ -2610,42 +2562,9 @@ expect@^21.2.1:
jest-message-util "^21.2.1"
jest-regex-util "^21.2.0"
-express@^4.13.3:
- version "4.15.3"
- resolved "https://registry.yarnpkg.com/express/-/express-4.15.3.tgz#bab65d0f03aa80c358408972fc700f916944b662"
- dependencies:
- accepts "~1.3.3"
- array-flatten "1.1.1"
- content-disposition "0.5.2"
- content-type "~1.0.2"
- cookie "0.3.1"
- cookie-signature "1.0.6"
- debug "2.6.7"
- depd "~1.1.0"
- encodeurl "~1.0.1"
- escape-html "~1.0.3"
- etag "~1.8.0"
- finalhandler "~1.0.3"
- fresh "0.5.0"
- merge-descriptors "1.0.1"
- methods "~1.1.2"
- on-finished "~2.3.0"
- parseurl "~1.3.1"
- path-to-regexp "0.1.7"
- proxy-addr "~1.1.4"
- qs "6.4.0"
- range-parser "~1.2.0"
- send "0.15.3"
- serve-static "1.12.3"
- setprototypeof "1.0.3"
- statuses "~1.3.1"
- type-is "~1.6.15"
- utils-merge "1.0.0"
- vary "~1.1.1"
-
-express@^4.15.2:
- version "4.16.1"
- resolved "https://registry.yarnpkg.com/express/-/express-4.16.1.tgz#6b33b560183c9b253b7b62144df33a4654ac9ed0"
+express@^4.13.3, express@^4.15.2, express@^4.16.2:
+ version "4.16.2"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c"
dependencies:
accepts "~1.3.4"
array-flatten "1.1.1"
@@ -2678,7 +2597,7 @@ express@^4.15.2:
utils-merge "1.0.1"
vary "~1.1.2"
-extend@~3.0.0:
+extend@~3.0.0, extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
@@ -2688,23 +2607,27 @@ extglob@^0.3.1:
dependencies:
is-extglob "^1.0.0"
-extract-text-webpack-plugin@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.1.2.tgz#756ef4efa8155c3681833fbc34da53b941746d6c"
+extract-text-webpack-plugin@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz#5f043eaa02f9750a9258b78c0a6e0dc1408fb2f7"
dependencies:
- async "^2.1.2"
- loader-utils "^1.0.2"
+ async "^2.4.1"
+ loader-utils "^1.1.0"
schema-utils "^0.3.0"
webpack-sources "^1.0.1"
-extsprintf@1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550"
+extsprintf@1.3.0, extsprintf@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
fast-deep-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
+fast-json-stable-stringify@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
+
fast-levenshtein@~2.0.4:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
@@ -2731,7 +2654,7 @@ fb-watchman@^2.0.0:
dependencies:
bser "^2.0.0"
-fbjs@^0.8.14, fbjs@^0.8.16:
+fbjs@^0.8.16, fbjs@^0.8.4, fbjs@^0.8.9:
version "0.8.16"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
dependencies:
@@ -2743,18 +2666,6 @@ fbjs@^0.8.14, fbjs@^0.8.16:
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"
-fbjs@^0.8.4, fbjs@^0.8.9:
- version "0.8.12"
- resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04"
- dependencies:
- core-js "^1.0.0"
- isomorphic-fetch "^2.1.1"
- loose-envify "^1.0.0"
- object-assign "^4.1.0"
- promise "^7.1.1"
- setimmediate "^1.0.5"
- ua-parser-js "^0.7.9"
-
figures@^1.3.5:
version "1.7.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
@@ -2787,8 +2698,8 @@ fileset@^2.0.2:
minimatch "^3.0.3"
filesize@^3.5.9:
- version "3.5.10"
- resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.10.tgz#fc8fa23ddb4ef9e5e0ab6e1e64f679a24a56761f"
+ version "3.5.11"
+ resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.11.tgz#1919326749433bb3cf77368bd158caabcc19e9ee"
fill-range@^2.1.0:
version "2.2.3"
@@ -2812,18 +2723,6 @@ finalhandler@1.1.0:
statuses "~1.3.1"
unpipe "~1.0.0"
-finalhandler@~1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.3.tgz#ef47e77950e999780e86022a560e3217e0d0cc89"
- dependencies:
- debug "2.6.7"
- encodeurl "~1.0.1"
- escape-html "~1.0.3"
- on-finished "~2.3.0"
- parseurl "~1.3.1"
- statuses "~1.3.1"
- unpipe "~1.0.0"
-
find-cache-dir@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f"
@@ -2846,8 +2745,8 @@ find-up@^2.0.0, find-up@^2.1.0:
locate-path "^2.0.0"
flat-cache@^1.2.1:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96"
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481"
dependencies:
circular-json "^0.3.1"
del "^2.0.2"
@@ -2859,10 +2758,10 @@ flatten@^1.0.2:
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
follow-redirects@^1.2.3:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.4.tgz#355e8f4d16876b43f577b0d5ce2668b9723214ea"
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.5.tgz#ffd3e14cbdd5eaa72f61b6368c1f68516c2a26cc"
dependencies:
- debug "^2.4.5"
+ debug "^2.6.9"
font-awesome@^4.7.0:
version "4.7.0"
@@ -2904,9 +2803,13 @@ form-data@~2.1.1:
combined-stream "^1.0.5"
mime-types "^2.1.12"
-forwarded@~0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363"
+form-data@~2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.5"
+ mime-types "^2.1.12"
forwarded@~0.1.2:
version "0.1.2"
@@ -2916,10 +2819,6 @@ fraction.js@4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.2.tgz#0eae896626f334b1bde763371347a83b5575d7f0"
-fresh@0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e"
-
fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
@@ -3015,12 +2914,9 @@ get-stdin@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
-get-stream@^2.2.0:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de"
- dependencies:
- object-assign "^4.0.1"
- pinkie-promise "^2.0.0"
+get-stream@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
getpass@^0.1.1:
version "0.1.7"
@@ -3052,7 +2948,11 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1:
once "^1.3.0"
path-is-absolute "^1.0.0"
-globals@^9.0.0, globals@^9.14.0, globals@^9.18.0:
+globals@^10.0.0:
+ version "10.2.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-10.2.0.tgz#69490789091fcaa7f7d512c668c8eb73894a4ef2"
+
+globals@^9.14.0, globals@^9.18.0:
version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
@@ -3086,8 +2986,8 @@ globule@^1.0.0:
minimatch "~3.0.2"
gonzales-pe@^4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.0.3.tgz#36148e18e267184fbfdc929af28f29ad9fbf9746"
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.2.2.tgz#f50a8c17842f13a9007909b7cb32188266e4d74c"
dependencies:
minimist "1.1.x"
@@ -3110,8 +3010,8 @@ handle-thing@^1.2.5:
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4"
handlebars@^4.0.3:
- version "4.0.10"
- resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f"
+ version "4.0.11"
+ resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc"
dependencies:
async "^1.4.0"
optimist "^0.6.1"
@@ -3123,6 +3023,10 @@ har-schema@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
+har-schema@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
+
har-validator@~4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
@@ -3130,6 +3034,13 @@ har-validator@~4.2.1:
ajv "^4.9.1"
har-schema "^1.0.5"
+har-validator@~5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
+ dependencies:
+ ajv "^5.1.0"
+ har-schema "^2.0.0"
+
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
@@ -3160,6 +3071,13 @@ hash-base@^2.0.0:
dependencies:
inherits "^2.0.1"
+hash-base@^3.0.0:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918"
+ dependencies:
+ inherits "^2.0.1"
+ safe-buffer "^5.0.1"
+
hash.js@^1.0.0, hash.js@^1.0.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846"
@@ -3167,7 +3085,7 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3"
minimalistic-assert "^1.0.0"
-hawk@~3.1.3:
+hawk@3.1.3, hawk@~3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
dependencies:
@@ -3176,6 +3094,15 @@ hawk@~3.1.3:
hoek "2.x.x"
sntp "1.x.x"
+hawk@~6.0.2:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
+ dependencies:
+ boom "4.x.x"
+ cryptiles "3.x.x"
+ hoek "4.x.x"
+ sntp "2.x.x"
+
history@^4.7.2:
version "4.7.2"
resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b"
@@ -3198,6 +3125,10 @@ hoek@2.x.x:
version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
+hoek@4.x.x:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
+
hoist-non-react-statics@^2.2.1, hoist-non-react-statics@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
@@ -3227,8 +3158,8 @@ html-comment-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e"
html-encoding-sniffer@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz#79bf7a785ea495fe66165e734153f363ff5437da"
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
dependencies:
whatwg-encoding "^1.0.1"
@@ -3260,19 +3191,14 @@ http-errors@1.6.2, http-errors@~1.6.2:
setprototypeof "1.0.3"
statuses ">= 1.3.1 < 2"
-http-errors@~1.6.1:
- version "1.6.1"
- resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.1.tgz#5f8b8ed98aca545656bf572997387f904a722257"
- dependencies:
- depd "1.1.0"
- inherits "2.0.3"
- setprototypeof "1.0.3"
- statuses ">= 1.3.1 < 2"
-
http-link-header@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/http-link-header/-/http-link-header-0.8.0.tgz#a22b41a0c9b1e2d8fac1bf1b697c6bd532d5f5e4"
+http-parser-js@>=0.4.0:
+ version "0.4.9"
+ resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.9.tgz#ea1a04fb64adff0242e9974f297dd4c3cad271e1"
+
http-proxy-middleware@~0.17.4:
version "0.17.4"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833"
@@ -3297,22 +3223,22 @@ http-signature@~1.1.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
+http-signature@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
+ dependencies:
+ assert-plus "^1.0.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
https-browserify@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
-iconv-lite@0.4.13:
- version "0.4.13"
- resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
-
-iconv-lite@0.4.19:
+iconv-lite@0.4.19, iconv-lite@~0.4.13:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
-iconv-lite@~0.4.13:
- version "0.4.18"
- resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2"
-
icss-replace-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
@@ -3328,12 +3254,19 @@ ieee754@^1.1.4:
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
ignore@^3.2.0:
- version "3.3.3"
- resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d"
+ version "3.3.7"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021"
-immutable@^3.8.1:
- version "3.8.1"
- resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2"
+immutable@^3.8.2:
+ version "3.8.2"
+ resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3"
+
+import-local@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/import-local/-/import-local-0.1.1.tgz#b1179572aacdc11c6a91009fb430dbcab5f668a8"
+ dependencies:
+ pkg-dir "^2.0.0"
+ resolve-cwd "^2.0.0"
imurmurhash@^0.1.4:
version "0.1.4"
@@ -3401,8 +3334,8 @@ internal-ip@1.2.0:
meow "^3.3.0"
interpret@^1.0.0:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90"
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0"
intersection-observer@^0.4.0:
version "0.4.2"
@@ -3417,24 +3350,18 @@ intl-messageformat-parser@1.2.0:
resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.2.0.tgz#5906b7f953ab7470e0dc8549097b648b991892ff"
intl-messageformat-parser@^1.2.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.3.0.tgz#c5d26ffb894c7d9c2b9fa444c67f417ab2594268"
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075"
-intl-messageformat@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.0.0.tgz#3d56982583425aee23b76c8b985fb9b0aae5be3c"
- dependencies:
- intl-messageformat-parser "1.2.0"
-
-intl-messageformat@^2.1.0:
+intl-messageformat@^2.0.0, intl-messageformat@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.1.0.tgz#1c51da76f02a3f7b360654cdc51bbc4d3fa6c72c"
dependencies:
intl-messageformat-parser "1.2.0"
-intl-relativeformat@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/intl-relativeformat/-/intl-relativeformat-2.0.0.tgz#d6ba9dc6c625819bc0abdb1d4e238138b7488f26"
+intl-relativeformat@^2.0.0, intl-relativeformat@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz#010f1105802251f40ac47d0e3e1a201348a255df"
dependencies:
intl-messageformat "^2.0.0"
@@ -3456,10 +3383,6 @@ ip@^1.1.0, ip@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
-ipaddr.js@1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.3.0.tgz#1e03a52fdad83a8bbb2b25cbf4998b4cffcd3dec"
-
ipaddr.js@1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0"
@@ -3479,8 +3402,8 @@ is-binary-path@^1.0.0:
binary-extensions "^1.0.0"
is-buffer@^1.0.2, is-buffer@^1.1.5:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
is-builtin-module@^1.0.0:
version "1.0.0"
@@ -3557,8 +3480,8 @@ is-glob@^3.1.0:
is-extglob "^2.1.0"
is-my-json-valid@^2.10.0:
- version "2.16.0"
- resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693"
+ version "2.16.1"
+ resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11"
dependencies:
generate-function "^2.0.0"
generate-object-property "^1.1.0"
@@ -3621,7 +3544,7 @@ is-property@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
-is-regex@^1.0.3, is-regex@^1.0.4:
+is-regex@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
dependencies:
@@ -3701,17 +3624,17 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
istanbul-api@^1.1.1:
- version "1.1.14"
- resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.14.tgz#25bc5701f7c680c0ffff913de46e3619a3a6e680"
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.2.1.tgz#0c60a0515eb11c7d65c6b50bba2c6e999acd8620"
dependencies:
async "^2.1.4"
fileset "^2.0.2"
istanbul-lib-coverage "^1.1.1"
- istanbul-lib-hook "^1.0.7"
- istanbul-lib-instrument "^1.8.0"
- istanbul-lib-report "^1.1.1"
- istanbul-lib-source-maps "^1.2.1"
- istanbul-reports "^1.1.2"
+ istanbul-lib-hook "^1.1.0"
+ istanbul-lib-instrument "^1.9.1"
+ istanbul-lib-report "^1.1.2"
+ istanbul-lib-source-maps "^1.2.2"
+ istanbul-reports "^1.1.3"
js-yaml "^3.7.0"
mkdirp "^0.5.1"
once "^1.4.0"
@@ -3720,15 +3643,15 @@ istanbul-lib-coverage@^1.0.1, istanbul-lib-coverage@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da"
-istanbul-lib-hook@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc"
+istanbul-lib-hook@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b"
dependencies:
append-transform "^0.4.0"
-istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.8.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.8.0.tgz#66f6c9421cc9ec4704f76f2db084ba9078a2b532"
+istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.5, istanbul-lib-instrument@^1.9.1:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e"
dependencies:
babel-generator "^6.18.0"
babel-template "^6.16.0"
@@ -3738,28 +3661,28 @@ istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.5, istanbul-lib-ins
istanbul-lib-coverage "^1.1.1"
semver "^5.3.0"
-istanbul-lib-report@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9"
+istanbul-lib-report@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425"
dependencies:
istanbul-lib-coverage "^1.1.1"
mkdirp "^0.5.1"
path-parse "^1.0.5"
supports-color "^3.1.2"
-istanbul-lib-source-maps@^1.1.0, istanbul-lib-source-maps@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c"
+istanbul-lib-source-maps@^1.1.0, istanbul-lib-source-maps@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c"
dependencies:
- debug "^2.6.3"
+ debug "^3.1.0"
istanbul-lib-coverage "^1.1.1"
mkdirp "^0.5.1"
rimraf "^2.6.1"
source-map "^0.5.3"
-istanbul-reports@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.2.tgz#0fb2e3f6aa9922bd3ce45d05d8ab4d5e8e07bd4f"
+istanbul-reports@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10"
dependencies:
handlebars "^4.0.3"
@@ -3993,8 +3916,8 @@ jest@^21.2.1:
jest-cli "^21.2.1"
js-base64@^2.1.8, js-base64@^2.1.9:
- version "2.1.9"
- resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce"
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.3.2.tgz#a79a923666372b580f8e27f51845c6f7e8fbfbaf"
js-string-escape@1.0.1:
version "1.0.1"
@@ -4004,14 +3927,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
-js-yaml@^3.4.3, js-yaml@^3.5.1:
- version "3.9.0"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.0.tgz#4ffbbf25c2ac963b8299dc74da7e3740de1c18ce"
- dependencies:
- argparse "^1.0.7"
- esprima "^4.0.0"
-
-js-yaml@^3.7.0, js-yaml@^3.9.0:
+js-yaml@^3.4.3, js-yaml@^3.5.1, js-yaml@^3.7.0, js-yaml@^3.9.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
dependencies:
@@ -4062,8 +3978,8 @@ jsesc@~0.5.0:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
json-loader@^0.5.4:
- version "0.5.4"
- resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.4.tgz#8baa1365a632f58a3c46d20175fc6002c96e37de"
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"
json-schema-traverse@^0.3.0:
version "0.3.1"
@@ -4106,13 +4022,13 @@ jsonpointer@^4.0.0:
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
jsprim@^1.2.2:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918"
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
dependencies:
assert-plus "1.0.0"
- extsprintf "1.0.2"
+ extsprintf "1.3.0"
json-schema "0.2.3"
- verror "1.3.6"
+ verror "1.10.0"
jsx-ast-utils@^1.0.0, jsx-ast-utils@^1.3.4:
version "1.4.1"
@@ -4328,13 +4244,13 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
-"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1, lodash@~4.17.4:
+"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
loglevel@^1.4.1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.4.1.tgz#95b383f91a3c2756fd4ab093667e4309161f2bcd"
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.5.1.tgz#189078c94ab9053ee215a0acdbf24244ea0f6502"
longest@^1.0.1:
version "1.0.1"
@@ -4365,10 +4281,10 @@ macaddress@^0.2.8:
resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12"
make-dir@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.0.0.tgz#97a011751e91dd87cfadef58832ebb04936de978"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51"
dependencies:
- pify "^2.3.0"
+ pify "^3.0.0"
makeerror@1.0.x:
version "1.0.11"
@@ -4393,8 +4309,8 @@ math-expression-evaluator@^1.2.14:
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"
mathjs@^3.11.5:
- version "3.14.2"
- resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-3.14.2.tgz#bb79b7dc878b7f586ce408ab067a9a42db2e7a2d"
+ version "3.16.5"
+ resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-3.16.5.tgz#d75a5265435d2824b067b37a478771deebf6aacc"
dependencies:
complex.js "2.0.4"
decimal.js "7.2.3"
@@ -4404,6 +4320,13 @@ mathjs@^3.11.5:
tiny-emitter "2.0.0"
typed-function "0.10.5"
+md5.js@^1.3.4:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
+ dependencies:
+ hash-base "^3.0.0"
+ inherits "^2.0.1"
+
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -4467,48 +4390,30 @@ micromatch@^2.1.5, micromatch@^2.3.11:
regex-cache "^0.4.2"
miller-rabin@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.0.tgz#4a62fb1d42933c05583982f4c716f6fb9e6c6d3d"
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
dependencies:
bn.js "^4.0.0"
brorand "^1.0.1"
-"mime-db@>= 1.27.0 < 2":
- version "1.29.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.29.0.tgz#48d26d235589651704ac5916ca06001914266878"
-
-mime-db@~1.27.0:
- version "1.27.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1"
+"mime-db@>= 1.30.0 < 2":
+ version "1.31.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.31.0.tgz#a49cd8f3ebf3ed1a482b60561d9105ad40ca74cb"
mime-db@~1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
-mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.7:
- version "2.1.15"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
- dependencies:
- mime-db "~1.27.0"
-
-mime-types@~2.1.16:
+mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7:
version "2.1.17"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
dependencies:
mime-db "~1.30.0"
-mime@1.3.4:
- version "1.3.4"
- resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
-
-mime@1.4.1:
+mime@1.4.1, mime@^1.3.4:
version "1.4.1"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
-mime@^1.3.4:
- version "1.3.6"
- resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0"
-
mimic-fn@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
@@ -4580,8 +4485,8 @@ mute-stream@0.0.5:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
nan@^2.0.0, nan@^2.3.0, nan@^2.3.2:
- version "2.6.2"
- resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45"
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46"
natural-compare@^1.4.0:
version "1.4.0"
@@ -4600,8 +4505,8 @@ negotiator@0.6.1:
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
node-fetch@^1.0.1:
- version "1.7.1"
- resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.1.tgz#899cb3d0a3c92f952c47f1b876f4c8aeabd400d5"
+ version "1.7.3"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
dependencies:
encoding "^0.1.11"
is-stream "^1.0.1"
@@ -4670,14 +4575,15 @@ node-notifier@^5.0.2:
which "^1.2.12"
node-pre-gyp@^0.6.36, node-pre-gyp@^0.6.4:
- version "0.6.36"
- resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786"
+ version "0.6.38"
+ resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.38.tgz#e92a20f83416415bb4086f6d1fb78b3da73d113d"
dependencies:
+ hawk "3.1.3"
mkdirp "^0.5.1"
nopt "^4.0.1"
npmlog "^4.0.2"
rc "^1.1.7"
- request "^2.81.0"
+ request "2.81.0"
rimraf "^2.6.1"
semver "^5.3.0"
tar "^2.2.1"
@@ -4706,7 +4612,7 @@ node-sass@^4.5.2:
sass-graph "^2.1.1"
stdout-stream "^1.4.0"
-node-zopfli@^2.0.0:
+node-zopfli@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/node-zopfli/-/node-zopfli-2.0.2.tgz#a7a473ae92aaea85d4c68d45bbf2c944c46116b8"
dependencies:
@@ -4744,7 +4650,7 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
-normalize-path@^2.0.1:
+normalize-path@^2.0.0, normalize-path@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
dependencies:
@@ -4796,7 +4702,7 @@ number-is-nan@^1.0.0:
version "1.4.3"
resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c"
-oauth-sign@~0.8.1:
+oauth-sign@~0.8.1, oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
@@ -4940,10 +4846,10 @@ os-locale@^1.4.0:
lcid "^1.0.0"
os-locale@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.0.0.tgz#15918ded510522b81ee7ae5a309d54f639fc39a4"
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2"
dependencies:
- execa "^0.5.0"
+ execa "^0.7.0"
lcid "^1.0.0"
mem "^1.1.0"
@@ -4977,8 +4883,8 @@ p-locate@^2.0.0:
p-limit "^1.1.0"
p-map@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.1.1.tgz#05f5e4ae97a068371bc2a5cc86bfbdbc19c4ae7a"
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
packet-reader@0.3.1:
version "0.3.1"
@@ -5027,6 +4933,12 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"
+parse-json@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-3.0.0.tgz#fa6f47b18e23826ead32f263e744d0e1e847fb13"
+ dependencies:
+ error-ex "^1.3.1"
+
parse5@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94"
@@ -5037,10 +4949,6 @@ parse5@^3.0.1:
dependencies:
"@types/node" "^6.0.46"
-parseurl@~1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56"
-
parseurl@~1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"
@@ -5104,8 +5012,8 @@ path-type@^2.0.0:
pify "^2.0.0"
pbkdf2@^3.0.3:
- version "3.0.12"
- resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.12.tgz#be36785c5067ea48d806ff923288c5f750b6b8a2"
+ version "3.0.14"
+ resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade"
dependencies:
create-hash "^1.1.2"
create-hmac "^1.1.4"
@@ -5133,10 +5041,9 @@ pg-pool@1.*:
object-assign "4.1.0"
pg-types@1.*:
- version "1.12.0"
- resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-1.12.0.tgz#8ad3b7b897e3fd463e62de241ad5fc640b4a66f0"
+ version "1.12.1"
+ resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-1.12.1.tgz#d64087e3903b58ffaad279e7595c52208a14c3d2"
dependencies:
- ap "~0.2.0"
postgres-array "~1.0.0"
postgres-bytea "~1.0.0"
postgres-date "~1.0.0"
@@ -5254,11 +5161,11 @@ postcss-custom-media@^6.0.0:
postcss "^6.0.1"
postcss-custom-properties@^6.1.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-6.1.0.tgz#9caf1151ac41b1e9e64d3a2ff9ece996ca18977d"
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-6.2.0.tgz#5d929a7f06e9b84e0f11334194c0ba9a30acfbe9"
dependencies:
balanced-match "^1.0.0"
- postcss "^6.0.3"
+ postcss "^6.0.13"
postcss-custom-selectors@^4.0.1:
version "4.0.1"
@@ -5321,12 +5228,12 @@ postcss-import@^10.0.0:
read-cache "^1.0.0"
resolve "^1.1.7"
-postcss-js@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-1.0.0.tgz#ccee5aa3b1970dd457008e79438165f66919ba30"
+postcss-js@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-1.0.1.tgz#ffaf29226e399ea74b5dce02cab1729d7addbc7b"
dependencies:
camelcase-css "^1.0.1"
- postcss "^6.0.1"
+ postcss "^6.0.11"
postcss-load-config@^1.2.0:
version "1.2.0"
@@ -5351,12 +5258,12 @@ postcss-load-plugins@^2.3.0:
cosmiconfig "^2.1.1"
object-assign "^4.1.0"
-postcss-loader@^2.0.6:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.0.6.tgz#8c7e0055a3df1889abc6bad52dd45b2f41bbc6fc"
+postcss-loader@^2.0.8:
+ version "2.0.8"
+ resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.0.8.tgz#8c67ddb029407dfafe684a406cfc16bad2ce0814"
dependencies:
loader-utils "^1.1.0"
- postcss "^6.0.2"
+ postcss "^6.0.0"
postcss-load-config "^1.2.0"
schema-utils "^0.3.0"
@@ -5428,13 +5335,13 @@ postcss-minify-selectors@^2.0.4:
postcss-selector-parser "^2.0.0"
postcss-mixins@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/postcss-mixins/-/postcss-mixins-6.0.1.tgz#f5c9726259a6103733b43daa6a8b67dd0ed7aa47"
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/postcss-mixins/-/postcss-mixins-6.2.0.tgz#fa9d2c2166b2ae7745956c727ab9dd2de4b96a40"
dependencies:
globby "^6.1.0"
- postcss "^6.0.3"
- postcss-js "^1.0.0"
- postcss-simple-vars "^4.0.0"
+ postcss "^6.0.13"
+ postcss-js "^1.0.1"
+ postcss-simple-vars "^4.1.0"
sugarss "^1.0.0"
postcss-modules-extract-imports@^1.0.0:
@@ -5465,16 +5372,17 @@ postcss-modules-values@^1.1.0:
postcss "^6.0.1"
postcss-nested@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-2.0.2.tgz#f38fad547f5c3747160aec3bb34745819252974a"
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-2.1.2.tgz#04057281f9631fef684857fb0119bae04ede03c6"
dependencies:
- postcss "^6.0.1"
+ postcss "^6.0.9"
+ postcss-selector-parser "^2.2.3"
postcss-nesting@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-4.0.1.tgz#8fc2ce40cbfcfab7ee24e7b68fb6ebe84b641469"
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-4.2.1.tgz#0483bce338b3f0828ced90ff530b29b98b00300d"
dependencies:
- postcss "^6.0.1"
+ postcss "^6.0.11"
postcss-normalize-charset@^1.1.0:
version "1.1.1"
@@ -5570,7 +5478,7 @@ postcss-selector-not@^3.0.1:
balanced-match "^0.4.2"
postcss "^6.0.1"
-postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2:
+postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2, postcss-selector-parser@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90"
dependencies:
@@ -5578,11 +5486,11 @@ postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2:
indexes-of "^1.0.1"
uniq "^1.0.1"
-postcss-simple-vars@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/postcss-simple-vars/-/postcss-simple-vars-4.0.0.tgz#d49e082897d9a4824f2268fa91d969d943e2ea76"
+postcss-simple-vars@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/postcss-simple-vars/-/postcss-simple-vars-4.1.0.tgz#043248cfef8d3f51b3486a28c09f8375dbf1b2f9"
dependencies:
- postcss "^6.0.1"
+ postcss "^6.0.9"
postcss-smart-import@^0.7.5:
version "0.7.5"
@@ -5630,28 +5538,20 @@ postcss-zindex@^2.0.1:
uniqs "^2.0.0"
postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16, postcss@^5.2.6:
- version "5.2.17"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.17.tgz#cf4f597b864d65c8a492b2eabe9d706c879c388b"
+ version "5.2.18"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5"
dependencies:
chalk "^1.1.3"
js-base64 "^2.1.9"
source-map "^0.5.6"
supports-color "^3.2.3"
-postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.2, postcss@^6.0.3, postcss@^6.0.6:
- version "6.0.6"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.6.tgz#bba4d58e884fc78c840d1539e10eddaabb8f73bd"
- dependencies:
- chalk "^2.0.1"
- source-map "^0.5.6"
- supports-color "^4.1.0"
-
-postcss@^6.0.11:
- version "6.0.12"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.12.tgz#6b0155089d2d212f7bd6a0cecd4c58c007403535"
+postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.11, postcss@^6.0.13, postcss@^6.0.3, postcss@^6.0.6, postcss@^6.0.9:
+ version "6.0.13"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.13.tgz#b9ecab4ee00c89db3ec931145bd9590bbf3f125f"
dependencies:
chalk "^2.1.0"
- source-map "^0.5.7"
+ source-map "^0.6.1"
supports-color "^4.4.0"
postgres-array@~1.0.0:
@@ -5667,8 +5567,8 @@ postgres-date@~1.0.0:
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.3.tgz#e2d89702efdb258ff9d9cee0fe91bd06975257a8"
postgres-interval@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.1.0.tgz#1031e7bac34564132862adc9eb6c6d2f3aa75bb4"
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.1.1.tgz#acdb0f897b4b1c6e496d9d4e0a853e1c428f06f0"
dependencies:
xtend "^4.0.0"
@@ -5717,8 +5617,8 @@ pretty-format@^21.2.1:
ansi-styles "^3.2.0"
private@^0.1.6, private@^0.1.7:
- version "0.1.7"
- resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
process-nextick-args@~1.0.6:
version "1.0.7"
@@ -5750,7 +5650,7 @@ prop-types-extra@^1.0.1:
dependencies:
warning "^3.0.0"
-prop-types@^15.5.10, prop-types@^15.6.0:
+prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0:
version "15.6.0"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
dependencies:
@@ -5758,20 +5658,6 @@ prop-types@^15.5.10, prop-types@^15.6.0:
loose-envify "^1.3.1"
object-assign "^4.1.1"
-prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8:
- version "15.5.10"
- resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
- dependencies:
- fbjs "^0.8.9"
- loose-envify "^1.3.1"
-
-proxy-addr@~1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.4.tgz#27e545f6960a44a627d9b44467e35c1b6b4ce2f3"
- dependencies:
- forwarded "~0.1.0"
- ipaddr.js "1.3.0"
-
proxy-addr@~2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
@@ -5810,17 +5696,17 @@ punycode@^2.1.0:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d"
q@^1.1.2:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1"
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
-qs@6.4.0, qs@~6.4.0:
- version "6.4.0"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
-
-qs@6.5.1:
+qs@6.5.1, qs@~6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
+qs@~6.4.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
+
query-string@^4.1.0:
version "4.3.4"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb"
@@ -5848,13 +5734,7 @@ quote@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/quote/-/quote-0.4.0.tgz#10839217f6c1362b89194044d29b233fd7f32f01"
-raf@^3.1.0:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/raf/-/raf-3.3.2.tgz#0c13be0b5b49b46f76d6669248d527cf2b02fe27"
- dependencies:
- performance-now "^2.1.0"
-
-raf@^3.3.2, raf@^3.4.0:
+raf@^3.1.0, raf@^3.3.2, raf@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575"
dependencies:
@@ -5902,8 +5782,8 @@ raw-body@2.3.2:
unpipe "1.0.0"
rc@^1.1.7:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95"
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077"
dependencies:
deep-extend "~0.4.0"
ini "~1.3.0"
@@ -5920,12 +5800,12 @@ react-dom@^16.0.0:
prop-types "^15.6.0"
react-event-listener@^0.5.0:
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.5.0.tgz#d82105135573e187e3d900d18150a5882304b8d1"
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.5.1.tgz#ba36076e47bc37c5a67ff5ccd4a9ff0f15621040"
dependencies:
babel-runtime "^6.26.0"
- fbjs "^0.8.14"
- prop-types "^15.5.10"
+ fbjs "^0.8.16"
+ prop-types "^15.6.0"
warning "^3.0.0"
react-hotkeys@^0.10.0:
@@ -5941,9 +5821,9 @@ react-immutable-proptypes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz#023d6f39bb15c97c071e9e60d00d136eac5fa0b4"
-react-immutable-pure-component@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/react-immutable-pure-component/-/react-immutable-pure-component-1.0.1.tgz#c36b11546822a17fbc115c43278fc1698147687f"
+react-immutable-pure-component@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/react-immutable-pure-component/-/react-immutable-pure-component-1.1.1.tgz#0ff69c6d4eaecd886db16805f3bbc1d2a2c654d8"
react-intl-translations-manager@^5.0.0:
version "5.0.1"
@@ -5963,34 +5843,34 @@ react-intl@^2.4.0:
intl-relativeformat "^2.0.0"
invariant "^2.1.1"
-react-motion@^0.5.0:
- version "0.5.1"
- resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.1.tgz#b90631408175ab1668e173caccd66d41a44f4592"
+react-motion@^0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316"
dependencies:
performance-now "^0.2.0"
prop-types "^15.5.8"
raf "^3.1.0"
-react-notification@^6.7.1:
- version "6.8.0"
- resolved "https://registry.yarnpkg.com/react-notification/-/react-notification-6.8.0.tgz#9cb7aa06c8e5085b4c0dc2e8d9aa1da1fbc61d93"
+react-notification@^6.8.2:
+ version "6.8.2"
+ resolved "https://registry.yarnpkg.com/react-notification/-/react-notification-6.8.2.tgz#5d9910cc2993bd51a234d3809e94a98dc490cfb0"
dependencies:
prop-types "^15.5.10"
-react-overlays@^0.8.1:
- version "0.8.1"
- resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.8.1.tgz#26e480003c2fd6f581a4a66c0c86cb3dff17e626"
+react-overlays@^0.8.3:
+ version "0.8.3"
+ resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.8.3.tgz#fad65eea5b24301cca192a169f5dddb0b20d3ac5"
dependencies:
classnames "^2.2.5"
dom-helpers "^3.2.1"
prop-types "^15.5.10"
prop-types-extra "^1.0.1"
- react-transition-group "^2.0.0-beta.0"
+ react-transition-group "^2.2.0"
warning "^3.0.0"
-react-redux-loading-bar@^2.9.2:
- version "2.9.2"
- resolved "https://registry.yarnpkg.com/react-redux-loading-bar/-/react-redux-loading-bar-2.9.2.tgz#f0e604ee35af5ecb25addb10bf24ca3d478c95a8"
+react-redux-loading-bar@^2.9.3:
+ version "2.9.3"
+ resolved "https://registry.yarnpkg.com/react-redux-loading-bar/-/react-redux-loading-bar-2.9.3.tgz#65865dddcbf597169e787edec15eec7ebfb84149"
dependencies:
prop-types "^15.5.6"
@@ -6016,11 +5896,11 @@ react-router-dom@^4.1.1:
react-router "^4.2.0"
warning "^3.0.0"
-react-router-scroll@Gargron/react-router-scroll#build:
- version "0.4.3"
- resolved "https://codeload.github.com/Gargron/react-router-scroll/tar.gz/17a028e3c2db0e488c6dca6ab1639783fb54480a"
+react-router-scroll-4@^1.0.0-beta.1:
+ version "1.0.0-beta.1"
+ resolved "https://registry.yarnpkg.com/react-router-scroll-4/-/react-router-scroll-4-1.0.0-beta.1.tgz#b1838c6e67b9fe64db33176958e88836e10bc4ce"
dependencies:
- prop-types "^15.6.0"
+ babel-eslint "^8.0.1"
scroll-behavior "^0.9.1"
warning "^3.0.0"
@@ -6065,7 +5945,7 @@ react-swipeable-views@^0.12.3:
react-swipeable-views-utils "^0.12.8"
warning "^3.0.0"
-react-test-renderer@^16.0.0:
+react-test-renderer@^16.0.0, react-test-renderer@^16.0.0-0:
version "16.0.0"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.0.0.tgz#9fe7b8308f2f71f29fc356d4102086f131c9cb15"
dependencies:
@@ -6084,9 +5964,9 @@ react-toggle@^4.0.1:
dependencies:
classnames "^2.2.5"
-react-transition-group@^2.0.0-beta.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.0.tgz#793bf8cb15bfe91b3101b24bce1c1d2891659575"
+react-transition-group@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10"
dependencies:
chain-function "^1.0.0"
classnames "^2.2.5"
@@ -6230,35 +6110,30 @@ redux@^3.7.1:
symbol-observable "^1.0.3"
regenerate@^1.2.1:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
-
-regenerator-runtime@^0.10.0:
- version "0.10.5"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f"
regenerator-runtime@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1"
-regenerator-transform@0.9.11:
- version "0.9.11"
- resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283"
+regenerator-transform@^0.10.0:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"
dependencies:
babel-runtime "^6.18.0"
babel-types "^6.19.0"
private "^0.1.6"
regex-cache@^0.4.2:
- version "0.4.3"
- resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145"
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd"
dependencies:
is-equal-shallow "^0.1.3"
- is-primitive "^2.0.0"
regex-parser@^2.2.1:
- version "2.2.7"
- resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.7.tgz#bd090e09181849acc45457e765f7be2a63f50ef1"
+ version "2.2.8"
+ resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.8.tgz#da4c0cda5a828559094168930f455f532b6ffbac"
regexpu-core@^1.0.0:
version "1.0.0"
@@ -6287,8 +6162,8 @@ regjsparser@^0.1.4:
jsesc "~0.5.0"
remove-trailing-separator@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz#69b062d978727ad14dc6b56ba4ab772fd8d70511"
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
repeat-element@^1.1.2:
version "1.1.2"
@@ -6304,7 +6179,34 @@ repeating@^2.0.0:
dependencies:
is-finite "^1.0.0"
-request@2, request@^2.79.0, request@^2.81.0:
+request@2, request@^2.79.0:
+ version "2.83.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
+ dependencies:
+ aws-sign2 "~0.7.0"
+ aws4 "^1.6.0"
+ caseless "~0.12.0"
+ combined-stream "~1.0.5"
+ extend "~3.0.1"
+ forever-agent "~0.6.1"
+ form-data "~2.3.1"
+ har-validator "~5.0.3"
+ hawk "~6.0.2"
+ http-signature "~1.2.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.17"
+ oauth-sign "~0.8.2"
+ performance-now "^2.1.0"
+ qs "~6.5.1"
+ safe-buffer "^5.1.1"
+ stringstream "~0.0.5"
+ tough-cookie "~2.3.3"
+ tunnel-agent "^0.6.0"
+ uuid "^3.1.0"
+
+request@2.81.0:
version "2.81.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
dependencies:
@@ -6339,10 +6241,14 @@ require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
-require-from-string@^1.1.0, require-from-string@^1.2.1:
+require-from-string@^1.1.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418"
+require-from-string@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.1.tgz#c545233e9d7da6616e9d59adfb39fc9f588676ff"
+
require-main-filename@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
@@ -6362,17 +6268,27 @@ reselect@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147"
+resolve-cwd@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
+ dependencies:
+ resolve-from "^3.0.0"
+
resolve-from@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
+resolve-from@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
+
resolve-pathname@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879"
-resolve-url-loader@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-2.1.0.tgz#27c95cc16a4353923fdbdc2dbaf5eef22232c477"
+resolve-url-loader@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-2.2.0.tgz#9662feaa11debf7cf8e3feb91dae9544aa7dee88"
dependencies:
adjust-sourcemap-loader "^1.1.0"
camelcase "^4.0.0"
@@ -6392,15 +6308,9 @@ resolve@1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
-resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.3:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
- dependencies:
- path-parse "^1.0.5"
-
-resolve@^1.2.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86"
+resolve@^1.1.6, resolve@^1.1.7, resolve@^1.2.0, resolve@^1.3.3:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
dependencies:
path-parse "^1.0.5"
@@ -6436,13 +6346,7 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
-rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1:
- version "2.6.1"
- resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
- dependencies:
- glob "^7.0.5"
-
-rimraf@^2.6.1:
+rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
@@ -6456,8 +6360,8 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
inherits "^2.0.1"
rst-selector-parser@^2.2.2:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.2.tgz#9927b619bd5af8dc23a76c64caef04edf90d2c65"
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91"
dependencies:
lodash.flattendeep "^4.4.0"
nearley "^2.7.10"
@@ -6472,7 +6376,7 @@ rx-lite@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
-safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@@ -6524,11 +6428,11 @@ schema-utils@^0.3.0:
ajv "^5.0.0"
scroll-behavior@^0.9.1:
- version "0.9.3"
- resolved "https://registry.yarnpkg.com/scroll-behavior/-/scroll-behavior-0.9.3.tgz#e48bcc8af364f3f07176e8dbca3968bd5e71557b"
+ version "0.9.4"
+ resolved "https://registry.yarnpkg.com/scroll-behavior/-/scroll-behavior-0.9.4.tgz#73b4a0eae3e59c0b8f3b6fc1ff78f054a513e79c"
dependencies:
- dom-helpers "^3.0.0"
- invariant "^2.2.1"
+ dom-helpers "^3.2.1"
+ invariant "^2.2.2"
scss-tokenizer@^0.2.3:
version "0.2.3"
@@ -6546,36 +6450,22 @@ select-hose@^2.0.0:
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
selfsigned@^1.9.1:
- version "1.9.1"
- resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.9.1.tgz#cdda4492d70d486570f87c65546023558e1dfa5a"
+ version "1.10.1"
+ resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.1.tgz#bf8cb7b83256c4551e31347c6311778db99eec52"
dependencies:
node-forge "0.6.33"
-"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@~5.3.0:
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
+"semver@2 || 3 || 4 || 5", semver@^5.3.0:
+ version "5.4.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
semver@4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7"
-send@0.15.3:
- version "0.15.3"
- resolved "https://registry.yarnpkg.com/send/-/send-0.15.3.tgz#5013f9f99023df50d1bd9892c19e3defd1d53309"
- dependencies:
- debug "2.6.7"
- depd "~1.1.0"
- destroy "~1.0.4"
- encodeurl "~1.0.1"
- escape-html "~1.0.3"
- etag "~1.8.0"
- fresh "0.5.0"
- http-errors "~1.6.1"
- mime "1.3.4"
- ms "2.0.0"
- on-finished "~2.3.0"
- range-parser "~1.2.0"
- statuses "~1.3.1"
+semver@~5.3.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
send@0.16.1:
version "0.16.1"
@@ -6596,25 +6486,16 @@ send@0.16.1:
statuses "~1.3.1"
serve-index@^1.7.2:
- version "1.9.0"
- resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.0.tgz#d2b280fc560d616ee81b48bf0fa82abed2485ce7"
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
dependencies:
- accepts "~1.3.3"
+ accepts "~1.3.4"
batch "0.6.1"
- debug "2.6.8"
+ debug "2.6.9"
escape-html "~1.0.3"
- http-errors "~1.6.1"
- mime-types "~2.1.15"
- parseurl "~1.3.1"
-
-serve-static@1.12.3:
- version "1.12.3"
- resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.3.tgz#9f4ba19e2f3030c547f8af99107838ec38d5b1e2"
- dependencies:
- encodeurl "~1.0.1"
- escape-html "~1.0.3"
- parseurl "~1.3.1"
- send "0.15.3"
+ http-errors "~1.6.2"
+ mime-types "~2.1.17"
+ parseurl "~1.3.2"
serve-static@1.13.1:
version "1.13.1"
@@ -6646,10 +6527,11 @@ setprototypeof@1.1.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
sha.js@^2.4.0, sha.js@^2.4.8:
- version "2.4.8"
- resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.8.tgz#37068c2c476b6baf402d14a49c67f597921f634f"
+ version "2.4.9"
+ resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d"
dependencies:
inherits "^2.0.1"
+ safe-buffer "^5.0.1"
shallow-clone@^0.1.2:
version "0.1.2"
@@ -6700,6 +6582,12 @@ sntp@1.x.x:
dependencies:
hoek "2.x.x"
+sntp@2.x.x:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
+ dependencies:
+ hoek "4.x.x"
+
sockjs-client@1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12"
@@ -6728,10 +6616,6 @@ source-list-map@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
-source-list-map@~0.1.7:
- version "0.1.8"
- resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106"
-
source-map-resolve@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761"
@@ -6763,19 +6647,13 @@ source-map@^0.4.2, source-map@^0.4.4:
dependencies:
amdefine ">=0.0.4"
-source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3:
- version "0.5.6"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
-
-source-map@^0.5.7:
+source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3, source-map@~0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
-source-map@~0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d"
- dependencies:
- amdefine ">=0.0.4"
+source-map@^0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
spdx-correct@~1.0.0:
version "1.0.2"
@@ -6815,8 +6693,8 @@ spdy@^3.4.1:
spdy-transport "^2.0.18"
split@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/split/-/split-1.0.0.tgz#c4395ce683abcd254bc28fe1dabb6e5c27dcffae"
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
dependencies:
through "2"
@@ -6838,7 +6716,11 @@ sshpk@^1.7.0:
jsbn "~0.1.0"
tweetnacl "~0.14.0"
-"statuses@>= 1.3.1 < 2", statuses@~1.3.1:
+"statuses@>= 1.3.1 < 2":
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
+
+statuses@~1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
@@ -6885,8 +6767,8 @@ string-width@^1.0.1, string-width@^1.0.2:
strip-ansi "^3.0.0"
string-width@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.0.tgz#030664561fc146c9423ec7d978fe2457437fe6d0"
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
dependencies:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
@@ -6901,7 +6783,7 @@ string_decoder@~1.0.3:
dependencies:
safe-buffer "~5.1.0"
-stringstream@~0.0.4:
+stringstream@~0.0.4, stringstream@~0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
@@ -6945,9 +6827,9 @@ strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
-style-loader@^0.18.2:
- version "0.18.2"
- resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.18.2.tgz#cc31459afbcd6d80b7220ee54b291a9fd66ff5eb"
+style-loader@^0.19.0:
+ version "0.19.0"
+ resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.19.0.tgz#7258e788f0fee6a42d710eaf7d6c2412a4c50759"
dependencies:
loader-utils "^1.0.2"
schema-utils "^0.3.0"
@@ -6972,21 +6854,9 @@ supports-color@^3.1.2, supports-color@^3.2.3:
dependencies:
has-flag "^1.0.0"
-supports-color@^4.0.0, supports-color@^4.1.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.0.tgz#ad986dc7eb2315d009b4d77c8169c2231a684037"
- dependencies:
- has-flag "^2.0.0"
-
-supports-color@^4.2.1:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.1.tgz#65a4bb2631e90e02420dba5554c375a4754bb836"
- dependencies:
- has-flag "^2.0.0"
-
-supports-color@^4.4.0:
- version "4.4.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e"
+supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
dependencies:
has-flag "^2.0.0"
@@ -7022,12 +6892,12 @@ table@^3.7.8:
string-width "^2.0.0"
tapable@^0.2.7:
- version "0.2.7"
- resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.7.tgz#e46c0daacbb2b8a98b9b0cea0f4052105817ed5c"
+ version "0.2.8"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22"
tar-pack@^3.4.0:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984"
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f"
dependencies:
debug "^2.2.0"
fstream "^1.0.10"
@@ -7082,9 +6952,13 @@ thunky@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/thunky/-/thunky-0.1.0.tgz#bf30146824e2b6e67b0f2d7a4ac8beb26908684e"
+time-stamp@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357"
+
timers-browserify@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.2.tgz#ab4883cf597dcd50af211349a00fbca56ac86b86"
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.4.tgz#96ca53f4b794a5e7c0e1bd7cc88a372298fa01e6"
dependencies:
setimmediate "^1.0.4"
@@ -7104,13 +6978,17 @@ to-arraybuffer@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
-to-fast-properties@^1.0.1, to-fast-properties@^1.0.3:
+to-fast-properties@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
-tough-cookie@^2.3.2, tough-cookie@~2.3.0:
- version "2.3.2"
- resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
+to-fast-properties@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
+
+tough-cookie@^2.3.2, tough-cookie@~2.3.0, tough-cookie@~2.3.3:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
dependencies:
punycode "^1.4.1"
@@ -7166,8 +7044,8 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
ua-parser-js@^0.7.9:
- version "0.7.13"
- resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.13.tgz#cd9dd2f86493b3f44dbeeef3780fda74c5ee14be"
+ version "0.7.17"
+ resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
uglify-js@^2.6, uglify-js@^2.8.29:
version "2.8.29"
@@ -7265,10 +7143,6 @@ util@0.10.3, util@^0.10.3:
dependencies:
inherits "2.0.1"
-utils-merge@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8"
-
utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
@@ -7296,10 +7170,6 @@ value-equal@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7"
-vary@~1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37"
-
vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
@@ -7308,11 +7178,13 @@ vendors@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22"
-verror@1.3.6:
- version "1.3.6"
- resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c"
+verror@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
dependencies:
- extsprintf "1.0.2"
+ assert-plus "^1.0.0"
+ core-util-is "1.0.2"
+ extsprintf "^1.2.0"
vm-browserify@0.0.4:
version "0.0.4"
@@ -7358,8 +7230,8 @@ webidl-conversions@^3.0.0:
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
webidl-conversions@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.1.tgz#8015a17ab83e7e1b311638486ace81da6ce206a0"
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
webpack-bundle-analyzer@^2.8.3:
version "2.9.0"
@@ -7378,17 +7250,18 @@ webpack-bundle-analyzer@^2.8.3:
ws "^2.3.1"
webpack-dev-middleware@^1.11.0:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.11.0.tgz#09691d0973a30ad1f82ac73a12e2087f0a4754f9"
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz#d34efefb2edda7e1d3b5dbe07289513219651709"
dependencies:
memory-fs "~0.4.1"
mime "^1.3.4"
path-is-absolute "^1.0.0"
range-parser "^1.0.3"
+ time-stamp "^2.0.0"
-webpack-dev-server@^2.6.1:
- version "2.9.1"
- resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.1.tgz#7ac9320b61b00eb65b2109f15c82747fc5b93585"
+webpack-dev-server@^2.9.3:
+ version "2.9.3"
+ resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.9.3.tgz#f0554e88d129e87796a6f74a016b991743ca6f81"
dependencies:
ansi-html "0.0.7"
array-includes "^3.0.3"
@@ -7396,10 +7269,12 @@ webpack-dev-server@^2.6.1:
chokidar "^1.6.0"
compression "^1.5.2"
connect-history-api-fallback "^1.3.0"
+ debug "^3.1.0"
del "^3.0.0"
express "^4.13.3"
html-entities "^1.2.0"
http-proxy-middleware "~0.17.4"
+ import-local "^0.1.1"
internal-ip "1.2.0"
ip "^1.1.5"
loglevel "^1.4.1"
@@ -7428,13 +7303,6 @@ webpack-merge@^4.1.0:
dependencies:
lodash "^4.17.4"
-webpack-sources@^0.1.0:
- version "0.1.5"
- resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750"
- dependencies:
- source-list-map "~0.1.7"
- source-map "~0.5.3"
-
webpack-sources@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.0.1.tgz#c7356436a4d13123be2e2426a05d1dad9cbe65cf"
@@ -7442,9 +7310,9 @@ webpack-sources@^1.0.1:
source-list-map "^2.0.0"
source-map "~0.5.3"
-webpack@^3.4.1:
- version "3.6.0"
- resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.6.0.tgz#a89a929fbee205d35a4fa2cc487be9cbec8898bc"
+webpack@^3.8.1:
+ version "3.8.1"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.8.1.tgz#b16968a81100abe61608b0153c9159ef8bb2bd83"
dependencies:
acorn "^5.0.0"
acorn-dynamic-import "^2.0.0"
@@ -7470,14 +7338,15 @@ webpack@^3.4.1:
yargs "^8.0.2"
websocket-driver@>=0.5.1:
- version "0.6.5"
- resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36"
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb"
dependencies:
+ http-parser-js ">=0.4.0"
websocket-extensions ">=0.1.1"
websocket-extensions@>=0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.1.tgz#76899499c184b6ef754377c2dbb0cd6cb55d29e7"
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.2.tgz#0e18781de629a18308ce1481650f67ffa2693a5d"
websocket.js@^0.1.12:
version "0.1.12"
@@ -7486,10 +7355,10 @@ websocket.js@^0.1.12:
backoff "^2.4.1"
whatwg-encoding@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz#3c6c451a198ee7aec55b1ec61d0920c67801a5f4"
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3"
dependencies:
- iconv-lite "0.4.13"
+ iconv-lite "0.4.19"
whatwg-fetch@>=0.10.0:
version "2.0.3"
@@ -7514,13 +7383,7 @@ which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
-which@1, which@^1.2.9:
- version "1.2.14"
- resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
- dependencies:
- isexe "^2.0.0"
-
-which@^1.2.12:
+which@1, which@^1.2.12, which@^1.2.9:
version "1.3.0"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
dependencies: