deps: i18next 10 -> 23, react-i18next 7 -> 14

Modernizes the whole i18n stack:
- 48 translate([], {wait:true}) / translate() HOCs -> withTranslation()
- react.wait:true -> react.useSuspense:false
- whitelist -> supportedLngs; added compatibilityJSON: 'v3' so our
  natural-language keys + v3 _plural layout keep working (custom
  separators ss/eth/dj preserved)
- backends: xhr -> i18next-http-backend (client), sync-fs ->
  i18next-fs-backend (server); dropped i18next-localstorage-cache
  (was enabled:false); languagedetector 2 -> 8
- ReSendEmail: <Interpolate> (removed in v10) -> <Trans values={{email}}/>,
  dropped the removed bare t export
- saveMissing handler signature (lngs, ns, key, fallbackValue)

Silences the per-component Translate/I18n legacy-context warnings.
Browser-verified es/en switch and <Trans> interpolation on /fires;
REST smoke byte-identical.
This commit is contained in:
vjrj 2026-07-18 06:28:41 +02:00
parent f1eae84e25
commit 12bdbe8fed
52 changed files with 226 additions and 553 deletions

View file

@ -308,7 +308,8 @@ MONGO_CONTAINER=tcef-mongo7 MONGO_SHELL=mongosh MONGO_PORT=27019 ./smoke/smoke.s
| nodemailer | 4 | 6.10 | ✅ done — drop-in for our usage: `email.js` only calls `nodemailer.createTransport(MAIL_URL)` and reads `transport.options.auth.user` (in the production-only `from()` branch); both verified unchanged in v6. Sending goes through `ostrio:mailer` (MailTime 2.5), which is v6-compatible. |
| Babel | 7 beta | 7 stable | ✅ done (escala 1) |
| react-meteor-data | 0.2.16 | 3.0.6 | ✅ done — 0.2.16 (React-15/16-era) looped `withTracker` on fire-detail pages under React 18 (never-ready → blank). `meteor add react-meteor-data@3.0.6`; no call-site changes (HOC API kept). Also dropped `tmeasday:check-npm-versions` (the constraint pinning 0.2.16). See section above. |
| i18next | 10 | current | debt — pin; not on the critical path |
| i18next | 10.5 | 23.16 | ✅ done — with react-i18next 14. `whitelist``supportedLngs`, added `compatibilityJSON: 'v3'` (our locale JSON uses natural-language keys + v3 `_plural` layout, not the v4 `_one`/`_other` suffixes), custom separators `ß`/`ð`/`đ` kept. `sendMissing``saveMissing`, missingKeyHandler signature is `(lngs, ns, key, fallbackValue)` now (array first). See react-i18next row. |
| react-i18next | 7.4 | 14.1 | ✅ done — 48 `translate([], {wait:true})`/`translate()` HOCs → `withTranslation()`; `react.wait:true``react.useSuspense:false`. `<Trans>` unchanged (locale JSON already stores the indexed-tag format `<1><0>{{x}}</0></1>`). ReSendEmail: removed `<Interpolate>` (deleted in v10) → `<Trans i18nKey values={{email}}/>`, dropped the removed bare `t` export. This is what silenced the per-component `Translate`/`I18n` legacy-context console spam. Backends: xhr→`i18next-http-backend` (client), sync-fs→`i18next-fs-backend` (server); `i18next-localstorage-cache` dropped (was `enabled:false`); languagedetector 2→8. Browser-verified: es/en switch, `<Trans>` interpolation (`{{countTotal}}`+`<strong>`) renders on /fires. |
| Leaflet | 1.3.1 | current | debt — pin; not on the critical path |
| arkham:comments-ui | 1.4.x | — | ✅ replaced with in-repo React feature |
| nimble:restivus | Atmosphere | vendored | ✅ local precompiled package, accounts-password 2.x |

View file

