Client - init localization w/ react-i18n - #40
This commit is contained in:
parent
4b39c7d1a8
commit
8473f6652c
@ -1,4 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { Translation } from 'react-i18next'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
|
|
||||||
@ -8,6 +9,8 @@ class NavBar extends React.PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
const { id, isAuthenticated, picture, username } = this.props
|
const { id, isAuthenticated, picture, username } = this.props
|
||||||
return (
|
return (
|
||||||
|
<Translation>
|
||||||
|
{t => (
|
||||||
<header>
|
<header>
|
||||||
<nav className="navbar navbar-expand-lg navbar-light bg-light">
|
<nav className="navbar navbar-expand-lg navbar-light bg-light">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
@ -35,7 +38,7 @@ class NavBar extends React.PureComponent {
|
|||||||
pathname: '/',
|
pathname: '/',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Dashboard
|
{t('Dashboard')}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
{isAuthenticated && (
|
{isAuthenticated && (
|
||||||
@ -46,7 +49,7 @@ class NavBar extends React.PureComponent {
|
|||||||
pathname: '/activities/history',
|
pathname: '/activities/history',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Workouts
|
{t('Workouts')}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
@ -58,7 +61,7 @@ class NavBar extends React.PureComponent {
|
|||||||
pathname: '/activities/statistics',
|
pathname: '/activities/statistics',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Statistics
|
{t('Statistics')}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
@ -70,7 +73,7 @@ class NavBar extends React.PureComponent {
|
|||||||
pathname: '/activities/add',
|
pathname: '/activities/add',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<strong>Add workout</strong>
|
<strong>{t('Add workout')}</strong>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
@ -87,7 +90,10 @@ class NavBar extends React.PureComponent {
|
|||||||
{/* </li> */}
|
{/* </li> */}
|
||||||
{/* )} */}
|
{/* )} */}
|
||||||
</ul>
|
</ul>
|
||||||
<ul className="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
{/* prettier-ignore */}
|
||||||
|
<ul
|
||||||
|
className="navbar-nav flex-row ml-md-auto d-none d-md-flex"
|
||||||
|
>
|
||||||
{!isAuthenticated && (
|
{!isAuthenticated && (
|
||||||
<li className="nav-item">
|
<li className="nav-item">
|
||||||
<Link
|
<Link
|
||||||
@ -96,7 +102,7 @@ class NavBar extends React.PureComponent {
|
|||||||
pathname: '/register',
|
pathname: '/register',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Register
|
{t('Register')}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
@ -108,7 +114,7 @@ class NavBar extends React.PureComponent {
|
|||||||
pathname: '/login',
|
pathname: '/login',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Login
|
{t('Login')}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
@ -139,7 +145,7 @@ class NavBar extends React.PureComponent {
|
|||||||
pathname: '/logout',
|
pathname: '/logout',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Logout
|
{t('Logout')}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
@ -148,6 +154,8 @@ class NavBar extends React.PureComponent {
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
)}
|
||||||
|
</Translation>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
|
|
||||||
import { history } from '../../index'
|
import { history } from '../../index'
|
||||||
import { isRegistrationAllowed } from '../../utils'
|
import { isRegistrationAllowed } from '../../utils'
|
||||||
|
|
||||||
export default function Form(props) {
|
export default function Form(props) {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const pageTitle = `${props.formType
|
||||||
|
.charAt(0)
|
||||||
|
.toUpperCase()}${props.formType.slice(1)}`
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>FitTrackee - {props.formType}</title>
|
<title>FitTrackee - {t(props.formType)}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<h1 className="page-title">
|
<h1 className="page-title">{t(pageTitle)}</h1>
|
||||||
{`${props.formType.charAt(0).toUpperCase()}${props.formType.slice(1)}`}
|
|
||||||
</h1>
|
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-md-3" />
|
<div className="col-md-3" />
|
||||||
@ -43,7 +46,7 @@ export default function Form(props) {
|
|||||||
<input
|
<input
|
||||||
className="form-control input-lg"
|
className="form-control input-lg"
|
||||||
name="username"
|
name="username"
|
||||||
placeholder="Enter a username"
|
placeholder={t('Enter a username')}
|
||||||
required
|
required
|
||||||
type="text"
|
type="text"
|
||||||
value={props.userForm.username}
|
value={props.userForm.username}
|
||||||
@ -55,7 +58,7 @@ export default function Form(props) {
|
|||||||
<input
|
<input
|
||||||
className="form-control input-lg"
|
className="form-control input-lg"
|
||||||
name="email"
|
name="email"
|
||||||
placeholder="Enter an email address"
|
placeholder={t('Enter an email address')}
|
||||||
required
|
required
|
||||||
type="email"
|
type="email"
|
||||||
value={props.userForm.email}
|
value={props.userForm.email}
|
||||||
@ -66,7 +69,7 @@ export default function Form(props) {
|
|||||||
<input
|
<input
|
||||||
className="form-control input-lg"
|
className="form-control input-lg"
|
||||||
name="password"
|
name="password"
|
||||||
placeholder="Enter a password"
|
placeholder={t('Enter a password')}
|
||||||
required
|
required
|
||||||
type="password"
|
type="password"
|
||||||
value={props.userForm.password}
|
value={props.userForm.password}
|
||||||
@ -78,7 +81,7 @@ export default function Form(props) {
|
|||||||
<input
|
<input
|
||||||
className="form-control input-lg"
|
className="form-control input-lg"
|
||||||
name="password_conf"
|
name="password_conf"
|
||||||
placeholder="Enter the password confirmation"
|
placeholder={t('Enter the password confirmation')}
|
||||||
required
|
required
|
||||||
type="password"
|
type="password"
|
||||||
value={props.userForm.password_conf}
|
value={props.userForm.password_conf}
|
||||||
@ -89,7 +92,7 @@ export default function Form(props) {
|
|||||||
<input
|
<input
|
||||||
type="submit"
|
type="submit"
|
||||||
className="btn btn-primary btn-lg btn-block"
|
className="btn btn-primary btn-lg btn-block"
|
||||||
value="Submit"
|
value={t('Submit')}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
|
31
fittrackee_client/src/i18n.js
Normal file
31
fittrackee_client/src/i18n.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import i18n from 'i18next'
|
||||||
|
import LanguageDetector from 'i18next-browser-languagedetector'
|
||||||
|
import XHR from 'i18next-xhr-backend'
|
||||||
|
|
||||||
|
import EnTranslations from './locales/en/translations.json'
|
||||||
|
import FrTranslations from './locales/fr/translations.json'
|
||||||
|
|
||||||
|
i18n
|
||||||
|
.use(XHR)
|
||||||
|
.use(LanguageDetector)
|
||||||
|
.init({
|
||||||
|
debug: true,
|
||||||
|
lng: 'en',
|
||||||
|
fallbackLng: 'en',
|
||||||
|
keySeparator: false,
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: false,
|
||||||
|
},
|
||||||
|
resources: {
|
||||||
|
en: {
|
||||||
|
translations: EnTranslations,
|
||||||
|
},
|
||||||
|
fr: {
|
||||||
|
translations: FrTranslations,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ns: ['translations'],
|
||||||
|
defaultNS: 'translations',
|
||||||
|
})
|
||||||
|
|
||||||
|
export default i18n
|
@ -1,11 +1,13 @@
|
|||||||
/* eslint-disable react/jsx-filename-extension */
|
/* eslint-disable react/jsx-filename-extension */
|
||||||
import { createBrowserHistory } from 'history'
|
import { createBrowserHistory } from 'history'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { I18nextProvider } from 'react-i18next'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import { routerMiddleware } from 'connected-react-router'
|
import { routerMiddleware } from 'connected-react-router'
|
||||||
import { applyMiddleware, createStore, compose } from 'redux'
|
import { applyMiddleware, compose, createStore } from 'redux'
|
||||||
import thunk from 'redux-thunk'
|
import thunk from 'redux-thunk'
|
||||||
|
|
||||||
|
import i18n from './i18n'
|
||||||
import App from './components/App'
|
import App from './components/App'
|
||||||
import Root from './components/Root'
|
import Root from './components/Root'
|
||||||
import registerServiceWorker from './registerServiceWorker'
|
import registerServiceWorker from './registerServiceWorker'
|
||||||
@ -34,7 +36,9 @@ if (window.localStorage.authToken !== null) {
|
|||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Root store={store} history={history}>
|
<Root store={store} history={history}>
|
||||||
|
<I18nextProvider i18n={i18n}>
|
||||||
<App />
|
<App />
|
||||||
|
</I18nextProvider>
|
||||||
</Root>,
|
</Root>,
|
||||||
rootNode
|
rootNode
|
||||||
)
|
)
|
||||||
|
15
fittrackee_client/src/locales/en/translations.json
Normal file
15
fittrackee_client/src/locales/en/translations.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"Dashboard": "Dashboard",
|
||||||
|
"Workouts": "Workouts",
|
||||||
|
"Statistics": "Statistics",
|
||||||
|
"Add workout": "Add workout",
|
||||||
|
"Register": "Register",
|
||||||
|
"Login": "Login",
|
||||||
|
"Logout": "Logout",
|
||||||
|
"login": "login",
|
||||||
|
"Enter a username": "Enter a username",
|
||||||
|
"Enter an email address": "Enter an email address",
|
||||||
|
"Enter a password": "Enter a password",
|
||||||
|
"Enter the password confirmation": "Enter the password confirmation",
|
||||||
|
"Submit": "Submit"
|
||||||
|
}
|
15
fittrackee_client/src/locales/fr/translations.json
Normal file
15
fittrackee_client/src/locales/fr/translations.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"Dashboard": "Tableau de Bord",
|
||||||
|
"Workouts": "Activités",
|
||||||
|
"Statistics": "Statistiques",
|
||||||
|
"Add workout": "Ajouter une activité",
|
||||||
|
"Register": "S'inscrire",
|
||||||
|
"Login": "Se connecter",
|
||||||
|
"Logout": "Se déconnecter",
|
||||||
|
"login": "se connecter",
|
||||||
|
"Enter a username": "Saisir un nom",
|
||||||
|
"Enter an email address": "Saisir une adresse e-mail",
|
||||||
|
"Enter a password": "Saisir un mot de passe",
|
||||||
|
"Enter the password confirmation": "Confirmer le mot de passe",
|
||||||
|
"Submit": "Valider"
|
||||||
|
}
|
@ -7,12 +7,16 @@
|
|||||||
"connected-react-router": "^6.5.2",
|
"connected-react-router": "^6.5.2",
|
||||||
"date-fns": "^2.1.0",
|
"date-fns": "^2.1.0",
|
||||||
"history": "^4.9.0",
|
"history": "^4.9.0",
|
||||||
|
"i18next": "^17.0.13",
|
||||||
|
"i18next-browser-languagedetector": "^3.0.3",
|
||||||
|
"i18next-xhr-backend": "^3.1.2",
|
||||||
"leaflet": "^1.5.1",
|
"leaflet": "^1.5.1",
|
||||||
"luxon": "^1.17.2",
|
"luxon": "^1.17.2",
|
||||||
"object-hash": "^1.3.1",
|
"object-hash": "^1.3.1",
|
||||||
"react": "^16.9.0",
|
"react": "^16.9.0",
|
||||||
"react-dom": "^16.9.0",
|
"react-dom": "^16.9.0",
|
||||||
"react-helmet": "^6.0.0-beta",
|
"react-helmet": "^6.0.0-beta",
|
||||||
|
"react-i18next": "^10.12.2",
|
||||||
"react-leaflet": "^2.4.0",
|
"react-leaflet": "^2.4.0",
|
||||||
"react-redux": "^7.1.1",
|
"react-redux": "^7.1.1",
|
||||||
"react-router-dom": "^5.0.1",
|
"react-router-dom": "^5.0.1",
|
||||||
|
41
yarn.lock
41
yarn.lock
@ -851,7 +851,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime "^0.13.2"
|
regenerator-runtime "^0.13.2"
|
||||||
|
|
||||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5":
|
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5":
|
||||||
version "7.6.0"
|
version "7.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205"
|
||||||
integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==
|
integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==
|
||||||
@ -5692,6 +5692,13 @@ html-minifier@^3.5.20:
|
|||||||
relateurl "0.2.x"
|
relateurl "0.2.x"
|
||||||
uglify-js "3.4.x"
|
uglify-js "3.4.x"
|
||||||
|
|
||||||
|
html-parse-stringify2@2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a"
|
||||||
|
integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=
|
||||||
|
dependencies:
|
||||||
|
void-elements "^2.0.1"
|
||||||
|
|
||||||
html-webpack-plugin@4.0.0-beta.5:
|
html-webpack-plugin@4.0.0-beta.5:
|
||||||
version "4.0.0-beta.5"
|
version "4.0.0-beta.5"
|
||||||
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.5.tgz#2c53083c1151bfec20479b1f8aaf0039e77b5513"
|
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.5.tgz#2c53083c1151bfec20479b1f8aaf0039e77b5513"
|
||||||
@ -5791,6 +5798,25 @@ https-browserify@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||||
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
||||||
|
|
||||||
|
i18next-browser-languagedetector@^3.0.3:
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-3.0.3.tgz#879ebe421685c70cc5cfa96191364a35ea7da742"
|
||||||
|
integrity sha512-1YuAogyQap0J6N4kM+6gAjZ6T7QWrp3xZCmSs0QedkNmgAKhj7FiQlCviHKl3IwbM6zJNgft4D7UDPWb1dTCMQ==
|
||||||
|
|
||||||
|
i18next-xhr-backend@^3.1.2:
|
||||||
|
version "3.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/i18next-xhr-backend/-/i18next-xhr-backend-3.1.2.tgz#f9da86c81981ac245325cb2dbfd4232a5b183676"
|
||||||
|
integrity sha512-zN+x85W5R2ezGfmRh8F7+lsXoQgCNNb1jjSfm0325VuSIZ4ewvsnq3uHFrZaXmSJ8qTwPibO9rRb3mIzncEF9g==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.5.5"
|
||||||
|
|
||||||
|
i18next@^17.0.13:
|
||||||
|
version "17.0.13"
|
||||||
|
resolved "https://registry.yarnpkg.com/i18next/-/i18next-17.0.13.tgz#3c639e15de86e0523f8f286f6cf07db355ee0a4f"
|
||||||
|
integrity sha512-tCBpekVs95IsN3kdi/6HhnfzHDlpXerOmOsf2ZMWtct9YbMYKI54HVdQ6XxsHGXBxY+UgjbQJwqghKCd2sYQWw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.3.1"
|
||||||
|
|
||||||
iconv-lite@0.4.11:
|
iconv-lite@0.4.11:
|
||||||
version "0.4.11"
|
version "0.4.11"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.11.tgz#2ecb42fd294744922209a2e7c404dac8793d8ade"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.11.tgz#2ecb42fd294744922209a2e7c404dac8793d8ade"
|
||||||
@ -9450,6 +9476,14 @@ react-helmet@^6.0.0-beta:
|
|||||||
react-fast-compare "^2.0.2"
|
react-fast-compare "^2.0.2"
|
||||||
react-side-effect "^1.1.0"
|
react-side-effect "^1.1.0"
|
||||||
|
|
||||||
|
react-i18next@^10.12.2:
|
||||||
|
version "10.12.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-10.12.2.tgz#2f2d79b84c1f3e3844d110e4c9d5c73a48f99418"
|
||||||
|
integrity sha512-tZCBhUz8rJtgmTi1z2pWEoQBvFHjwOS2+TQ7L4RfJq1LDirXi2m+3Pwg6gUECVCGenWomLufWNiTwRF9fmBrUQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.3.1"
|
||||||
|
html-parse-stringify2 "2.0.1"
|
||||||
|
|
||||||
react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, 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.9.0:
|
||||||
version "16.9.0"
|
version "16.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb"
|
||||||
@ -11642,6 +11676,11 @@ vm-browserify@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019"
|
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019"
|
||||||
integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==
|
integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==
|
||||||
|
|
||||||
|
void-elements@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
|
||||||
|
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
|
||||||
|
|
||||||
w3c-hr-time@^1.0.1:
|
w3c-hr-time@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045"
|
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045"
|
||||||
|
Loading…
Reference in New Issue
Block a user