diff --git a/package.json b/package.json
index 2f8d5f9f7a..2451f5ffc4 100644
--- a/package.json
+++ b/package.json
@@ -81,6 +81,7 @@
"glob": "^5.0.14",
"glob-to-regexp": "^0.4.1",
"highlight.js": "^9.15.8",
+ "html-entities": "^1.2.1",
"humanize": "^0.0.9",
"is-ip": "^2.0.0",
"isomorphic-fetch": "^2.2.1",
diff --git a/res/css/views/dialogs/_DMInviteDialog.scss b/res/css/views/dialogs/_DMInviteDialog.scss
index 1153ecb0d4..364c796f16 100644
--- a/res/css/views/dialogs/_DMInviteDialog.scss
+++ b/res/css/views/dialogs/_DMInviteDialog.scss
@@ -77,5 +77,9 @@ limitations under the License.
float: right;
line-height: 36px; // Height of the avatar to keep the time vertically aligned
}
+
+ .mx_DMInviteDialog_roomTile_highlight {
+ font-weight: 900;
+ }
}
diff --git a/src/components/views/dialogs/DMInviteDialog.js b/src/components/views/dialogs/DMInviteDialog.js
index ff498e3e75..c5e9c92131 100644
--- a/src/components/views/dialogs/DMInviteDialog.js
+++ b/src/components/views/dialogs/DMInviteDialog.js
@@ -23,23 +23,48 @@ import {makeUserPermalink} from "../../../utils/permalinks/Permalinks";
import DMRoomMap from "../../../utils/DMRoomMap";
import {RoomMember} from "matrix-js-sdk/lib/matrix";
import * as humanize from "humanize";
+import SdkConfig from "../../../SdkConfig";
+import {getHttpUriForMxc} from "matrix-js-sdk/lib/content-repo";
// TODO: [TravisR] Make this generic for all kinds of invites
const INITIAL_ROOMS_SHOWN = 3; // Number of rooms to show at first
const INCREMENT_ROOMS_SHOWN = 5; // Number of rooms to add when 'show more' is clicked
+class DirectoryMember {
+ _userId: string;
+ _displayName: string;
+ _avatarUrl: string;
+
+ constructor(userDirResult: {user_id: string, display_name: string, avatar_url: string}) {
+ this._userId = userDirResult.user_id;
+ this._displayName = userDirResult.display_name;
+ this._avatarUrl = userDirResult.avatar_url;
+ }
+
+ // These next members are to implement the contract expected by DMRoomTile
+ get name(): string {
+ return this._displayName || this._userId;
+ }
+
+ get userId(): string {
+ return this._userId;
+ }
+
+ getMxcAvatarUrl(): string {
+ return this._avatarUrl;
+ }
+}
+
class DMRoomTile extends React.PureComponent {
static propTypes = {
+ // Has properties to match RoomMember: userId (str), name (str), getMxcAvatarUrl(): string
member: PropTypes.object.isRequired,
lastActiveTs: PropTypes.number,
onToggle: PropTypes.func.isRequired,
+ highlightWord: PropTypes.string,
};
- constructor() {
- super();
- }
-
_onClick = (e) => {
// Stop the browser from highlighting text
e.preventDefault();
@@ -48,8 +73,44 @@ class DMRoomTile extends React.PureComponent {
this.props.onToggle(this.props.member.userId);
};
+ _highlightName(str: string) {
+ if (!this.props.highlightWord) return str;
+
+ // We convert things to lowercase for index searching, but pull substrings from
+ // the submitted text to preserve case. Note: we don't need to htmlEntities the
+ // string because React will safely encode the text for us.
+ const lowerStr = str.toLowerCase();
+ const filterStr = this.props.highlightWord.toLowerCase();
+
+ const result = [];
+
+ let i = 0;
+ let ii;
+ while ((ii = lowerStr.indexOf(filterStr, i)) >= 0) {
+ // Push any text we missed (first bit/middle of text)
+ if (ii > i) {
+ // Push any text we aren't highlighting (middle of text match, or beginning of text)
+ result.push({str.substring(i, ii)});
+ }
+
+ i = ii; // copy over ii only if we have a match (to preserve i for end-of-text matching)
+
+ // Highlight the word the user entered
+ const substr = str.substring(i, filterStr.length + i);
+ result.push({substr});
+ i += substr.length;
+ }
+
+ // Push any text we missed (end of text)
+ if (i < (str.length - 1)) {
+ result.push({str.substring(i)});
+ }
+
+ return result;
+ }
+
render() {
- const MemberAvatar = sdk.getComponent("views.avatars.MemberAvatar");
+ const BaseAvatar = sdk.getComponent("views.avatars.BaseAvatar");
let timestamp = null;
if (this.props.lastActiveTs) {
@@ -59,11 +120,22 @@ class DMRoomTile extends React.PureComponent {
timestamp = {humanTs};
}
+ const avatarSize = 36;
+ const avatarUrl = getHttpUriForMxc(
+ MatrixClientPeg.get().getHomeserverUrl(), this.props.member.getMxcAvatarUrl(),
+ avatarSize, avatarSize, "crop");
+
return (
-
- {this.props.member.name}
- {this.props.member.userId}
+
+ {this._highlightName(this.props.member.name)}
+ {this._highlightName(this.props.member.userId)}
{timestamp}
);
@@ -76,6 +148,8 @@ export default class DMInviteDialog extends React.PureComponent {
onFinished: PropTypes.func.isRequired,
};
+ _debounceTimer: number = null;
+
constructor() {
super();
@@ -84,6 +158,9 @@ export default class DMInviteDialog extends React.PureComponent {
filterText: "",
recents: this._buildRecents(),
numRecentsShown: INITIAL_ROOMS_SHOWN,
+ suggestions: this._buildSuggestions(),
+ numSuggestionsShown: INITIAL_ROOMS_SHOWN,
+ serverResultsMixin: [], // { user: DirectoryMember, userId: string }[], like recents and suggestions
};
}
@@ -109,6 +186,64 @@ export default class DMInviteDialog extends React.PureComponent {
return recents;
}
+ _buildSuggestions(): {userId: string, user: RoomMember} {
+ const maxConsideredMembers = 200;
+ const client = MatrixClientPeg.get();
+ const excludedUserIds = [client.getUserId(), SdkConfig.get()['welcomeUserId']];
+ const joinedRooms = client.getRooms()
+ .filter(r => r.getMyMembership() === 'join')
+ .filter(r => r.getJoinedMemberCount() <= maxConsideredMembers);
+
+ // Generates { userId: {member, rooms[]} }
+ const memberRooms = joinedRooms.reduce((members, room) => {
+ const joinedMembers = room.getJoinedMembers().filter(u => !excludedUserIds.includes(u.userId));
+ for (const member of joinedMembers) {
+ if (!members[member.userId]) {
+ members[member.userId] = {
+ member: member,
+ // Track the room size of the 'picked' member so we can use the profile of
+ // the smallest room (likely a DM).
+ pickedMemberRoomSize: room.getJoinedMemberCount(),
+ rooms: [],
+ };
+ }
+
+ members[member.userId].rooms.push(room);
+
+ if (room.getJoinedMemberCount() < members[member.userId].pickedMemberRoomSize) {
+ members[member.userId].member = member;
+ members[member.userId].pickedMemberRoomSize = room.getJoinedMemberCount();
+ }
+ }
+ return members;
+ }, {});
+
+ // Generates { userId: {member, numRooms, score} }
+ const memberScores = Object.values(memberRooms).reduce((scores, entry) => {
+ const numMembersTotal = entry.rooms.reduce((c, r) => c + r.getJoinedMemberCount(), 0);
+ const maxRange = maxConsideredMembers * entry.rooms.length;
+ scores[entry.member.userId] = {
+ member: entry.member,
+ numRooms: entry.rooms.length,
+ score: Math.max(0, Math.pow(1 - (numMembersTotal / maxRange), 5)),
+ };
+ return scores;
+ }, {});
+
+ const members = Object.values(memberScores);
+ members.sort((a, b) => {
+ if (a.score === b.score) {
+ if (a.numRooms === b.numRooms) {
+ return a.member.userId.localeCompare(b.member.userId);
+ }
+
+ return b.numRooms - a.numRooms;
+ }
+ return b.score - a.score;
+ });
+ return members.map(m => ({userId: m.member.userId, user: m.member}));
+ }
+
_startDm = () => {
this.props.onFinished(this.state.targets);
};
@@ -118,13 +253,45 @@ export default class DMInviteDialog extends React.PureComponent {
};
_updateFilter = (e) => {
- this.setState({filterText: e.target.value});
+ const term = e.target.value;
+ this.setState({filterText: term});
+
+ // Debounce server lookups to reduce spam. We don't clear the existing server
+ // results because they might still be vaguely accurate, likewise for races which
+ // could happen here.
+ if (this._debounceTimer) {
+ clearTimeout(this._debounceTimer);
+ }
+ this._debounceTimer = setTimeout(() => {
+ MatrixClientPeg.get().searchUserDirectory({term}).then(r => {
+ if (term !== this.state.filterText) {
+ // Discard the results - we were probably too slow on the server-side to make
+ // these results useful. This is a race we want to avoid because we could overwrite
+ // more accurate results.
+ return;
+ }
+ this.setState({
+ serverResultsMixin: r.results.map(u => ({
+ userId: u.user_id,
+ user: new DirectoryMember(u),
+ })),
+ });
+ }).catch(e => {
+ console.error("Error searching user directory:");
+ console.error(e);
+ this.setState({serverResultsMixin: []}); // clear results because it's moderately fatal
+ });
+ }, 150); // 150ms debounce (human reaction time + some)
};
_showMoreRecents = () => {
this.setState({numRecentsShown: this.state.numRecentsShown + INCREMENT_ROOMS_SHOWN});
};
+ _showMoreSuggestions = () => {
+ this.setState({numSuggestionsShown: this.state.numSuggestionsShown + INCREMENT_ROOMS_SHOWN});
+ };
+
_toggleMember = (userId) => {
const targets = this.state.targets.map(t => t); // cheap clone for mutation
const idx = targets.indexOf(userId);
@@ -133,29 +300,71 @@ export default class DMInviteDialog extends React.PureComponent {
this.setState({targets});
};
- _renderRecents() {
- if (!this.state.recents || this.state.recents.length === 0) return null;
+ _renderSection(kind: "recents"|"suggestions") {
+ let sourceMembers = kind === 'recents' ? this.state.recents : this.state.suggestions;
+ let showNum = kind === 'recents' ? this.state.numRecentsShown : this.state.numSuggestionsShown;
+ const showMoreFn = kind === 'recents' ? this._showMoreRecents.bind(this) : this._showMoreSuggestions.bind(this);
+ const lastActive = (m) => kind === 'recents' ? m.lastActive : null;
+ const sectionName = kind === 'recents' ? _t("Recent Conversations") : _t("Suggestions");
+
+ // Mix in the server results if we have any, but only if we're searching
+ if (this.state.filterText && this.state.serverResultsMixin && kind === 'suggestions') {
+ // only pick out the server results that aren't already covered though
+ const uniqueServerResults = this.state.serverResultsMixin
+ .filter(u => !sourceMembers.some(m => m.userId === u.userId));
+
+ sourceMembers = sourceMembers.concat(uniqueServerResults);
+ }
+
+ // Hide the section if there's nothing to filter by
+ if (!sourceMembers || sourceMembers.length === 0) return null;
+
+ // Do some simple filtering on the input before going much further. If we get no results, say so.
+ if (this.state.filterText) {
+ const filterBy = this.state.filterText.toLowerCase();
+ sourceMembers = sourceMembers
+ .filter(m => m.user.name.toLowerCase().includes(filterBy) || m.userId.toLowerCase().includes(filterBy));
+
+ if (sourceMembers.length === 0) {
+ return (
+
+
{sectionName}
+
{_t("No results")}
+
+ );
+ }
+ }
+
+ // If we're going to hide one member behind 'show more', just use up the space of the button
+ // with the member's tile instead.
+ if (showNum === sourceMembers.length - 1) showNum++;
// .slice() will return an incomplete array but won't error on us if we go too far
- const toRender = this.state.recents.slice(0, this.state.numRecentsShown);
- const hasMore = toRender.length < this.state.recents.length;
+ const toRender = sourceMembers.slice(0, showNum);
+ const hasMore = toRender.length < sourceMembers.length;
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
let showMore = null;
if (hasMore) {
showMore = (
-
+
{_t("Show more")}
);
}
const tiles = toRender.map(r => (
-
+
));
return (
-
{_t("Recent Conversations")}
+ {sectionName}
{tiles}
{showMore}
@@ -175,7 +384,6 @@ export default class DMInviteDialog extends React.PureComponent {
id="inviteTargets"
value={this.state.filterText}
onChange={this._updateFilter}
- placeholder="TODO: Implement filtering/searching (vector-im/riot-web#11199)"
/>
);
@@ -209,7 +417,8 @@ export default class DMInviteDialog extends React.PureComponent {
{_t("Go")}
- {this._renderRecents()}
+ {this._renderSection('recents')}
+ {this._renderSection('suggestions')}
);
diff --git a/src/components/views/elements/LazyRenderList.js b/src/components/views/elements/LazyRenderList.js
index 0fc0ef6733..7572dced0b 100644
--- a/src/components/views/elements/LazyRenderList.js
+++ b/src/components/views/elements/LazyRenderList.js
@@ -56,14 +56,20 @@ class ItemRange {
}
export default class LazyRenderList extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {};
+ }
+
static getDerivedStateFromProps(props, state) {
const range = LazyRenderList.getVisibleRangeFromProps(props);
const intersectRange = range.expand(props.overflowMargin);
const renderRange = range.expand(props.overflowItems);
- const listHasChangedSize = !!state && renderRange.totalSize() !== state.renderRange.totalSize();
+ const listHasChangedSize = !!state.renderRange && renderRange.totalSize() !== state.renderRange.totalSize();
// only update render Range if the list has shrunk/grown and we need to adjust padding OR
// if the new range + overflowMargin isn't contained by the old anymore
- if (listHasChangedSize || !state || !state.renderRange.contains(intersectRange)) {
+ if (listHasChangedSize || !state.renderRange || !state.renderRange.contains(intersectRange)) {
return {renderRange};
}
return null;
diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js
index f232756433..0b81098124 100644
--- a/src/components/views/elements/TagTile.js
+++ b/src/components/views/elements/TagTile.js
@@ -55,6 +55,8 @@ export default createReactClass({
hover: false,
// The profile data of the group if this.props.tag is a group ID
profile: null,
+ // Whether or not the context menu is open
+ menuDisplayed: false,
};
},
diff --git a/src/components/views/emojipicker/EmojiPicker.js b/src/components/views/emojipicker/EmojiPicker.js
index 4d49b25100..a9cf2a4732 100644
--- a/src/components/views/emojipicker/EmojiPicker.js
+++ b/src/components/views/emojipicker/EmojiPicker.js
@@ -47,10 +47,8 @@ class EmojiPicker extends React.Component {
viewportHeight: 280,
};
- // Convert recent emoji characters to emoji data, removing unknowns.
- this.recentlyUsed = recent.get()
- .map(unicode => getEmojiFromUnicode(unicode))
- .filter(data => !!data);
+ // Convert recent emoji characters to emoji data, removing unknowns and duplicates
+ this.recentlyUsed = Array.from(new Set(recent.get().map(getEmojiFromUnicode).filter(Boolean)));
this.memoizedDataByCategory = {
recent: this.recentlyUsed,
...DATA_BY_CATEGORY,
diff --git a/src/components/views/groups/GroupPublicityToggle.js b/src/components/views/groups/GroupPublicityToggle.js
index bacf54382a..176bd9f988 100644
--- a/src/components/views/groups/GroupPublicityToggle.js
+++ b/src/components/views/groups/GroupPublicityToggle.js
@@ -32,7 +32,7 @@ export default createReactClass({
return {
busy: false,
ready: false,
- isGroupPublicised: null,
+ isGroupPublicised: false, // assume false as expects a boolean
};
},
@@ -43,7 +43,7 @@ export default createReactClass({
_initGroupStore: function(groupId) {
this._groupStoreToken = GroupStore.registerListener(groupId, () => {
this.setState({
- isGroupPublicised: GroupStore.getGroupPublicity(groupId),
+ isGroupPublicised: Boolean(GroupStore.getGroupPublicity(groupId)),
ready: GroupStore.isStateReady(groupId, GroupStore.STATE_KEY.Summary),
});
});
diff --git a/src/components/views/right_panel/UserInfo.js b/src/components/views/right_panel/UserInfo.js
index b55991eda8..9c90953114 100644
--- a/src/components/views/right_panel/UserInfo.js
+++ b/src/components/views/right_panel/UserInfo.js
@@ -1000,8 +1000,8 @@ const UserInfo = ({user, groupId, roomId, onClose}) => {
// Load room if we are given a room id and memoize it
const room = useMemo(() => roomId ? cli.getRoom(roomId) : null, [cli, roomId]);
- // fetch latest room member if we have a room, so we don't show historical information
- const member = useMemo(() => room ? room.getMember(user.userId) : user, [room, user]);
+ // fetch latest room member if we have a room, so we don't show historical information, falling back to user
+ const member = useMemo(() => room ? (room.getMember(user.userId) || user) : user, [room, user]);
// only display the devices list if our client supports E2E
const _enableDevices = cli.isCryptoEnabled();
diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js
index aa9d46c9d5..8e75680a89 100644
--- a/src/components/views/room_settings/AliasSettings.js
+++ b/src/components/views/room_settings/AliasSettings.js
@@ -17,7 +17,7 @@ limitations under the License.
import EditableItemList from "../elements/EditableItemList";
-const React = require('react');
+import React, {createRef} from 'react';
import PropTypes from 'prop-types';
const MatrixClientPeg = require('../../../MatrixClientPeg');
const sdk = require("../../../index");
@@ -28,22 +28,41 @@ import AccessibleButton from "../elements/AccessibleButton";
const Modal = require("../../../Modal");
class EditableAliasesList extends EditableItemList {
+ constructor(props) {
+ super(props);
+
+ this._aliasField = createRef();
+ }
+
+ _onAliasAdded = async () => {
+ await this._aliasField.current.validate({ allowEmpty: false });
+
+ if (this._aliasField.current.isValid) {
+ if (this.props.onItemAdded) this.props.onItemAdded(this.props.newItem);
+ return;
+ }
+
+ this._aliasField.current.focus();
+ this._aliasField.current.validate({ allowEmpty: false, focused: true });
+ };
+
_renderNewItemField() {
const RoomAliasField = sdk.getComponent('views.elements.RoomAliasField');
const onChange = (alias) => this._onNewItemChanged({target: {value: alias}});
return (
@@ -99,11 +118,6 @@ export default class AliasSettings extends React.Component {
return dict;
}
- isAliasValid(alias) {
- // XXX: FIXME https://github.com/matrix-org/matrix-doc/issues/668
- return (alias.match(/^#([^/:,]+?):(.+)$/) && encodeURI(alias) === alias);
- }
-
changeCanonicalAlias(alias) {
if (!this.props.canSetCanonicalAlias) return;
@@ -139,38 +153,31 @@ export default class AliasSettings extends React.Component {
const localDomain = MatrixClientPeg.get().getDomain();
if (!alias.includes(':')) alias += ':' + localDomain;
- if (this.isAliasValid(alias) && alias.endsWith(localDomain)) {
- MatrixClientPeg.get().createAlias(alias, this.props.roomId).then(() => {
- const localAliases = this.state.domainToAliases[localDomain] || [];
- const domainAliases = Object.assign({}, this.state.domainToAliases);
- domainAliases[localDomain] = [...localAliases, alias];
- this.setState({
- domainToAliases: domainAliases,
- // Reset the add field
- newAlias: "",
- });
+ MatrixClientPeg.get().createAlias(alias, this.props.roomId).then(() => {
+ const localAliases = this.state.domainToAliases[localDomain] || [];
+ const domainAliases = Object.assign({}, this.state.domainToAliases);
+ domainAliases[localDomain] = [...localAliases, alias];
- if (!this.state.canonicalAlias) {
- this.changeCanonicalAlias(alias);
- }
- }).catch((err) => {
- console.error(err);
- Modal.createTrackedDialog('Error creating alias', '', ErrorDialog, {
- title: _t("Error creating alias"),
- description: _t(
- "There was an error creating that alias. It may not be allowed by the server " +
- "or a temporary failure occurred.",
- ),
- });
+ this.setState({
+ domainToAliases: domainAliases,
+ // Reset the add field
+ newAlias: "",
});
- } else {
- const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
- Modal.createTrackedDialog('Invalid alias format', '', ErrorDialog, {
- title: _t('Invalid alias format'),
- description: _t('\'%(alias)s\' is not a valid format for an alias', { alias: alias }),
+
+ if (!this.state.canonicalAlias) {
+ this.changeCanonicalAlias(alias);
+ }
+ }).catch((err) => {
+ console.error(err);
+ Modal.createTrackedDialog('Error creating alias', '', ErrorDialog, {
+ title: _t("Error creating alias"),
+ description: _t(
+ "There was an error creating that alias. It may not be allowed by the server " +
+ "or a temporary failure occurred.",
+ ),
});
- }
+ });
};
onLocalAliasDeleted = (index) => {
diff --git a/src/components/views/room_settings/RoomProfileSettings.js b/src/components/views/room_settings/RoomProfileSettings.js
index 2093a31a28..abcdce23f8 100644
--- a/src/components/views/room_settings/RoomProfileSettings.js
+++ b/src/components/views/room_settings/RoomProfileSettings.js
@@ -98,6 +98,8 @@ export default class RoomProfileSettings extends React.Component {
newState.avatarUrl = client.mxcUrlToHttp(uri, 96, 96, 'crop', false);
newState.originalAvatarUrl = newState.avatarUrl;
newState.avatarFile = null;
+ } else if (this.state.originalAvatarUrl !== this.state.avatarUrl) {
+ await client.sendStateEvent(this.props.roomId, 'm.room.avatar', {url: undefined}, '');
}
if (this.state.originalTopic !== this.state.topic) {
diff --git a/src/components/views/rooms/LinkPreviewWidget.js b/src/components/views/rooms/LinkPreviewWidget.js
index ee63cd1bb7..3b5545e0e0 100644
--- a/src/components/views/rooms/LinkPreviewWidget.js
+++ b/src/components/views/rooms/LinkPreviewWidget.js
@@ -18,7 +18,8 @@ limitations under the License.
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
-import { linkifyElement } from '../../../HtmlUtils';
+import { AllHtmlEntities } from 'html-entities';
+import {linkifyElement} from '../../../HtmlUtils';
import SettingsStore from "../../../settings/SettingsStore";
import { _t } from "../../../languageHandler";
@@ -127,6 +128,10 @@ module.exports = createReactClass({
;
}
+ // The description includes &-encoded HTML entities, we decode those as React treats the thing as an
+ // opaque string. This does not allow any HTML to be injected into the DOM.
+ const description = AllHtmlEntities.decode(p["og:description"] || "");
+
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
return (
@@ -135,7 +140,7 @@ module.exports = createReactClass({
{ p["og:site_name"] ? (" - " + p["og:site_name"]) : null }
- { p["og:description"] }
+ { description }
diff --git a/src/components/views/settings/ProfileSettings.js b/src/components/views/settings/ProfileSettings.js
index 480b414911..b56321c1c9 100644
--- a/src/components/views/settings/ProfileSettings.js
+++ b/src/components/views/settings/ProfileSettings.js
@@ -88,6 +88,8 @@ export default class ProfileSettings extends React.Component {
newState.avatarUrl = client.mxcUrlToHttp(uri, 96, 96, 'crop', false);
newState.originalAvatarUrl = newState.avatarUrl;
newState.avatarFile = null;
+ } else if (this.state.originalAvatarUrl !== this.state.avatarUrl) {
+ await client.setAvatarUrl(""); // use empty string as Synapse 500s on undefined
}
this.setState(newState);
diff --git a/src/emoji.js b/src/emoji.js
index 7b7a9c1bfe..125864e381 100644
--- a/src/emoji.js
+++ b/src/emoji.js
@@ -16,14 +16,12 @@ limitations under the License.
import EMOJIBASE from 'emojibase-data/en/compact.json';
-export const VARIATION_SELECTOR = String.fromCharCode(0xFE0F);
-
// The unicode is stored without the variant selector
const UNICODE_TO_EMOJI = new Map(); // not exported as gets for it are handled by getEmojiFromUnicode
export const EMOTICON_TO_EMOJI = new Map();
export const SHORTCODE_TO_EMOJI = new Map();
-export const getEmojiFromUnicode = unicode => UNICODE_TO_EMOJI.get(unicode.replace(VARIATION_SELECTOR, ""));
+export const getEmojiFromUnicode = unicode => UNICODE_TO_EMOJI.get(stripVariation(unicode));
const EMOJIBASE_GROUP_ID_TO_CATEGORY = [
"people", // smileys
@@ -51,13 +49,6 @@ export const DATA_BY_CATEGORY = {
// Store various mappings from unicode/emoticon/shortcode to the Emoji objects
EMOJIBASE.forEach(emoji => {
- if (emoji.unicode.includes(VARIATION_SELECTOR)) {
- // Clone data into variation-less version
- emoji = Object.assign({}, emoji, {
- unicode: emoji.unicode.replace(VARIATION_SELECTOR, ""),
- });
- }
-
const categoryId = EMOJIBASE_GROUP_ID_TO_CATEGORY[emoji.group];
if (DATA_BY_CATEGORY.hasOwnProperty(categoryId)) {
DATA_BY_CATEGORY[categoryId].push(emoji);
@@ -66,7 +57,13 @@ EMOJIBASE.forEach(emoji => {
emoji.filterString = `${emoji.annotation}\n${emoji.shortcodes.join('\n')}}\n${emoji.emoticon || ''}`.toLowerCase();
// Add mapping from unicode to Emoji object
- UNICODE_TO_EMOJI.set(emoji.unicode, emoji);
+ // The 'unicode' field that we use in emojibase has either
+ // VS15 or VS16 appended to any characters that can take
+ // variation selectors. Which one it appends depends
+ // on whether emojibase considers their type to be 'text' or
+ // 'emoji'. We therefore strip any variation chars from strings
+ // both when building the map and when looking up.
+ UNICODE_TO_EMOJI.set(stripVariation(emoji.unicode), emoji);
if (emoji.emoticon) {
// Add mapping from emoticon to Emoji object
@@ -80,3 +77,15 @@ EMOJIBASE.forEach(emoji => {
});
}
});
+
+/**
+ * Strips variation selectors from a string
+ * NB. Skin tone modifers are not variation selectors:
+ * this function does not touch them. (Should it?)
+ *
+ * @param {string} str string to strip
+ * @returns {string} stripped string
+ */
+function stripVariation(str) {
+ return str.replace(/[\uFE00-\uFE0F]/, "");
+}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 9c2105afab..b34b737891 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -1074,8 +1074,6 @@
"There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.": "There was an error updating the room's main address. It may not be allowed by the server or a temporary failure occurred.",
"Error creating alias": "Error creating alias",
"There was an error creating that alias. It may not be allowed by the server or a temporary failure occurred.": "There was an error creating that alias. It may not be allowed by the server or a temporary failure occurred.",
- "Invalid alias format": "Invalid alias format",
- "'%(alias)s' is not a valid format for an alias": "'%(alias)s' is not a valid format for an alias",
"Error removing alias": "Error removing alias",
"There was an error removing that alias. It may no longer exist or a temporary error occurred.": "There was an error removing that alias. It may no longer exist or a temporary error occurred.",
"Main address": "Main address",
@@ -1424,8 +1422,9 @@
"View Servers in Room": "View Servers in Room",
"Toolbox": "Toolbox",
"Developer Tools": "Developer Tools",
- "Show more": "Show more",
"Recent Conversations": "Recent Conversations",
+ "Suggestions": "Suggestions",
+ "Show more": "Show more",
"Direct Messages": "Direct Messages",
"If you can't find someone, ask them for their username, or share your username (%(userId)s) or profile link.": "If you can't find someone, ask them for their username, or share your username (%(userId)s) or profile link.",
"Go": "Go",
diff --git a/test/end-to-end-tests/src/usecases/room-settings.js b/test/end-to-end-tests/src/usecases/room-settings.js
index 5b425f14b7..8e9e267d45 100644
--- a/test/end-to-end-tests/src/usecases/room-settings.js
+++ b/test/end-to-end-tests/src/usecases/room-settings.js
@@ -55,6 +55,7 @@ module.exports = async function changeRoomSettings(session, settings) {
await session.replaceInputText(aliasField, settings.alias.substring(1, settings.alias.lastIndexOf(":")));
const addButton = await session.query(".mx_RoomSettingsDialog .mx_AliasSettings .mx_AccessibleButton");
await addButton.click();
+ await session.delay(10); // delay to give time for the validator to run and check the alias
session.log.done();
}
diff --git a/yarn.lock b/yarn.lock
index c32a108934..36b6acee26 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -531,22 +531,6 @@ agentkeepalive@^3.4.1:
dependencies:
humanize-ms "^1.2.1"
-airbnb-prop-types@^2.15.0:
- version "2.15.0"
- resolved "https://registry.yarnpkg.com/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz#5287820043af1eb469f5b0af0d6f70da6c52aaef"
- integrity sha512-jUh2/hfKsRjNFC4XONQrxo/n/3GG4Tn6Hl0WlFQN5PY9OMC9loSCoAYKnZsWaP8wEfd5xcrPloK0Zg6iS1xwVA==
- dependencies:
- array.prototype.find "^2.1.0"
- function.prototype.name "^1.1.1"
- has "^1.0.3"
- is-regex "^1.0.4"
- object-is "^1.0.1"
- object.assign "^4.1.0"
- object.entries "^1.1.0"
- prop-types "^15.7.2"
- prop-types-exact "^1.2.0"
- react-is "^16.9.0"
-
ajv-errors@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
@@ -675,11 +659,6 @@ arr-union@^3.1.0:
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
-array-filter@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83"
- integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=
-
array-find-index@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
@@ -720,22 +699,6 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
-array.prototype.find@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.1.0.tgz#630f2eaf70a39e608ac3573e45cf8ccd0ede9ad7"
- integrity sha512-Wn41+K1yuO5p7wRZDl7890c3xvv5UBrfVXTVIe28rSQb6LS0fZMDrQB6PAcxQFRFy6vJTLDc3A2+3CjQdzVKRg==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.13.0"
-
-array.prototype.flat@^1.2.3:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b"
- integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
-
arraybuffer.slice@~0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
@@ -1658,11 +1621,6 @@ body-parser@^1.16.1:
raw-body "2.4.0"
type-is "~1.6.17"
-boolbase@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
- integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
-
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -1999,18 +1957,6 @@ chardet@^0.7.0:
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
-cheerio@^1.0.0-rc.3:
- version "1.0.0-rc.3"
- resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6"
- integrity sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==
- dependencies:
- css-select "~1.2.0"
- dom-serializer "~0.1.1"
- entities "~1.1.1"
- htmlparser2 "^3.9.1"
- lodash "^4.15.0"
- parse5 "^3.0.1"
-
chokidar@^1.6.1:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
@@ -2190,7 +2136,7 @@ commander@2.15.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
-commander@^2.11.0, commander@^2.19.0, commander@^2.20.0:
+commander@^2.11.0, commander@^2.20.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -2428,21 +2374,6 @@ crypto-browserify@^3.11.0:
randombytes "^2.0.0"
randomfill "^1.0.3"
-css-select@~1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
- integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=
- dependencies:
- boolbase "~1.0.0"
- css-what "2.1"
- domutils "1.5.1"
- nth-check "~1.0.1"
-
-css-what@2.1:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
- integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
-
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@@ -2661,11 +2592,6 @@ dir-glob@^2.2.2:
dependencies:
path-type "^3.0.0"
-discontinuous-range@1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
- integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=
-
doctrine@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
@@ -2705,20 +2631,12 @@ dom-serializer@0:
domelementtype "^2.0.1"
entities "^2.0.0"
-dom-serializer@~0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0"
- integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
- dependencies:
- domelementtype "^1.3.0"
- entities "^1.1.1"
-
domain-browser@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
-domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1:
+domelementtype@1, domelementtype@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
@@ -2735,14 +2653,6 @@ domhandler@^2.3.0:
dependencies:
domelementtype "1"
-domutils@1.5.1:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
- integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=
- dependencies:
- dom-serializer "0"
- domelementtype "1"
-
domutils@^1.5.1:
version "1.7.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
@@ -2906,7 +2816,7 @@ ent@~2.2.0:
resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0=
-entities@^1.1.1, "entities@~ 1.1.1", entities@~1.1.1:
+entities@^1.1.1, "entities@~ 1.1.1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
@@ -2916,69 +2826,6 @@ entities@^2.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
-enzyme-adapter-react-16@^1.15.1:
- version "1.15.2"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.2.tgz#b16db2f0ea424d58a808f9df86ab6212895a4501"
- integrity sha512-SkvDrb8xU3lSxID8Qic9rB8pvevDbLybxPK6D/vW7PrT0s2Cl/zJYuXvsd1EBTz0q4o3iqG3FJhpYz3nUNpM2Q==
- dependencies:
- enzyme-adapter-utils "^1.13.0"
- enzyme-shallow-equal "^1.0.1"
- has "^1.0.3"
- object.assign "^4.1.0"
- object.values "^1.1.1"
- prop-types "^15.7.2"
- react-is "^16.12.0"
- react-test-renderer "^16.0.0-0"
- semver "^5.7.0"
-
-enzyme-adapter-utils@^1.13.0:
- version "1.13.0"
- resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.13.0.tgz#01c885dde2114b4690bf741f8dc94cee3060eb78"
- integrity sha512-YuEtfQp76Lj5TG1NvtP2eGJnFKogk/zT70fyYHXK2j3v6CtuHqc8YmgH/vaiBfL8K1SgVVbQXtTcgQZFwzTVyQ==
- dependencies:
- airbnb-prop-types "^2.15.0"
- function.prototype.name "^1.1.2"
- object.assign "^4.1.0"
- object.fromentries "^2.0.2"
- prop-types "^15.7.2"
- semver "^5.7.1"
-
-enzyme-shallow-equal@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.1.tgz#7afe03db3801c9b76de8440694096412a8d9d49e"
- integrity sha512-hGA3i1so8OrYOZSM9whlkNmVHOicJpsjgTzC+wn2JMJXhq1oO4kA4bJ5MsfzSIcC71aLDKzJ6gZpIxrqt3QTAQ==
- dependencies:
- has "^1.0.3"
- object-is "^1.0.2"
-
-enzyme@^3.10.0:
- version "3.11.0"
- resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.11.0.tgz#71d680c580fe9349f6f5ac6c775bc3e6b7a79c28"
- integrity sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==
- dependencies:
- array.prototype.flat "^1.2.3"
- cheerio "^1.0.0-rc.3"
- enzyme-shallow-equal "^1.0.1"
- function.prototype.name "^1.1.2"
- has "^1.0.3"
- html-element-map "^1.2.0"
- is-boolean-object "^1.0.1"
- is-callable "^1.1.5"
- is-number-object "^1.0.4"
- is-regex "^1.0.5"
- is-string "^1.0.5"
- is-subset "^0.1.1"
- lodash.escape "^4.0.1"
- lodash.isequal "^4.5.0"
- object-inspect "^1.7.0"
- object-is "^1.0.2"
- object.assign "^4.1.0"
- object.entries "^1.1.1"
- object.values "^1.1.1"
- raf "^3.4.1"
- rst-selector-parser "^2.2.3"
- string.prototype.trim "^1.2.1"
-
err-code@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960"
@@ -3014,23 +2861,6 @@ es-abstract@^1.12.0, es-abstract@^1.15.0, es-abstract@^1.16.2, es-abstract@^1.7.
string.prototype.trimleft "^2.1.0"
string.prototype.trimright "^2.1.0"
-es-abstract@^1.13.0, es-abstract@^1.17.0-next.1:
- version "1.17.0"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1"
- integrity sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug==
- dependencies:
- es-to-primitive "^1.2.1"
- function-bind "^1.1.1"
- has "^1.0.3"
- has-symbols "^1.0.1"
- is-callable "^1.1.5"
- is-regex "^1.0.5"
- object-inspect "^1.7.0"
- object-keys "^1.1.1"
- object.assign "^4.1.0"
- string.prototype.trimleft "^2.1.1"
- string.prototype.trimright "^2.1.1"
-
es-get-iterator@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.0.1.tgz#ebc4d3bbc2d59dd95a0ecef441ca2dbce7d9e2cd"
@@ -3770,15 +3600,6 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
-function.prototype.name@^1.1.1, function.prototype.name@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.2.tgz#5cdf79d7c05db401591dfde83e3b70c5123e9a45"
- integrity sha512-C8A+LlHBJjB2AdcRPorc5JvJ5VUoWlXdEHLOJdCI7kjHEtGTpHQUiqMvCIKUwIsGwZX2jZJy761AXsn356bJQg==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
- functions-have-names "^1.2.0"
-
functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
@@ -4167,19 +3988,17 @@ hosted-git-info@^2.1.4:
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c"
integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==
-html-element-map@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/html-element-map/-/html-element-map-1.2.0.tgz#dfbb09efe882806af63d990cf6db37993f099f22"
- integrity sha512-0uXq8HsuG1v2TmQ8QkIhzbrqeskE4kn52Q18QJ9iAA/SnHoEKXWiUxHQtclRsCFWEUD2So34X+0+pZZu862nnw==
- dependencies:
- array-filter "^1.0.0"
+html-entities@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
+ integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=
html-tags@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b"
integrity sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=
-htmlparser2@^3.10.0, htmlparser2@^3.9.1:
+htmlparser2@^3.10.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
@@ -4498,11 +4317,6 @@ is-boolean-object@^1.0.0:
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
integrity sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M=
-is-boolean-object@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e"
- integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==
-
is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
@@ -4518,11 +4332,6 @@ is-callable@^1.0.4, is-callable@^1.1.4:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
-is-callable@^1.1.5:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
- integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
-
is-data-descriptor@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
@@ -4700,11 +4509,6 @@ is-number-object@^1.0.3:
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799"
integrity sha1-8mWrian0RQNO9q/xWo8AsA9VF5k=
-is-number-object@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197"
- integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==
-
is-number@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
@@ -4768,13 +4572,6 @@ is-regex@^1.0.3, is-regex@^1.0.4:
dependencies:
has "^1.0.1"
-is-regex@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
- integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==
- dependencies:
- has "^1.0.3"
-
is-regexp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
@@ -4795,16 +4592,6 @@ is-string@^1.0.4:
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64"
integrity sha1-zDqbaYV9Yh6WNyWiTK7shzuCbmQ=
-is-string@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
- integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==
-
-is-subset@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
- integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=
-
is-supported-regexp-flag@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.1.tgz#21ee16518d2c1dd3edd3e9a0d57e50207ac364ca"
@@ -5290,21 +5077,11 @@ lodash.clonedeep@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
-lodash.escape@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98"
- integrity sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=
-
lodash.escaperegexp@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"
integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=
-lodash.flattendeep@^4.4.0:
- version "4.4.0"
- resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
- integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=
-
lodash.get@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
@@ -5315,11 +5092,6 @@ lodash.isboolean@^3.0.3:
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
-lodash.isequal@^4.5.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
- integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
-
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
@@ -5345,7 +5117,7 @@ lodash.unescape@4.0.1:
resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c"
integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=
-lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.2.1:
+lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.2.1:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@@ -5792,11 +5564,6 @@ mocha@^5.0.5:
mkdirp "0.5.1"
supports-color "5.4.0"
-moo@^0.4.3:
- version "0.4.3"
- resolved "https://registry.yarnpkg.com/moo/-/moo-0.4.3.tgz#3f847a26f31cf625a956a87f2b10fbc013bfd10e"
- integrity sha512-gFD2xGCl8YFgGHsqJ9NKRVdwlioeW3mI1iqfLNYQOv0+6JRwG58Zk9DIGQgyIaffSYaO1xsKnMaYzzNr1KyIAw==
-
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@@ -5851,17 +5618,6 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
-nearley@^2.7.10:
- version "2.19.0"
- resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.19.0.tgz#37717781d0fd0f2bfc95e233ebd75678ca4bda46"
- integrity sha512-2v52FTw7RPqieZr3Gth1luAXZR7Je6q3KaDHY5bjl/paDUdMu35fZ8ICNgiYJRr3tf3NMvIQQR1r27AvEr9CRA==
- dependencies:
- commander "^2.19.0"
- moo "^0.4.3"
- railroad-diagrams "^1.0.0"
- randexp "0.4.6"
- semver "^5.4.1"
-
needle@^2.2.1:
version "2.4.0"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c"
@@ -6036,13 +5792,6 @@ npmlog@^4.0.2:
gauge "~2.7.3"
set-blocking "~2.0.0"
-nth-check@~1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
- integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==
- dependencies:
- boolbase "~1.0.0"
-
null-check@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd"
@@ -6087,11 +5836,6 @@ object-inspect@^1.1.0, object-inspect@^1.7.0:
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==
-object-is@^1.0.1, object-is@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4"
- integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==
-
object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.0.9, object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
@@ -6124,16 +5868,6 @@ object.entries@^1.1.0:
function-bind "^1.1.1"
has "^1.0.3"
-object.entries@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.1.tgz#ee1cf04153de02bb093fec33683900f57ce5399b"
- integrity sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
- function-bind "^1.1.1"
- has "^1.0.3"
-
object.fromentries@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.1.tgz#050f077855c7af8ae6649f45c80b16ee2d31e704"
@@ -6144,16 +5878,6 @@ object.fromentries@^2.0.1:
function-bind "^1.1.1"
has "^1.0.3"
-object.fromentries@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9"
- integrity sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
- function-bind "^1.1.1"
- has "^1.0.3"
-
object.omit@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
@@ -6179,16 +5903,6 @@ object.values@^1.1.0:
function-bind "^1.1.1"
has "^1.0.3"
-object.values@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e"
- integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
- function-bind "^1.1.1"
- has "^1.0.3"
-
on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
@@ -6399,13 +6113,6 @@ parse-passwd@^1.0.0:
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=
-parse5@^3.0.1:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
- integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==
- dependencies:
- "@types/node" "*"
-
parseqs@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d"
@@ -6724,15 +6431,6 @@ promise@^7.0.3, promise@^7.1.1:
dependencies:
asap "~2.0.3"
-prop-types-exact@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/prop-types-exact/-/prop-types-exact-1.2.0.tgz#825d6be46094663848237e3925a98c6e944e9869"
- integrity sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==
- dependencies:
- has "^1.0.3"
- object.assign "^4.1.0"
- reflect.ownkeys "^0.2.0"
-
prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
@@ -6861,26 +6559,13 @@ raf-schd@^2.1.0:
resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-2.1.2.tgz#ec622b5167f2912089f054dc03ebd5bcf33c8f62"
integrity sha512-Orl0IEvMtUCgPddgSxtxreK77UiQz4nPYJy9RggVzu4mKsZkQWiAaG1y9HlYWdvm9xtN348xRaT37qkvL/+A+g==
-raf@^3.1.0, raf@^3.4.1:
+raf@^3.1.0:
version "3.4.1"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==
dependencies:
performance-now "^2.1.0"
-railroad-diagrams@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
- integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=
-
-randexp@0.4.6:
- version "0.4.6"
- resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3"
- integrity sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==
- dependencies:
- discontinuous-range "1.0.0"
- ret "~0.1.10"
-
randomatic@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed"
@@ -6988,7 +6673,7 @@ react-focus-lock@^2.2.1:
dependencies:
gemini-scrollbar matrix-org/gemini-scrollbar#91e1e566
-react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0:
+react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6:
version "16.12.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==
@@ -7020,7 +6705,7 @@ react-redux@^5.0.6:
react-is "^16.6.0"
react-lifecycles-compat "^3.0.0"
-react-test-renderer@^16.0.0-0, react-test-renderer@^16.9.0:
+react-test-renderer@^16.9.0:
version "16.12.0"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.12.0.tgz#11417ffda579306d4e841a794d32140f3da1b43f"
integrity sha512-Vj/teSqt2oayaWxkbhQ6gKis+t5JrknXfPVo+aIJ8QwYAqMPH77uptOdrlphyxl8eQI/rtkOYg86i/UWkpFu0w==
@@ -7137,11 +6822,6 @@ redux@^3.7.2:
loose-envify "^1.1.0"
symbol-observable "^1.0.3"
-reflect.ownkeys@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460"
- integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=
-
regenerate@^1.2.1:
version "1.4.0"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
@@ -7458,14 +7138,6 @@ rollup-pluginutils@^2.8.1:
dependencies:
estree-walker "^0.6.1"
-rst-selector-parser@^2.2.3:
- version "2.2.3"
- resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91"
- integrity sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=
- dependencies:
- lodash.flattendeep "^4.4.0"
- nearley "^2.7.10"
-
run-async@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
@@ -7552,7 +7224,7 @@ schema-utils@^1.0.0:
ajv-errors "^1.0.0"
ajv-keywords "^3.1.0"
-"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
+"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -8001,15 +7673,6 @@ string.prototype.repeat@^0.2.0:
resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz#aba36de08dcee6a5a337d49b2ea1da1b28fc0ecf"
integrity sha1-q6Nt4I3O5qWjN9SbLqHaGyj8Ds8=
-string.prototype.trim@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782"
- integrity sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
- function-bind "^1.1.1"
-
string.prototype.trimleft@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634"
@@ -8018,14 +7681,6 @@ string.prototype.trimleft@^2.1.0:
define-properties "^1.1.3"
function-bind "^1.1.1"
-string.prototype.trimleft@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74"
- integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==
- dependencies:
- define-properties "^1.1.3"
- function-bind "^1.1.1"
-
string.prototype.trimright@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58"
@@ -8034,14 +7689,6 @@ string.prototype.trimright@^2.1.0:
define-properties "^1.1.3"
function-bind "^1.1.1"
-string.prototype.trimright@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9"
- integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==
- dependencies:
- define-properties "^1.1.3"
- function-bind "^1.1.1"
-
string_decoder@^1.0.0, string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"