@ -3,9 +3,8 @@ import i18n from 'i18next';
import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker';
import { ReactiveVar } from 'meteor/reactive-var';
import backend from 'i18next-xhr-backend';
import backend from 'i18next-http-backend';
import LngDetector from 'i18next-browser-languagedetector';
import Cache from 'i18next-localstorage-cache';
import { T9n } from 'meteor-accounts-t9n';
import moment from 'moment';
import 'moment/locale/es';
@ -31,21 +30,9 @@ const detectorOptions = {
export const i18nReady = new ReactiveVar(false);
const cacheOptions = {
// turn on or off
enabled: false,
// prefix for stored languages
prefix: 'i18next_res_',
// expiration
expirationTime: 7 * 24 * 60 * 60 * 1000,
// language versions
versions: {}
};
i18nOpts.cache = cacheOptions;
i18nOpts.detection = detectorOptions;
i18nOpts.react = {
wait: true,
useSuspense: false, // was `wait: true` pre-react-i18next-10
defaultTransParent: 'span'
// https://react.i18next.com/components/i18next-instance.ht
/* bindI18n: 'languageChanged loaded',
@ -55,8 +42,10 @@ i18nOpts.react = {
const sendMissing = true; // Meteor.isDevelopment;
if (sendMissing && Meteor.isDevelopment) {
i18nOpts.sendMissing = true;
i18nOpts.missingKeyHandler = function miss(lng, ns, key, defaultValue) {
i18nOpts.saveMissing = true;
// Modern signature is (lngs, ns, key, fallbackValue, ...); key/fallback keep
// the same positions, so we still only need those two.
i18nOpts.missingKeyHandler = function miss(lngs, ns, key, defaultValue) {
Meteor.call('utility.saveMissingI18n', key, defaultValue);
};
}
@ -71,7 +60,6 @@ function setT9(lang) {
i18n.use(backend)
.use(LngDetector)
.use(Cache)
.init(i18nOpts, (err, t) => {
// initialized and ready to
if (err) {

View file

@ -40,13 +40,17 @@ const i18nOpts = {
return value;
}
},
whitelist: ['es', 'en', 'gl'], // allowed languages
supportedLngs: ['es', 'en', 'gl'], // allowed languages (was `whitelist` pre-i18next-21)
load: 'languageOnly', // 'es' o 'en', previously: 'all', // es-ES -> es, en-US -> en
debug: shouldDebug,
ns: 'common',
defaultNS: 'common',
saveMissing: shouldDebug, // if true seems it's fails to getResourceBundle
saveMissingTo: 'es',
// Our locale JSON uses natural-language (Spanish) keys and the v3 plural
// layout (`key_plural`), so keep i18next on the v3 JSON format instead of
// the v4 suffix scheme (`key_one`/`key_other`).
compatibilityJSON: 'v3',
keySeparator: 'ß',
nsSeparator: 'ð',
pluralSeparator: 'đ'

View file

@ -1,6 +1,6 @@
import { Meteor } from 'meteor/meteor';
import i18n from 'i18next';
import backend from 'i18next-sync-fs-backend';
import backend from 'i18next-fs-backend';
import i18nOpts from '../common/i18n';
// import moment from 'moment';
// import { T9n } from 'meteor-accounts-t9n';

View file

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { LinkContainer } from 'react-router-bootstrap';
/* import { Nav, NavDropdown } from 'react-bootstrap'; */
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { testId } from '/imports/ui/components/Utils/TestUtils';
/*
@ -39,4 +39,4 @@ AuthenticatedNavigation.propTypes = {
name: PropTypes.string.isRequired
};
export default translate([], { wait: true })(withRouter(AuthenticatedNavigation));
export default withTranslation()(withRouter(AuthenticatedNavigation));

View file

@ -4,7 +4,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import './BetaRibbon.scss';
@ -30,4 +30,4 @@ BetaRibbon.propTypes = {
BetaRibbon.defaultProps = {
};
export default translate([], { wait: true })(BetaRibbon);
export default withTranslation()(BetaRibbon);

View file

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import { Tracker } from 'meteor/tracker';
import { ReactiveVar } from 'meteor/reactive-var';
import { Button } from 'react-bootstrap';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { Bert } from 'meteor/themeteorchef:bert';
import './CenterInMyPosition.scss';
@ -63,4 +63,4 @@ CenterInMyPosition.propTypes = {
onlyIcon: PropTypes.bool
};
export default translate([], { wait: true })(CenterInMyPosition);
export default withTranslation()(CenterInMyPosition);

View file

@ -3,7 +3,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { withTracker } from 'meteor/react-meteor-data';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { Meteor } from 'meteor/meteor';
import moment from 'moment';
import CommentsCollection from '/imports/api/Comments/Comments';
@ -149,4 +149,4 @@ const CommentsBoxContainer = withTracker(({ referenceId }) => {
};
})(CommentsBox);
export default translate([], { wait: true })(CommentsBoxContainer);
export default withTranslation()(CommentsBoxContainer);

View file

@ -2,7 +2,7 @@
/* eslint-disable import/no-absolute-path */
import React from 'react';
import PropTypes from 'prop-types';
import { Trans, translate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import Tooltip from 'rc-tooltip';
import Slider from 'rc-slider';
import 'rc-slider/assets/index.css';
@ -107,4 +107,4 @@ DistanceSlider.propTypes = {
onChange: PropTypes.func
};
export default translate([], { wait: true })(DistanceSlider);
export default withTranslation()(DistanceSlider);

View file

@ -5,7 +5,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Meteor } from 'meteor/meteor';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { FormGroup, Button, FormControl } from 'react-bootstrap';
import { Bert } from 'meteor/themeteorchef:bert';
import { withTracker } from 'meteor/react-meteor-data';
@ -134,7 +134,7 @@ Feedback.propTypes = {
isHome: PropTypes.bool.isRequired
};
export default translate()(withTracker(props => ({
export default withTranslation()(withTracker(props => ({
emailAddress: props.emailAddress,
emailVerified: props.emailVerified,
isHome: isHome()

View file

@ -4,7 +4,7 @@ import React from 'react';
import { year } from '@cleverbeagle/dates';
import { Link } from 'react-router-dom';
import { Grid } from 'react-bootstrap';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { testId } from '/imports/ui/components/Utils/TestUtils';
import './Footer.scss';
@ -51,4 +51,4 @@ const Footer = (props) => {
Footer.propTypes = {};
export default translate([], { wait: true })(Footer);
export default withTranslation()(Footer);

View file

@ -5,7 +5,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withTracker } from 'meteor/react-meteor-data';
import Chronos from '/imports/ui/components/Chronos/Chronos';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { dateLongFormat } from '/imports/api/Common/dates';
import './FromNow.scss';
@ -60,7 +60,7 @@ FromNow.defaultProps = {
* export default FromNowContainer;
* */
export default translate([], { wait: true })(withTracker((props) => {
export default withTranslation()(withTracker((props) => {
const whenDate = props.when;
return {
when: whenDate ? Chronos.moment(whenDate).fromNow() : null,

View file

@ -1,7 +1,7 @@
/* eslint-disable react/jsx-indent-props */
import React from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import PlacesAutocomplete, { geocodeByAddress, getLatLng } from 'react-places-autocomplete';
import { FormGroup, ControlLabel, HelpBlock } from 'react-bootstrap';
import { Bert } from 'meteor/themeteorchef:bert';
@ -130,4 +130,4 @@ LocationAutocomplete.propTypes = {
i18n: PropTypes.object.isRequired
};
export default translate([], { wait: true })(LocationAutocomplete);
export default withTranslation()(LocationAutocomplete);

View file

@ -4,7 +4,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { GoogleLayer } from 'react-leaflet-google/lib/';
import Gkeys from '/imports/startup/client/Gkeys';
import { TileLayer, LayersControl } from 'react-leaflet';
@ -85,4 +85,4 @@ DefMapLayers.defaultProps = {
satellite: false
};
export default translate([], { wait: true })(DefMapLayers);
export default withTranslation()(DefMapLayers);

View file

@ -3,7 +3,7 @@ import React, { Component, Fragment } from 'react';
import { CircleMarker, Marker, Tooltip } from 'react-leaflet';
import PropTypes from 'prop-types';
import { fireIconS, fireIconM, fireIconL, nFireIcon, industryIcon, regIndustryIcon } from '/imports/ui/components/Maps/Icons';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { onMarkClick } from './MarkListeners';
import FirePopup from './FirePopup';
@ -80,4 +80,4 @@ FireIconMark.propTypes = {
t: PropTypes.func.isRequired
};
export default translate([], { wait: true })(FireIconMark);
export default withTranslation()(FireIconMark);

View file

@ -3,7 +3,7 @@
import React from 'react';
import { CircleMarker } from 'react-leaflet';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import FirePopup from './FirePopup';
/* Less acurate (1 pixel per fire) but faster */
@ -34,4 +34,4 @@ FirePixel.propTypes = {
t: PropTypes.func.isRequired
};
export default translate([], { wait: true })(FirePixel);
export default withTranslation()(FirePixel);

View file

@ -2,7 +2,7 @@
import React, { Fragment } from 'react';
import { Tooltip } from 'react-leaflet';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
const FirePopup = ({
lat,
@ -29,4 +29,4 @@ FirePopup.propTypes = {
t: PropTypes.func.isRequired
};
export default translate([], { wait: true })(FirePopup);
export default withTranslation()(FirePopup);

View file

@ -4,7 +4,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import FullscreenControl from 'react-leaflet-fullscreen';
import 'react-leaflet-fullscreen/dist/styles.css';
@ -25,4 +25,4 @@ FullScreenMap.propTypes = {
t: PropTypes.func.isRequired
};
export default translate([], { wait: true })(FullScreenMap);
export default withTranslation()(FullScreenMap);

View file

@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
import { Navbar } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import { LinkContainer } from 'react-router-bootstrap';
import { Trans, translate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import { testId } from '/imports/ui/components/Utils/TestUtils';
/* import BetaRibbon from '../../components/BetaRibbon/BetaRibbon'; */
import PublicNavigation from '../PublicNavigation/PublicNavigation';
@ -71,4 +71,4 @@ Navigation.propTypes = {
authenticated: PropTypes.bool.isRequired
};
export default translate([], { wait: true })(Navigation);
export default withTranslation()(Navigation);

View file

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { Meteor } from 'meteor/meteor';
import { Bert } from 'meteor/themeteorchef:bert';
import Icon from '../Icon/Icon';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
import './OAuthLoginButton.scss';
@ -60,4 +60,4 @@ OAuthLoginButton.propTypes = {
callback: PropTypes.func,
};
export default translate([], { wait: true })(OAuthLoginButton);
export default withTranslation()(OAuthLoginButton);

View file

@ -3,7 +3,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { LinkContainer } from 'react-router-bootstrap';
/* import { Nav } from 'react-bootstrap'; */
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { testId } from '/imports/ui/components/Utils/TestUtils';
/*
@ -32,4 +32,4 @@ PublicNavigation.propTypes = {
t: PropTypes.func.isRequired
};
export default translate([], { wait: true })(PublicNavigation);
export default withTranslation()(PublicNavigation);

View file

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Grid, Alert, Button } from 'react-bootstrap';
import { t, Trans, translate, Interpolate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
const handleResendVerificationEmail = (emailAddress, t) => {
@ -16,7 +16,7 @@ const handleResendVerificationEmail = (emailAddress, t) => {
const ReSendEmail = props => (
<div>
{props.userId && !props.emailVerified ? <Alert className="verify-email text-center"><p><Interpolate i18nKey="verifyEmail" email={props.emailAddress}></Interpolate> <Button bsStyle="link" onClick={() => handleResendVerificationEmail(props.emailAddress, props.t)} href="#"><Trans parent="span">Reenviar email de verificación</Trans></Button></p></Alert> : ''}
{props.userId && !props.emailVerified ? <Alert className="verify-email text-center"><p><Trans i18nKey="verifyEmail" values={{ email: props.emailAddress }} /> <Button bsStyle="link" onClick={() => handleResendVerificationEmail(props.emailAddress, props.t)} href="#"><Trans parent="span">Reenviar email de verificación</Trans></Button></p></Alert> : ''}
</div>
);
@ -32,4 +32,4 @@ ReSendEmail.propTypes = {
emailVerified: PropTypes.bool.isRequired,
};
export default translate([], { wait: true })(ReSendEmail);
export default withTranslation()(ReSendEmail);

View file

@ -3,7 +3,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
/* import { Meteor } from 'meteor/meteor';
import { Tracker } from 'meteor/tracker'; */
import Blaze from 'meteor/gadicc:blaze-react-component';
@ -28,7 +28,7 @@ Reconnect.propTypes = {
Reconnect.defaultProps = {
};
export default translate([], { wait: true })(Reconnect);
export default withTranslation()(Reconnect);
/*
if (!Meteor.isProduction) {

View file

@ -9,7 +9,7 @@ import PropTypes from 'prop-types';
import { Meteor } from 'meteor/meteor';
import { Map, Marker, CircleMarker, Circle, Tooltip } from 'react-leaflet';
import Leaflet from 'leaflet';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { withTracker } from 'meteor/react-meteor-data';
import update from 'immutability-helper';
import geolocation from '/imports/startup/client/geolocation';
@ -293,7 +293,7 @@ SelectionMap.propTypes = {
}))
};
export default translate([], { wait: true })(withTracker((props) => {
export default withTranslation()(withTracker((props) => {
const subscription = Meteor.subscribe('mysubscriptions');
// console.log(props.loadingSubs);
return {

View file

@ -3,7 +3,7 @@
/* eslint-disable import/no-absolute-path */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { withTracker } from 'meteor/react-meteor-data';
import { currentLocationHref } from '/imports/ui/components/Utils/location';
import {
@ -138,7 +138,7 @@ ShareIt.propTypes = {
ShareIt.defaultProps = {
};
export default translate([], { wait: true })(withTracker((props) => {
export default withTranslation()(withTracker((props) => {
const { title } = props;
return {
title

View file

@ -8,7 +8,7 @@ import PropTypes from 'prop-types';
import { Meteor } from 'meteor/meteor';
import { Bert } from 'meteor/themeteorchef:bert';
import FireSubscription from '/imports/ui/pages/FireSubscription/FireSubscription';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { isAnyMobile } from '/imports/ui/components/Utils/isMobile';
class SubscriptionEditor extends React.Component {
@ -89,4 +89,4 @@ SubscriptionEditor.propTypes = {
focusInput: PropTypes.bool
};
export default translate([], { wait: true })(SubscriptionEditor);
export default withTranslation()(SubscriptionEditor);

View file

@ -3,7 +3,7 @@
/* eslint-disable react/jsx-indent */
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Page from '../Page/Page';
const About = props => (
@ -16,4 +16,4 @@ const About = props => (
</div>
);
export default translate([], { wait: true })(About);
export default withTranslation()(About);

View file

@ -4,7 +4,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { Bert } from 'meteor/themeteorchef:bert';
import { Meteor } from 'meteor/meteor';
import { T9n } from 'meteor-accounts-t9n';
@ -45,4 +45,4 @@ Auth.propTypes = {
Auth.defaultProps = {
};
export default translate([], { wait: true })(Auth);
export default withTranslation()(Auth);

View file

@ -3,7 +3,7 @@
/* eslint-disable react/jsx-indent */
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Page from '../Page/Page';
const Credits = props => (
@ -16,4 +16,4 @@ const Credits = props => (
</div>
);
export default translate([], { wait: true })(Credits);
export default withTranslation()(Credits);

View file

@ -3,7 +3,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'react-bootstrap';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import DistanceSlider from '/imports/ui/components/DistanceSlider/DistanceSlider';
import SelectionMap, { action } from '/imports/ui/components/SelectionMap/SelectionMap';
import Gkeys from '/imports/startup/client/Gkeys';
@ -129,4 +129,4 @@ FireSubscription.propTypes = {
disableFstBtn: PropTypes.bool.isRequired
};
export default translate([], { wait: true })(FireSubscription);
export default withTranslation()(FireSubscription);

View file

@ -5,7 +5,7 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { withTracker } from 'meteor/react-meteor-data';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { Row, Col, Alert, FormGroup } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
import { Bert } from 'meteor/themeteorchef:bert';
@ -259,7 +259,7 @@ Fire.propTypes = {
Fire.defaultProps = {
};
// export default translate([], { wait: true })(withTracker((props) => {
// export default withTranslation()(withTracker((props) => {
const FireContainer = withTracker(({ match }) => {
const id = match.params.id;
@ -304,4 +304,4 @@ const FireContainer = withTracker(({ match }) => {
})(Fire);
// export default FireContainer;
export default translate([], { wait: true })(FireContainer);
export default withTranslation()(FireContainer);

View file

@ -4,7 +4,7 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import FromNow from '/imports/ui/components/FromNow/FromNow';
class FireStats extends Component {
@ -57,4 +57,4 @@ FireStats.propTypes = {
FireStats.defaultProps = {
};
export default translate([], { wait: true })(FireStats);
export default withTranslation()(FireStats);

View file

@ -10,7 +10,7 @@ import { ReactiveVar } from 'meteor/reactive-var';
import { withTracker } from 'meteor/react-meteor-data';
import { Tracker } from 'meteor/tracker';
import { Helmet } from 'react-helmet-async';
import { Trans, translate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import { Map } from 'react-leaflet';
import Control from 'react-leaflet-control';
import LoadingBar from '/imports/ui/components/Loading/LoadingBar';
@ -386,7 +386,7 @@ FiresMap.propTypes = {
let geoInit = true;
export default translate([], { wait: true })(withTracker(() => {
export default withTranslation()(withTracker(() => {
// const firesType = match.params.type;
// const withIndustries = firesType === 'with-industries';
// console.log(`With industries: ${withIndustries}`);

View file

@ -4,7 +4,7 @@
/* eslint-env jquery */
import 'simple-line-icons/css/simple-line-icons.css';
import React, { Component } from 'react';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { Helmet } from 'react-helmet-async';
import PropTypes from 'prop-types';
// import { Link } from 'react-router-dom';
@ -335,4 +335,4 @@ Index.propTypes = {
t: PropTypes.func.isRequired
};
export default translate([], { wait: true })(Index);
export default withTranslation()(Index);

View file

@ -3,7 +3,7 @@
/* eslint-disable react/jsx-indent */
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { dateParseShortFormat } from '/imports/api/Common/dates';
import Page from '../Page/Page';
@ -17,4 +17,4 @@ const License = props => (
</div>
);
export default translate([], { wait: true })(License);
export default withTranslation()(License);

View file

@ -7,7 +7,7 @@ import { Link } from 'react-router-dom';
import { Meteor } from 'meteor/meteor';
import { Bert } from 'meteor/themeteorchef:bert';
import { Helmet } from 'react-helmet-async';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
import { testId } from '/imports/ui/components/Utils/TestUtils';
import Col from '../../components/Col/Col';
@ -126,4 +126,4 @@ Login.propTypes = {
location: PropTypes.object
};
export default translate([], { wait: true })(Login);
export default withTranslation()(Login);

View file

@ -1,7 +1,7 @@
import React from 'react';
import { Meteor } from 'meteor/meteor';
import Icon from '../../components/Icon/Icon';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { Helmet } from 'react-helmet-async';
import './Logout.scss';
@ -30,4 +30,4 @@ class Logout extends React.Component {
Logout.propTypes = {};
export default translate([], { wait: true })(Logout);
export default withTranslation()(Logout);

View file

@ -2,7 +2,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Trans, translate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import SubscriptionEditor from '../../components/SubscriptionEditor/SubscriptionEditor';
class NewSubscription extends Component {
@ -47,4 +47,4 @@ NewSubscription.propTypes = {
location: PropTypes.object
};
export default translate([], { wait: true })(NewSubscription);
export default withTranslation()(NewSubscription);

View file

@ -1,6 +1,6 @@
import React from 'react';
import { Alert } from 'react-bootstrap';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { Helmet } from 'react-helmet-async';
const NotFound = () => (
@ -16,4 +16,4 @@ const NotFound = () => (
</div>
);
export default translate([], { wait: true })(NotFound);
export default withTranslation()(NotFound);

View file

@ -3,7 +3,7 @@
/* eslint-disable react/jsx-indent */
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { dateParseShortFormat } from '/imports/api/Common/dates';
import Page from '../Page/Page';
@ -17,4 +17,4 @@ const Privacy = props => (
</div>
);
export default translate([], { wait: true })(Privacy);
export default withTranslation()(Privacy);

View file

@ -9,7 +9,7 @@ import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { Bert } from 'meteor/themeteorchef:bert';
import { testId } from '/imports/ui/components/Utils/TestUtils';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
import { withTracker } from 'meteor/react-meteor-data';
import Col from '../../components/Col/Col';
@ -272,7 +272,7 @@ Profile.propTypes = {
i18n: PropTypes.object.isRequired
};
export default translate()(withTracker(() => {
export default withTranslation()(withTracker(() => {
const subscription = Meteor.subscribe('users.editProfile');
return {

View file

@ -8,7 +8,7 @@ import { Bert } from 'meteor/themeteorchef:bert';
import { Helmet } from 'react-helmet-async';
import AccountPageFooter from '../../components/AccountPageFooter/AccountPageFooter';
import validate from '../../../modules/validate';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
class RecoverPassword extends React.Component {
@ -89,4 +89,4 @@ RecoverPassword.propTypes = {
history: PropTypes.object.isRequired
};
export default translate([], { wait: true })(RecoverPassword);
export default withTranslation()(RecoverPassword);

View file

@ -6,7 +6,7 @@ import { Accounts } from 'meteor/accounts-base';
import { Bert } from 'meteor/themeteorchef:bert';
import { Helmet } from 'react-helmet-async';
import validate from '../../../modules/validate';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
class ResetPassword extends React.Component {
@ -104,4 +104,4 @@ ResetPassword.propTypes = {
history: PropTypes.object.isRequired,
};
export default translate([], { wait: true })(ResetPassword);
export default withTranslation()(ResetPassword);

View file

@ -1,7 +1,7 @@
/* eslint-disable import/no-absolute-path */
import React from 'react';
// import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
class Sandbox extends React.Component {
componentDidMount() {
@ -21,4 +21,4 @@ Sandbox.propTypes = {
// history: PropTypes.object.isRequired
};
export default translate([], { wait: true })(Sandbox);
export default withTranslation()(Sandbox);

View file

@ -8,7 +8,7 @@ import { Link } from 'react-router-dom';
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { Bert } from 'meteor/themeteorchef:bert';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
import { Helmet } from 'react-helmet-async';
import { testId } from '/imports/ui/components/Utils/TestUtils';
@ -213,4 +213,4 @@ Signup.propTypes = {
location: PropTypes.object
};
export default translate([], { wait: true })(Signup);
export default withTranslation()(Signup);

View file

@ -4,7 +4,7 @@
import React, { Fragment, Component } from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { withTracker } from 'meteor/react-meteor-data';
import Blaze from 'meteor/gadicc:blaze-react-component';
import { Helmet } from 'react-helmet-async';
@ -44,7 +44,7 @@ Status.propTypes = {
Status.defaultProps = {
};
// export default translate([], { wait: true })(Status);
export default translate([], { wait: true })(withTracker(props => ({
// export default withTranslation()(Status);
export default withTranslation()(withTracker(props => ({
// props.something
}))(Status));

View file

@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
import { Alert } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
import { withTracker } from 'meteor/react-meteor-data';
import { Trans, translate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import { Bert } from 'meteor/themeteorchef:bert';
import { Helmet } from 'react-helmet-async';
import UserSubsToFiresCollection from '/imports/api/Subscriptions/Subscriptions';
@ -127,7 +127,7 @@ Subscriptions.propTypes = {
location: PropTypes.object
};
export default translate([], { wait: true })(withTracker(() => {
export default withTranslation()(withTracker(() => {
const subscription = Meteor.subscribe('mysubscriptions');
// console.log(UserSubsToFiresCollection.find().fetch());
return {

View file

@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
import { Button, ButtonGroup, Row, Col } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
import { withTracker } from 'meteor/react-meteor-data';
import { Trans, translate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import { Map } from 'react-leaflet';
import { Helmet } from 'react-helmet-async';
import L from 'leaflet';
@ -165,7 +165,7 @@ SubscriptionsMap.propTypes = {
t: PropTypes.func.isRequired
};
export default translate([], { wait: true })(withTracker(() => {
export default withTranslation()(withTracker(() => {
const settingsSubs = Meteor.subscribe('settings');
const userSubs = SiteSettings.findOne({ name: 'subs-public-union' });
const userSubsBounds = SiteSettings.findOne({ name: 'subs-public-union-bounds' });

View file

@ -3,7 +3,7 @@
/* eslint-disable react/jsx-indent */
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { dateParseShortFormat } from '/imports/api/Common/dates';
import Page from '../Page/Page';
@ -17,4 +17,4 @@ const Terms = props => (
</div>
);
export default translate([], { wait: true })(Terms);
export default withTranslation()(Terms);

View file

@ -5,7 +5,7 @@ import { Meteor } from 'meteor/meteor';
import { Helmet } from 'react-helmet-async';
import { Accounts } from 'meteor/accounts-base';
import { Bert } from 'meteor/themeteorchef:bert';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
class VerifyEmail extends React.Component {
@ -48,4 +48,4 @@ VerifyEmail.propTypes = {
history: PropTypes.object.isRequired
};
export default translate([], { wait: true })(VerifyEmail);
export default withTranslation()(VerifyEmail);

543
package-lock.json generated
View file

@ -24,11 +24,10 @@
"handlebars": "^4.0.11",
"history": "^4.7.2",
"html5-device-mockups": "^3.2.0",
"i18next": "^10.5.0",
"i18next-browser-languagedetector": "^2.1.0",
"i18next-localstorage-cache": "^1.1.1",
"i18next-sync-fs-backend": "^1.0.0",
"i18next-xhr-backend": "^1.5.1",
"i18next": "^23.16.8",
"i18next-browser-languagedetector": "^8.2.1",
"i18next-fs-backend": "^2.6.6",
"i18next-http-backend": "^2.7.3",
"immutability-helper": "^2.5.1",
"indexof": "0.0.1",
"iron": "^5.0.4",
@ -65,7 +64,7 @@
"react-confirm": "^0.1.16",
"react-dom": "^18.3.1",
"react-helmet-async": "^2.0.5",
"react-i18next": "^7.4.0",
"react-i18next": "^14.1.3",
"react-leaflet": "^1.8.0",
"react-leaflet-control": "^1.4.0",
"react-leaflet-fullscreen": "0.0.6",
@ -1968,15 +1967,6 @@
"sprintf-js": "~1.0.2"
}
},
"node_modules/argv": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
"integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"engines": {
"node": ">=0.6.10"
}
},
"node_modules/aria-query": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-0.7.0.tgz",
@ -4227,284 +4217,6 @@
"node": ">= 0.12.0"
}
},
"node_modules/codecov": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/codecov/-/codecov-2.3.1.tgz",
"integrity": "sha1-fdqUXNWKH2CBAltbA+4Bou8g+G4=",
"dependencies": {
"argv": "0.0.2",
"request": "2.77.0",
"urlgrey": "0.4.4"
},
"bin": {
"codecov": "bin/codecov"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/codecov/node_modules/assert-plus": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
"integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
"engines": {
"node": ">=0.8"
}
},
"node_modules/codecov/node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"node_modules/codecov/node_modules/aws-sign2": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
"integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
"engines": {
"node": "*"
}
},
"node_modules/codecov/node_modules/aws4": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
},
"node_modules/codecov/node_modules/boom": {
"version": "2.10.1",
"resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
"integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
"deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).",
"dependencies": {
"hoek": "2.x.x"
},
"engines": {
"node": ">=0.10.40"
}
},
"node_modules/codecov/node_modules/caseless": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
"integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c="
},
"node_modules/codecov/node_modules/combined-stream": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/codecov/node_modules/cryptiles": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
"integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
"deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).",
"dependencies": {
"boom": "2.x.x"
},
"engines": {
"node": ">=0.10.40"
}
},
"node_modules/codecov/node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/codecov/node_modules/extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
},
"node_modules/codecov/node_modules/forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
"engines": {
"node": "*"
}
},
"node_modules/codecov/node_modules/form-data": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
"integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.5",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 0.12"
}
},
"node_modules/codecov/node_modules/har-validator": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
"integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
"deprecated": "this library is no longer supported",
"dependencies": {
"chalk": "^1.1.1",
"commander": "^2.9.0",
"is-my-json-valid": "^2.12.4",
"pinkie-promise": "^2.0.0"
},
"bin": {
"har-validator": "bin/har-validator"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/codecov/node_modules/hawk": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
"integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
"deprecated": "This module moved to @hapi/hawk. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.",
"dependencies": {
"boom": "2.x.x",
"cryptiles": "2.x.x",
"hoek": "2.x.x",
"sntp": "1.x.x"
},
"engines": {
"node": ">=0.10.32"
}
},
"node_modules/codecov/node_modules/hoek": {
"version": "2.16.3",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
"integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
"deprecated": "This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).",
"engines": {
"node": ">=0.10.40"
}
},
"node_modules/codecov/node_modules/http-signature": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
"integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
"dependencies": {
"assert-plus": "^0.2.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
},
"engines": {
"node": ">=0.8",
"npm": ">=1.3.7"
}
},
"node_modules/codecov/node_modules/is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"node_modules/codecov/node_modules/isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"node_modules/codecov/node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"node_modules/codecov/node_modules/oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
"engines": {
"node": "*"
}
},
"node_modules/codecov/node_modules/pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/codecov/node_modules/pinkie-promise": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
"dependencies": {
"pinkie": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/codecov/node_modules/qs": {
"version": "6.3.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
"integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
"engines": {
"node": ">=0.6"
}
},
"node_modules/codecov/node_modules/request": {
"version": "2.77.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.77.0.tgz",
"integrity": "sha1-KwDYIDDt7cyXCJ/6XYgQqcKqMUs=",
"deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
"dependencies": {
"aws-sign2": "~0.6.0",
"aws4": "^1.2.1",
"caseless": "~0.11.0",
"combined-stream": "~1.0.5",
"extend": "~3.0.0",
"forever-agent": "~0.6.1",
"form-data": "~2.1.1",
"har-validator": "~2.0.6",
"hawk": "~3.1.3",
"http-signature": "~1.1.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.7",
"node-uuid": "~1.4.7",
"oauth-sign": "~0.8.1",
"qs": "~6.3.0",
"stringstream": "~0.0.4",
"tough-cookie": "~2.3.0",
"tunnel-agent": "~0.4.1"
},
"engines": {
"node": ">= 4"
}
},
"node_modules/codecov/node_modules/sntp": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
"integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
"deprecated": "This module moved to @hapi/sntp. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.",
"dependencies": {
"hoek": "2.x.x"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/codecov/node_modules/stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
},
"node_modules/codecov/node_modules/tunnel-agent": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
"integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
"engines": {
"node": "*"
}
},
"node_modules/color-convert": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
@ -4785,6 +4497,51 @@
"node": "*"
}
},
"node_modules/cross-fetch": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
"integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==",
"license": "MIT",
"dependencies": {
"node-fetch": "^2.6.12"
}
},
"node_modules/cross-fetch/node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/cross-fetch/node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"license": "BSD-2-Clause"
},
"node_modules/cross-fetch/node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/cross-spawn": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
@ -8135,19 +7892,6 @@
"node": ">=0.10.0"
}
},
"node_modules/generate-function": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
"integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ="
},
"node_modules/generate-object-property": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
"integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
"dependencies": {
"is-property": "^1.0.0"
}
},
"node_modules/get-caller-file": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
@ -8395,11 +8139,6 @@
"node": ">=4.0.0"
}
},
"node_modules/hoist-non-react-statics": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz",
"integrity": "sha1-ND24TGAYxlB3iJgkATWhQg7iLOA="
},
"node_modules/home-or-tmp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
@ -8445,12 +8184,13 @@
"whatwg-encoding": "^1.0.1"
}
},
"node_modules/html-parse-stringify2": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz",
"integrity": "sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=",
"node_modules/html-parse-stringify": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
"license": "MIT",
"dependencies": {
"void-elements": "^2.0.1"
"void-elements": "3.1.0"
}
},
"node_modules/html5-device-mockups": {
@ -8496,81 +8236,52 @@
}
},
"node_modules/i18next": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-10.5.0.tgz",
"integrity": "sha512-soHpHN/J8fpkt6z3mEsvO5Uf4huBLk1gYpwK7GwRJOBCJz6Zq4LgMjJ5pr8Lz0+lVwyzKW3zun7+C4pS4LZJ6Q=="
"version": "23.16.8",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.8.tgz",
"integrity": "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==",
"funding": [
{
"type": "individual",
"url": "https://locize.com"
},
{
"type": "individual",
"url": "https://locize.com/i18next.html"
},
{
"type": "individual",
"url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
}
],
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.23.2"
}
},
"node_modules/i18next-browser-languagedetector": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-2.1.0.tgz",
"integrity": "sha1-Gw4XsJUH+E56H6dhU5oHVE+SoN8="
},
"node_modules/i18next-localstorage-cache": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/i18next-localstorage-cache/-/i18next-localstorage-cache-1.1.1.tgz",
"integrity": "sha1-V1JWzDXoyy2IFI91R2b90tJLsbc="
},
"node_modules/i18next-sync-fs-backend": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/i18next-sync-fs-backend/-/i18next-sync-fs-backend-1.0.0.tgz",
"integrity": "sha512-fymETW6cOnpqf2tm14/CgpPn881SJYACD98lwvsflHKFPLEKm6S0e6atGCdQ37beizsiZJuGF02Bjx7yS/DAzg==",
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.1.tgz",
"integrity": "sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw==",
"license": "MIT",
"dependencies": {
"codecov": "^2.2.0",
"js-yaml": "3.5.4",
"json5": "0.5.0"
"@babel/runtime": "^7.23.2"
}
},
"node_modules/i18next-sync-fs-backend/node_modules/argparse": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
"integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
"dependencies": {
"sprintf-js": "~1.0.2"
}
"node_modules/i18next-fs-backend": {
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/i18next-fs-backend/-/i18next-fs-backend-2.6.6.tgz",
"integrity": "sha512-mYGu6Nt8RIp3X/U8Y+Gej1wo5xmYWmGKLqBGMCC2OCAou5rW5epeHgHmVcw20mJs9Z9+DAPHIxQPNCgFyPRMeg==",
"license": "MIT"
},
"node_modules/i18next-sync-fs-backend/node_modules/esprima": {
"node_modules/i18next-http-backend": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/i18next-sync-fs-backend/node_modules/js-yaml": {
"version": "3.5.4",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.4.tgz",
"integrity": "sha1-9k8W3NeL65zoNhBo5zPr5HsHkXk=",
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.7.3.tgz",
"integrity": "sha512-FgZxrXdRA5u44xfYsJlEBL4/KH3f2IluBpgV/7riW0YW2VEyM8FzVt2XHAOi6id0Ppj7vZvCZVpp5LrGXnc8Ig==",
"license": "MIT",
"dependencies": {
"argparse": "^1.0.2",
"esprima": "^2.6.0"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
"cross-fetch": "4.0.0"
}
},
"node_modules/i18next-sync-fs-backend/node_modules/json5": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.5.0.tgz",
"integrity": "sha1-myBxWwJsvjd4/Xae3M2CLYMypbI=",
"bin": {
"json5": "lib/cli.js"
}
},
"node_modules/i18next-sync-fs-backend/node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"node_modules/i18next-xhr-backend": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/i18next-xhr-backend/-/i18next-xhr-backend-1.5.1.tgz",
"integrity": "sha512-9OLdC/9YxDvTFcgsH5t2BHCODHEotHCa6h7Ly0EUlUC7Y2GS09UeoHOGj3gWKQ3HCqXz8NlH4gOrK3NNc9vPuw==",
"deprecated": "replaced by i18next-http-backend"
},
"node_modules/iconv-lite": {
"version": "0.4.17",
"integrity": "sha1-T9qjs4rLwsAxsEXQ7c3+HsqxjI0=",
@ -8980,18 +8691,6 @@
"node": ">=0.10.0"
}
},
"node_modules/is-my-json-valid": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
"integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
"deprecated": "catastrophic backtracking in regexes could potentially lead to REDOS attack, upgrade to 2.17.2 as soon as possible",
"dependencies": {
"generate-function": "^2.0.0",
"generate-object-property": "^1.1.0",
"jsonpointer": "^4.0.0",
"xtend": "^4.0.0"
}
},
"node_modules/is-number": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
@ -9061,11 +8760,6 @@
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
"dev": true
},
"node_modules/is-property": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
},
"node_modules/is-regex": {
"version": "1.0.4",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
@ -11154,14 +10848,6 @@
"debug": "^2.1.3"
}
},
"node_modules/jsonpointer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
"integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@ -13339,15 +13025,6 @@
"which": "bin/which"
}
},
"node_modules/node-uuid": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
"integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=",
"deprecated": "Use uuid module instead",
"bin": {
"uuid": "bin/uuid"
}
},
"node_modules/nodemailer": {
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.1.tgz",
@ -19673,17 +19350,25 @@
}
},
"node_modules/react-i18next": {
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-7.4.0.tgz",
"integrity": "sha1-B6M25J/I8lmdCBNtcxNOPcSDC0k=",
"version": "14.1.3",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.3.tgz",
"integrity": "sha512-wZnpfunU6UIAiJ+bxwOiTmBOAaB14ha97MjOEnLGac2RJ+h/maIYXZuTHlmyqQVX1UVHmU1YDTQ5vxLmwfXTjw==",
"license": "MIT",
"dependencies": {
"hoist-non-react-statics": "2.3.1",
"html-parse-stringify2": "2.0.1",
"prop-types": "^15.6.0"
"@babel/runtime": "^7.23.9",
"html-parse-stringify": "^3.0.1"
},
"peerDependencies": {
"i18next": ">= 6.0.1",
"react": ">= 15.0.0"
"i18next": ">= 23.2.3",
"react": ">= 16.8.0"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/react-is": {
@ -21497,11 +21182,6 @@
"react": ">=0.11.0"
}
},
"node_modules/urlgrey": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz",
"integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8="
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
@ -21544,9 +21224,10 @@
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"node_modules/void-elements": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
"integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}

View file

@ -24,11 +24,10 @@
"handlebars": "^4.0.11",
"history": "^4.7.2",
"html5-device-mockups": "^3.2.0",
"i18next": "^10.5.0",
"i18next-browser-languagedetector": "^2.1.0",
"i18next-localstorage-cache": "^1.1.1",
"i18next-sync-fs-backend": "^1.0.0",
"i18next-xhr-backend": "^1.5.1",
"i18next": "^23.16.8",
"i18next-browser-languagedetector": "^8.2.1",
"i18next-fs-backend": "^2.6.6",
"i18next-http-backend": "^2.7.3",
"immutability-helper": "^2.5.1",
"indexof": "0.0.1",
"iron": "^5.0.4",
@ -65,7 +64,7 @@
"react-confirm": "^0.1.16",
"react-dom": "^18.3.1",
"react-helmet-async": "^2.0.5",
"react-i18next": "^7.4.0",
"react-i18next": "^14.1.3",
"react-leaflet": "^1.8.0",
"react-leaflet-control": "^1.4.0",
"react-leaflet-fullscreen": "0.0.6",