kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Merge remote-tracking branch 'soapbox/develop' into ts
commit
97b4b9cfd4
|
@ -8,6 +8,7 @@
|
||||||
/deploy.sh
|
/deploy.sh
|
||||||
/.vs/
|
/.vs/
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
/junit.xml
|
||||||
|
|
||||||
/static/
|
/static/
|
||||||
/static-test/
|
/static-test/
|
||||||
|
|
|
@ -56,7 +56,14 @@ jest:
|
||||||
- "jest.config.js"
|
- "jest.config.js"
|
||||||
- "package.json"
|
- "package.json"
|
||||||
- "yarn.lock"
|
- "yarn.lock"
|
||||||
|
- ".gitlab-ci.yml"
|
||||||
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
|
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
|
||||||
|
artifacts:
|
||||||
|
reports:
|
||||||
|
junit: junit.xml
|
||||||
|
coverage_report:
|
||||||
|
coverage_format: cobertura
|
||||||
|
path: .coverage/cobertura-coverage.xml
|
||||||
|
|
||||||
nginx-test:
|
nginx-test:
|
||||||
stage: test
|
stage: test
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
type ButtonThemes = 'primary' | 'secondary' | 'ghost' | 'accent' | 'danger' | 'transparent' | 'link'
|
type ButtonThemes = 'primary' | 'secondary' | 'ghost' | 'accent' | 'danger' | 'transparent' | 'link' | 'danger-link'
|
||||||
type ButtonSizes = 'sm' | 'md' | 'lg'
|
type ButtonSizes = 'sm' | 'md' | 'lg'
|
||||||
|
|
||||||
type IButtonStyles = {
|
type IButtonStyles = {
|
||||||
|
@ -25,6 +25,7 @@ const useButtonStyles = ({
|
||||||
ghost: 'shadow-none border-gray-200 text-gray-700 bg-white dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 focus:ring-primary-500 focus:ring-2 focus:ring-offset-2',
|
ghost: 'shadow-none border-gray-200 text-gray-700 bg-white dark:border-slate-700 dark:bg-slate-800 dark:text-slate-200 focus:ring-primary-500 focus:ring-2 focus:ring-offset-2',
|
||||||
accent: 'border-transparent text-white bg-accent-500 hover:bg-accent-300 focus:ring-pink-500 focus:ring-2 focus:ring-offset-2',
|
accent: 'border-transparent text-white bg-accent-500 hover:bg-accent-300 focus:ring-pink-500 focus:ring-2 focus:ring-offset-2',
|
||||||
danger: 'border-transparent text-danger-700 bg-danger-100 hover:bg-danger-200 focus:ring-danger-500 focus:ring-2 focus:ring-offset-2',
|
danger: 'border-transparent text-danger-700 bg-danger-100 hover:bg-danger-200 focus:ring-danger-500 focus:ring-2 focus:ring-offset-2',
|
||||||
|
'danger-link': 'border-transparent text-accent-500 hover:bg-accent-500 hover:bg-opacity-10',
|
||||||
transparent: 'border-transparent text-gray-800 backdrop-blur-sm bg-white/75 hover:bg-white/80',
|
transparent: 'border-transparent text-gray-800 backdrop-blur-sm bg-white/75 hover:bg-white/80',
|
||||||
link: 'border-transparent text-primary-600 dark:text-primary-400 hover:bg-primary-100 hover:text-primary-700 dark:hover:bg-slate-900/50',
|
link: 'border-transparent text-primary-600 dark:text-primary-400 hover:bg-primary-100 hover:text-primary-700 dark:hover:bg-slate-900/50',
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,13 +14,13 @@ import Icon from 'soapbox/components/icon';
|
||||||
import { Button } from 'soapbox/components/ui';
|
import { Button } from 'soapbox/components/ui';
|
||||||
import { isMobile } from 'soapbox/is_mobile';
|
import { isMobile } from 'soapbox/is_mobile';
|
||||||
|
|
||||||
|
import PollForm from '../components/polls/poll-form';
|
||||||
import ReplyMentions from '../components/reply_mentions';
|
import ReplyMentions from '../components/reply_mentions';
|
||||||
import UploadForm from '../components/upload_form';
|
import UploadForm from '../components/upload_form';
|
||||||
import Warning from '../components/warning';
|
import Warning from '../components/warning';
|
||||||
import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container';
|
import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container';
|
||||||
import MarkdownButtonContainer from '../containers/markdown_button_container';
|
import MarkdownButtonContainer from '../containers/markdown_button_container';
|
||||||
import PollButtonContainer from '../containers/poll_button_container';
|
import PollButtonContainer from '../containers/poll_button_container';
|
||||||
import PollFormContainer from '../containers/poll_form_container';
|
|
||||||
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
|
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
|
||||||
import QuotedStatusContainer from '../containers/quoted_status_container';
|
import QuotedStatusContainer from '../containers/quoted_status_container';
|
||||||
import ReplyIndicatorContainer from '../containers/reply_indicator_container';
|
import ReplyIndicatorContainer from '../containers/reply_indicator_container';
|
||||||
|
@ -361,7 +361,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
!condensed &&
|
!condensed &&
|
||||||
<div className='compose-form__modifiers'>
|
<div className='compose-form__modifiers'>
|
||||||
<UploadForm />
|
<UploadForm />
|
||||||
<PollFormContainer />
|
<PollForm />
|
||||||
<ScheduleFormContainer />
|
<ScheduleFormContainer />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { addPollOption, changePollOption, changePollSettings, clearComposeSuggestions, fetchComposeSuggestions, removePoll, removePollOption, selectComposeSuggestion } from 'soapbox/actions/compose';
|
||||||
import AutosuggestInput from 'soapbox/components/autosuggest_input';
|
import AutosuggestInput from 'soapbox/components/autosuggest_input';
|
||||||
import { Button, Divider, HStack, Stack, Text, Toggle } from 'soapbox/components/ui';
|
import { Button, Divider, HStack, Stack, Text, Toggle } from 'soapbox/components/ui';
|
||||||
import { useAppSelector } from 'soapbox/hooks';
|
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||||
|
|
||||||
import DurationSelector from './polls/duration-selector';
|
import DurationSelector from './duration-selector';
|
||||||
|
|
||||||
import type { AutoSuggestion } from 'soapbox/components/autosuggest_input';
|
import type { AutoSuggestion } from 'soapbox/components/autosuggest_input';
|
||||||
|
|
||||||
|
@ -31,12 +30,8 @@ interface IOption {
|
||||||
maxChars: number
|
maxChars: number
|
||||||
numOptions: number
|
numOptions: number
|
||||||
onChange(index: number, value: string): void
|
onChange(index: number, value: string): void
|
||||||
onClearSuggestions(): void
|
|
||||||
onFetchSuggestions(token: string): void
|
|
||||||
onRemove(index: number): void
|
onRemove(index: number): void
|
||||||
onRemovePoll(): void
|
onRemovePoll(): void
|
||||||
onSuggestionSelected(tokenStart: number, token: string, value: string, key: (string | number)[]): void
|
|
||||||
suggestions?: any // list
|
|
||||||
title: string
|
title: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,16 +41,16 @@ const Option = (props: IOption) => {
|
||||||
maxChars,
|
maxChars,
|
||||||
numOptions,
|
numOptions,
|
||||||
onChange,
|
onChange,
|
||||||
onClearSuggestions,
|
|
||||||
onFetchSuggestions,
|
|
||||||
onRemove,
|
onRemove,
|
||||||
onRemovePoll,
|
onRemovePoll,
|
||||||
suggestions,
|
|
||||||
title,
|
title,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const suggestions = useAppSelector((state) => state.compose.get('suggestions'));
|
||||||
|
|
||||||
const handleOptionTitleChange = (event: React.ChangeEvent<HTMLInputElement>) => onChange(index, event.target.value);
|
const handleOptionTitleChange = (event: React.ChangeEvent<HTMLInputElement>) => onChange(index, event.target.value);
|
||||||
|
|
||||||
const handleOptionRemove = () => {
|
const handleOptionRemove = () => {
|
||||||
|
@ -66,13 +61,13 @@ const Option = (props: IOption) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSuggestionsClearRequested = () => onClearSuggestions();
|
const onSuggestionsClearRequested = () => dispatch(clearComposeSuggestions());
|
||||||
|
|
||||||
const onSuggestionsFetchRequested = (token: string) => onFetchSuggestions(token);
|
const onSuggestionsFetchRequested = (token: string) => dispatch(fetchComposeSuggestions(token));
|
||||||
|
|
||||||
const onSuggestionSelected = (tokenStart: number, token: string | null, value: AutoSuggestion) => {
|
const onSuggestionSelected = (tokenStart: number, token: string | null, value: AutoSuggestion) => {
|
||||||
if (token && typeof value === 'string') {
|
if (token && typeof token === 'string') {
|
||||||
props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', index]);
|
dispatch(selectComposeSuggestion(tokenStart, token, value, ['poll', 'options', index]));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -94,7 +89,7 @@ const Option = (props: IOption) => {
|
||||||
onSuggestionsClearRequested={onSuggestionsClearRequested}
|
onSuggestionsClearRequested={onSuggestionsClearRequested}
|
||||||
onSuggestionSelected={onSuggestionSelected}
|
onSuggestionSelected={onSuggestionSelected}
|
||||||
searchTokens={[':']}
|
searchTokens={[':']}
|
||||||
autoFocus={index === 0}
|
autoFocus={index === 0 || index >= 2}
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
||||||
|
@ -107,42 +102,26 @@ const Option = (props: IOption) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IPollForm {
|
const PollForm = () => {
|
||||||
expiresIn?: number
|
const dispatch = useAppDispatch();
|
||||||
isMultiple?: boolean
|
|
||||||
onAddOption(value: string): void
|
|
||||||
onChangeOption(): void
|
|
||||||
onChangeSettings(value: string | number | undefined, isMultiple?: boolean): void
|
|
||||||
onClearSuggestions(): void
|
|
||||||
onFetchSuggestions(token: string): void
|
|
||||||
onRemoveOption(): void
|
|
||||||
onRemovePoll(): void
|
|
||||||
onSuggestionSelected(tokenStart: number, token: string, value: string, key: (string | number)[]): void
|
|
||||||
options?: any
|
|
||||||
suggestions?: any // list
|
|
||||||
}
|
|
||||||
|
|
||||||
const PollForm = (props: IPollForm) => {
|
|
||||||
const {
|
|
||||||
expiresIn,
|
|
||||||
isMultiple,
|
|
||||||
onAddOption,
|
|
||||||
onChangeOption,
|
|
||||||
onChangeSettings,
|
|
||||||
onRemoveOption,
|
|
||||||
options,
|
|
||||||
...filteredProps
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const pollLimits = useAppSelector((state) => state.instance.getIn(['configuration', 'polls']) as any);
|
const pollLimits = useAppSelector((state) => state.instance.getIn(['configuration', 'polls']) as any);
|
||||||
|
const options = useAppSelector((state) => state.compose.getIn(['poll', 'options']));
|
||||||
|
const expiresIn = useAppSelector((state) => state.compose.getIn(['poll', 'expires_in']));
|
||||||
|
const isMultiple = useAppSelector((state) => state.compose.getIn(['poll', 'multiple']));
|
||||||
|
|
||||||
const maxOptions = pollLimits.get('max_options');
|
const maxOptions = pollLimits.get('max_options');
|
||||||
const maxOptionChars = pollLimits.get('max_characters_per_option');
|
const maxOptionChars = pollLimits.get('max_characters_per_option');
|
||||||
|
|
||||||
const handleAddOption = () => onAddOption('');
|
const onRemoveOption = (index: number) => dispatch(removePollOption(index));
|
||||||
|
const onChangeOption = (index: number, title: string) => dispatch(changePollOption(index, title));
|
||||||
|
const handleAddOption = () => dispatch(addPollOption(''));
|
||||||
|
const onChangeSettings = (expiresIn: string | number | undefined, isMultiple?: boolean) =>
|
||||||
|
dispatch(changePollSettings(expiresIn, isMultiple));
|
||||||
const handleSelectDuration = (value: number) => onChangeSettings(value, isMultiple);
|
const handleSelectDuration = (value: number) => onChangeSettings(value, isMultiple);
|
||||||
const handleToggleMultiple = () => onChangeSettings(expiresIn, !isMultiple);
|
const handleToggleMultiple = () => onChangeSettings(expiresIn, !isMultiple);
|
||||||
|
const onRemovePoll = () => dispatch(removePoll());
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -160,7 +139,7 @@ const PollForm = (props: IPollForm) => {
|
||||||
onRemove={onRemoveOption}
|
onRemove={onRemoveOption}
|
||||||
maxChars={maxOptionChars}
|
maxChars={maxOptionChars}
|
||||||
numOptions={options.size}
|
numOptions={options.size}
|
||||||
{...filteredProps}
|
onRemovePoll={onRemovePoll}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
@ -211,7 +190,7 @@ const PollForm = (props: IPollForm) => {
|
||||||
|
|
||||||
{/* Remove Poll */}
|
{/* Remove Poll */}
|
||||||
<div className='text-center'>
|
<div className='text-center'>
|
||||||
<Button theme='danger' size='sm' onClick={props.onRemovePoll}>
|
<Button theme='danger-link' onClick={onRemovePoll}>
|
||||||
{intl.formatMessage(messages.removePoll)}
|
{intl.formatMessage(messages.removePoll)}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
|
@ -1,57 +0,0 @@
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import {
|
|
||||||
addPollOption,
|
|
||||||
removePollOption,
|
|
||||||
changePollOption,
|
|
||||||
changePollSettings,
|
|
||||||
removePoll,
|
|
||||||
clearComposeSuggestions,
|
|
||||||
fetchComposeSuggestions,
|
|
||||||
selectComposeSuggestion,
|
|
||||||
} from '../../../actions/compose';
|
|
||||||
import PollForm from '../components/poll-form';
|
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
|
||||||
suggestions: state.getIn(['compose', 'suggestions']),
|
|
||||||
options: state.getIn(['compose', 'poll', 'options']),
|
|
||||||
expiresIn: state.getIn(['compose', 'poll', 'expires_in']),
|
|
||||||
isMultiple: state.getIn(['compose', 'poll', 'multiple']),
|
|
||||||
});
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
|
||||||
onAddOption(title) {
|
|
||||||
dispatch(addPollOption(title));
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemoveOption(index) {
|
|
||||||
dispatch(removePollOption(index));
|
|
||||||
},
|
|
||||||
|
|
||||||
onChangeOption(index, title) {
|
|
||||||
dispatch(changePollOption(index, title));
|
|
||||||
},
|
|
||||||
|
|
||||||
onChangeSettings(expiresIn, isMultiple) {
|
|
||||||
dispatch(changePollSettings(expiresIn, isMultiple));
|
|
||||||
},
|
|
||||||
|
|
||||||
onClearSuggestions() {
|
|
||||||
dispatch(clearComposeSuggestions());
|
|
||||||
},
|
|
||||||
|
|
||||||
onFetchSuggestions(token) {
|
|
||||||
dispatch(fetchComposeSuggestions(token));
|
|
||||||
},
|
|
||||||
|
|
||||||
onSuggestionSelected(position, token, accountId, path) {
|
|
||||||
dispatch(selectComposeSuggestion(position, token, accountId, path));
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemovePoll() {
|
|
||||||
dispatch(removePoll());
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(PollForm);
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { AxiosError } from 'axios';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import OtpInput from 'react-otp-input';
|
import OtpInput from 'react-otp-input';
|
||||||
|
@ -61,15 +62,13 @@ const SmsVerification = () => {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
setStatus(Statuses.REQUESTED);
|
setStatus(Statuses.REQUESTED);
|
||||||
}).catch(() => {
|
}).catch((error: AxiosError) => {
|
||||||
dispatch(
|
const message = (error.response?.data as any)?.message || intl.formatMessage({
|
||||||
snackbar.error(
|
id: 'sms_verification.fail',
|
||||||
intl.formatMessage({
|
defaultMessage: 'Failed to send SMS message to your phone number.',
|
||||||
id: 'sms_verification.fail',
|
});
|
||||||
defaultMessage: 'Failed to send SMS message to your phone number.',
|
|
||||||
}),
|
dispatch(snackbar.error(message));
|
||||||
),
|
|
||||||
);
|
|
||||||
setStatus(Statuses.FAIL);
|
setStatus(Statuses.FAIL);
|
||||||
});
|
});
|
||||||
}, [phone, isValid]);
|
}, [phone, isValid]);
|
||||||
|
|
|
@ -28,6 +28,7 @@ module.exports = {
|
||||||
],
|
],
|
||||||
'coverageDirectory': '<rootDir>/.coverage/',
|
'coverageDirectory': '<rootDir>/.coverage/',
|
||||||
'coverageReporters': ['html', 'text', 'text-summary', 'cobertura'],
|
'coverageReporters': ['html', 'text', 'text-summary', 'cobertura'],
|
||||||
|
'reporters': ['default', 'jest-junit'],
|
||||||
'moduleDirectories': [
|
'moduleDirectories': [
|
||||||
'<rootDir>/node_modules',
|
'<rootDir>/node_modules',
|
||||||
'<rootDir>/app',
|
'<rootDir>/app',
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
"jsdoc": "npx jsdoc -c jsdoc.conf.js",
|
"jsdoc": "npx jsdoc -c jsdoc.conf.js",
|
||||||
"manage:translations": "node ./webpack/translationRunner.js",
|
"manage:translations": "node ./webpack/translationRunner.js",
|
||||||
"test": "npx cross-env NODE_ENV=test npx jest",
|
"test": "npx cross-env NODE_ENV=test npx jest",
|
||||||
"test:coverage": "npx jest --coverage",
|
"test:coverage": "${npm_execpath} run test --coverage",
|
||||||
"test:all": "${npm_execpath} run test:coverage && ${npm_execpath} run lint",
|
"test:all": "${npm_execpath} run test:coverage && ${npm_execpath} run lint",
|
||||||
"lint": "${npm_execpath} run lint:js && ${npm_execpath} run lint:sass",
|
"lint": "${npm_execpath} run lint:js && ${npm_execpath} run lint:sass",
|
||||||
"lint:js": "npx eslint --ext .js,.jsx,.ts,.tsx . --cache",
|
"lint:js": "npx eslint --ext .js,.jsx,.ts,.tsx . --cache",
|
||||||
|
@ -219,6 +219,7 @@
|
||||||
"fake-indexeddb": "^3.1.7",
|
"fake-indexeddb": "^3.1.7",
|
||||||
"husky": "^7.0.2",
|
"husky": "^7.0.2",
|
||||||
"jest": "^27.5.1",
|
"jest": "^27.5.1",
|
||||||
|
"jest-junit": "^13.2.0",
|
||||||
"lint-staged": ">=10",
|
"lint-staged": ">=10",
|
||||||
"raf": "^3.4.1",
|
"raf": "^3.4.1",
|
||||||
"react-intl-translations-manager": "^5.0.3",
|
"react-intl-translations-manager": "^5.0.3",
|
||||||
|
|
15
yarn.lock
15
yarn.lock
|
@ -6778,6 +6778,16 @@ jest-jasmine2@^27.5.1:
|
||||||
pretty-format "^27.5.1"
|
pretty-format "^27.5.1"
|
||||||
throat "^6.0.1"
|
throat "^6.0.1"
|
||||||
|
|
||||||
|
jest-junit@^13.2.0:
|
||||||
|
version "13.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-13.2.0.tgz#66eeb86429aafac8c1745a70f44ace185aacb943"
|
||||||
|
integrity sha512-B0XNlotl1rdsvFZkFfoa19mc634+rrd8E4Sskb92Bb8MmSXeWV9XJGUyctunZS1W410uAxcyYuPUGVnbcOH8cg==
|
||||||
|
dependencies:
|
||||||
|
mkdirp "^1.0.4"
|
||||||
|
strip-ansi "^6.0.1"
|
||||||
|
uuid "^8.3.2"
|
||||||
|
xml "^1.0.1"
|
||||||
|
|
||||||
jest-leak-detector@^27.5.1:
|
jest-leak-detector@^27.5.1:
|
||||||
version "27.5.1"
|
version "27.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8"
|
resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8"
|
||||||
|
@ -11312,6 +11322,11 @@ xml-name-validator@^3.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
||||||
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
|
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
|
||||||
|
|
||||||
|
xml@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
|
||||||
|
integrity sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==
|
||||||
|
|
||||||
xmlchars@^2.2.0:
|
xmlchars@^2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
|
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
|
||||||
|
|
Ładowanie…
Reference in New Issue