Répare les liens interne dans la documentation
Les liens dans le markdown ne prenaient pas en compte le `basename` configuré via react-router/history. Utilisation de `react-markdown` au lieu de `marked` qui s'inter-opère mieux avec notre UI.pull/607/head
parent
7ea44a7b46
commit
db90552f6a
|
@ -29,7 +29,6 @@
|
|||
"i18next": "^14.1.1",
|
||||
"iframe-resizer": "^3.6.2",
|
||||
"js-yaml": "^3.13.1",
|
||||
"marked": "^0.3.17",
|
||||
"nearley": "^2.16.0",
|
||||
"ramda": "^0.25.0",
|
||||
"raven-for-redux": "^1.3.1",
|
||||
|
@ -42,6 +41,7 @@
|
|||
"react-helmet": "6.0.0-beta",
|
||||
"react-highlight-words": "^0.11.0",
|
||||
"react-i18next": "^10.0.1",
|
||||
"react-markdown": "^4.1.0",
|
||||
"react-number-format": "^4.0.8",
|
||||
"react-redux": "^7.0.3",
|
||||
"react-router": "^5.0.1",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import marked from 'Engine/marked'
|
||||
import { Markdown } from 'Components/utils/markdown'
|
||||
import { path } from 'ramda'
|
||||
import React, { Component } from 'react'
|
||||
import './Dictionary.css'
|
||||
|
@ -18,9 +18,6 @@ export let AttachDictionary = dictionary => Decorated =>
|
|||
if (!term) return null
|
||||
this.setState({ explanation, term })
|
||||
}
|
||||
renderExplanationMarkdown(explanation, term) {
|
||||
return marked(`### Mécanisme : ${term}\n\n${explanation}`)
|
||||
}
|
||||
render() {
|
||||
let { explanation, term } = this.state
|
||||
return (
|
||||
|
@ -29,11 +26,11 @@ export let AttachDictionary = dictionary => Decorated =>
|
|||
{explanation && (
|
||||
<Overlay
|
||||
onClose={() => this.setState({ term: null, explanation: null })}>
|
||||
<div
|
||||
id="dictionaryPanel"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: this.renderExplanationMarkdown(explanation, term)
|
||||
}}
|
||||
<div id="dictionaryPanel">
|
||||
<Markdown
|
||||
source={`### Mécanisme : ${term}\n\n${explanation}`}
|
||||
/>
|
||||
</div>
|
||||
/>
|
||||
</Overlay>
|
||||
)}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { goToQuestion, hideControl } from 'Actions/actions'
|
||||
import { makeJsx } from 'Engine/evaluation'
|
||||
import { createMarkdownDiv } from 'Engine/marked'
|
||||
import { compose } from 'ramda'
|
||||
import React from 'react'
|
||||
import emoji from 'react-easy-emoji'
|
||||
|
@ -9,6 +8,7 @@ import { connect } from 'react-redux'
|
|||
import { analysisWithDefaultsSelector } from 'Selectors/analyseSelectors'
|
||||
import animate from 'Ui/animate'
|
||||
import './Controls.css'
|
||||
import { Markdown } from './utils/markdown'
|
||||
import withColours from './utils/withColours'
|
||||
|
||||
function Controls({
|
||||
|
@ -50,7 +50,7 @@ function Controls({
|
|||
{emoji(level == 'avertissement' ? '⚠️' : 'ℹ️')}
|
||||
<div className="controlText ui__ card">
|
||||
{message ? (
|
||||
createMarkdownDiv(message)
|
||||
<Markdown source={message} />
|
||||
) : (
|
||||
<span id="controlExplanation">{makeJsx(evaluated)}</span>
|
||||
)}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { EXPLAIN_VARIABLE } from 'Actions/actions'
|
||||
import { Markdown } from 'Components/utils/markdown'
|
||||
import withColours from 'Components/utils/withColours'
|
||||
import marked from 'Engine/marked'
|
||||
import { findRuleByDottedName } from 'Engine/rules'
|
||||
import { compose } from 'ramda'
|
||||
import React, { Component } from 'react'
|
||||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { flatRulesSelector } from 'Selectors/analyseSelectors'
|
||||
import References from '../rule/References'
|
||||
|
@ -20,43 +20,32 @@ export default compose(
|
|||
})
|
||||
),
|
||||
withColours
|
||||
)(
|
||||
class Aide extends Component {
|
||||
renderExplanationMarkdown(explanation, term) {
|
||||
return marked(`# ${term} \n\n${explanation}`)
|
||||
}
|
||||
render() {
|
||||
let { flatRules, explained, stopExplaining, colours } = this.props
|
||||
)(function Aide({ flatRules, explained, stopExplaining, colours }) {
|
||||
if (!explained) return <section id="helpWrapper" />
|
||||
|
||||
if (!explained) return <section id="helpWrapper" />
|
||||
let rule = findRuleByDottedName(flatRules, explained),
|
||||
text = rule.description,
|
||||
refs = rule.références
|
||||
|
||||
let rule = findRuleByDottedName(flatRules, explained),
|
||||
text = rule.description,
|
||||
refs = rule.références
|
||||
|
||||
return (
|
||||
<div id="helpWrapper" className="active">
|
||||
<section id="help">
|
||||
<button
|
||||
id="closeHelp"
|
||||
onClick={stopExplaining}
|
||||
style={{ color: colours.colour }}>
|
||||
✖️
|
||||
</button>
|
||||
<p
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: this.renderExplanationMarkdown(text, rule.title)
|
||||
}}
|
||||
/>
|
||||
{refs && (
|
||||
<div>
|
||||
<p>Pour en savoir plus: </p>
|
||||
<References refs={refs} />
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
return (
|
||||
<div id="helpWrapper" className="active">
|
||||
<section id="help">
|
||||
<button
|
||||
id="closeHelp"
|
||||
onClick={stopExplaining}
|
||||
style={{ color: colours.colour }}>
|
||||
✖️
|
||||
</button>
|
||||
<p>
|
||||
<Markdown source={`# ${rule.title} \n\n${text}`} />
|
||||
</p>
|
||||
{refs && (
|
||||
<div>
|
||||
<p>Pour en savoir plus: </p>
|
||||
<References refs={refs} />
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
|
|
@ -5,6 +5,7 @@ import React, { Component } from 'react'
|
|||
import { withTranslation } from 'react-i18next'
|
||||
import { connect } from 'react-redux'
|
||||
import { change, Field } from 'redux-form'
|
||||
import { Markdown } from '../utils/markdown'
|
||||
|
||||
/*
|
||||
This higher order component wraps "Form" components (e.g. Question.js), that represent user inputs,
|
||||
|
@ -37,7 +38,7 @@ export var FormDecorator = formType => RenderField =>
|
|||
render() {
|
||||
let {
|
||||
stepAction,
|
||||
subquestion,
|
||||
subquestionMarkdown,
|
||||
valueType,
|
||||
defaultValue,
|
||||
fieldName,
|
||||
|
@ -61,10 +62,9 @@ export var FormDecorator = formType => RenderField =>
|
|||
{this.props.question}{' '}
|
||||
{!inversion && <Explicable dottedName={fieldName} />}
|
||||
</h3>
|
||||
<div
|
||||
className="step-subquestion"
|
||||
dangerouslySetInnerHTML={{ __html: subquestion }}
|
||||
/>
|
||||
<div className="step-subquestion">
|
||||
<Markdown source={subquestionMarkdown} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import PeriodSwitch from 'Components/PeriodSwitch'
|
||||
import withColours from 'Components/utils/withColours'
|
||||
import { createMarkdownDiv } from 'Engine/marked'
|
||||
import { path } from 'ramda'
|
||||
import React from 'react'
|
||||
import emoji from 'react-easy-emoji'
|
||||
import { Trans } from 'react-i18next'
|
||||
import { capitalise0 } from '../../utils'
|
||||
import { Markdown } from '../utils/markdown'
|
||||
import Destinataire from './Destinataire'
|
||||
import './Header.css'
|
||||
import Namespace from './Namespace'
|
||||
|
@ -38,7 +38,7 @@ let RuleHeader = withColours(
|
|||
</header>
|
||||
<div id="ruleHeader__content">
|
||||
<div id="ruleHeader__description">
|
||||
{createMarkdownDiv(description || question)}
|
||||
<Markdown source={description || question} />
|
||||
</div>
|
||||
{(type || flatRule['période']) && (
|
||||
<div id="ruleHeader__infobox">
|
||||
|
|
|
@ -2,8 +2,8 @@ import { T } from 'Components'
|
|||
import withColours from 'Components/utils/withColours'
|
||||
import withLanguage from 'Components/utils/withLanguage'
|
||||
import withSitePaths from 'Components/utils/withSitePaths'
|
||||
import Value from 'Components/Value'
|
||||
import knownMecanisms from 'Engine/known-mecanisms.yaml'
|
||||
import { createMarkdownDiv } from 'Engine/marked'
|
||||
import {
|
||||
encodeRuleName,
|
||||
findRuleByDottedName,
|
||||
|
@ -24,12 +24,12 @@ import {
|
|||
} from 'Selectors/analyseSelectors'
|
||||
import Animate from 'Ui/animate'
|
||||
import { AttachDictionary } from '../AttachDictionary'
|
||||
import { Markdown } from '../utils/markdown'
|
||||
import Algorithm from './Algorithm'
|
||||
import Examples from './Examples'
|
||||
import RuleHeader from './Header'
|
||||
import References from './References'
|
||||
import './Rule.css'
|
||||
import Value from 'Components/Value'
|
||||
|
||||
let LazySource = React.lazy(() => import('./RuleSource'))
|
||||
|
||||
|
@ -145,7 +145,7 @@ export default compose(
|
|||
{flatRule.note && (
|
||||
<section id="notes">
|
||||
<h3>Note: </h3>
|
||||
{createMarkdownDiv(flatRule.note)}
|
||||
<Markdown source={flatRule.note} />
|
||||
</section>
|
||||
)}
|
||||
<Examples
|
||||
|
|
|
@ -22,6 +22,14 @@ button {
|
|||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
background: var(--lighterColour);
|
||||
border-radius: 0.6em;
|
||||
padding: 1.2em 1em 0.4em;
|
||||
margin: 0.6em;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.ui__.answer-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -83,5 +91,3 @@ span.ui__.enumeration:not(:last-of-type)::after {
|
|||
margin: 0 0.3rem;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
import { createContext } from 'react'
|
||||
export const IsEmbeddedContext = createContext(false)
|
|
@ -0,0 +1,29 @@
|
|||
import React from 'react'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
function LinkRenderer({ href, children }) {
|
||||
if (href.startsWith('http')) {
|
||||
return (
|
||||
<a target="_blank" href={href}>
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
} else {
|
||||
return <Link to={href}>{children}</Link>
|
||||
}
|
||||
}
|
||||
|
||||
export const Markdown = ({
|
||||
source,
|
||||
className = '',
|
||||
renderers = {},
|
||||
otherProps
|
||||
}) => (
|
||||
<ReactMarkdown
|
||||
source={source}
|
||||
className={`markdown ${className}`}
|
||||
renderers={{ ...renderers, link: LinkRenderer }}
|
||||
{...otherProps}
|
||||
/>
|
||||
)
|
|
@ -1,27 +0,0 @@
|
|||
import marked from 'marked'
|
||||
import React from 'react'
|
||||
|
||||
let customMarked = new marked.Renderer()
|
||||
customMarked.link = (href, title, text) =>
|
||||
`<a target="_blank" href="${href}" title="${title}">${text}</a>`
|
||||
marked.setOptions({
|
||||
renderer: customMarked
|
||||
})
|
||||
|
||||
export let createMarkdownDiv = markdown => (
|
||||
<div
|
||||
className="markdown"
|
||||
css={`
|
||||
blockquote {
|
||||
background: var(--lighterColour);
|
||||
border-radius: 0.6em;
|
||||
padding: 1.2em 1em 0.4em;
|
||||
margin: 0.6em;
|
||||
color: #333;
|
||||
}
|
||||
`}
|
||||
dangerouslySetInnerHTML={{ __html: marked(markdown || '') }}
|
||||
/>
|
||||
)
|
||||
|
||||
export default marked
|
|
@ -1,264 +1,263 @@
|
|||
import { parseUnit } from "Engine/units";
|
||||
import {
|
||||
assoc,
|
||||
chain,
|
||||
dropLast,
|
||||
find,
|
||||
fromPairs,
|
||||
has,
|
||||
is,
|
||||
isNil,
|
||||
join,
|
||||
last,
|
||||
map,
|
||||
path,
|
||||
pipe,
|
||||
propEq,
|
||||
props,
|
||||
range,
|
||||
reduce,
|
||||
reduced,
|
||||
reject,
|
||||
split,
|
||||
take,
|
||||
toPairs,
|
||||
trim,
|
||||
when
|
||||
} from 'ramda'
|
||||
import rawRules from 'Règles/base.yaml'
|
||||
import translations from 'Règles/externalized.yaml'
|
||||
assoc,
|
||||
chain,
|
||||
dropLast,
|
||||
find,
|
||||
fromPairs,
|
||||
has,
|
||||
is,
|
||||
isNil,
|
||||
join,
|
||||
last,
|
||||
map,
|
||||
path,
|
||||
pipe,
|
||||
propEq,
|
||||
props,
|
||||
range,
|
||||
reduce,
|
||||
reduced,
|
||||
reject,
|
||||
split,
|
||||
take,
|
||||
toPairs,
|
||||
trim,
|
||||
when
|
||||
} from "ramda";
|
||||
import rawRules from "Règles/base.yaml";
|
||||
import translations from "Règles/externalized.yaml";
|
||||
// TODO - should be in UI, not engine
|
||||
import { capitalise0, coerceArray } from '../utils'
|
||||
import marked from './marked'
|
||||
import possibleVariableTypes from './possibleVariableTypes.yaml'
|
||||
import { parseUnit } from 'Engine/units'
|
||||
import { capitalise0, coerceArray } from "../utils";
|
||||
import possibleVariableTypes from "./possibleVariableTypes.yaml";
|
||||
|
||||
/***********************************
|
||||
Functions working on one rule */
|
||||
|
||||
export let enrichRule = rule => {
|
||||
try {
|
||||
let unit = rule.unité && parseUnit(rule.unité)
|
||||
return {
|
||||
...rule,
|
||||
type: possibleVariableTypes.find(t => has(t, rule) || rule.type === t),
|
||||
name: rule['nom'],
|
||||
title: capitalise0(rule['titre'] || rule['nom']),
|
||||
ns: rule['espace'],
|
||||
dottedName: buildDottedName(rule),
|
||||
subquestion: rule['sous-question'] && marked(rule['sous-question']),
|
||||
defaultValue: rule['par défaut'],
|
||||
examples: rule['exemples'],
|
||||
icons: rule['icônes'],
|
||||
summary: rule['résumé'],
|
||||
unit
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
throw new Error('Problem enriching ' + JSON.stringify(rule))
|
||||
}
|
||||
}
|
||||
try {
|
||||
let unit = rule.unité && parseUnit(rule.unité);
|
||||
return {
|
||||
...rule,
|
||||
type: possibleVariableTypes.find(t => has(t, rule) || rule.type === t),
|
||||
name: rule["nom"],
|
||||
title: capitalise0(rule["titre"] || rule["nom"]),
|
||||
ns: rule["espace"],
|
||||
dottedName: buildDottedName(rule),
|
||||
subquestionMarkdown: rule["sous-question"],
|
||||
defaultValue: rule["par défaut"],
|
||||
examples: rule["exemples"],
|
||||
icons: rule["icônes"],
|
||||
summary: rule["résumé"],
|
||||
unit
|
||||
};
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
throw new Error("Problem enriching " + JSON.stringify(rule));
|
||||
}
|
||||
};
|
||||
|
||||
export let buildDottedName = rule =>
|
||||
rule['espace'] ? [rule['espace'], rule['nom']].join(' . ') : rule['nom']
|
||||
rule["espace"] ? [rule["espace"], rule["nom"]].join(" . ") : rule["nom"];
|
||||
|
||||
// les variables dans les tests peuvent être exprimées relativement à l'espace de nom de la règle,
|
||||
// comme dans sa formule
|
||||
export let disambiguateExampleSituation = (rules, rule) =>
|
||||
pipe(
|
||||
toPairs,
|
||||
map(([k, v]) => [disambiguateRuleReference(rules, rule, k), v]),
|
||||
fromPairs
|
||||
)
|
||||
pipe(
|
||||
toPairs,
|
||||
map(([k, v]) => [disambiguateRuleReference(rules, rule, k), v]),
|
||||
fromPairs
|
||||
);
|
||||
|
||||
export let hasKnownRuleType = rule => rule && enrichRule(rule).type
|
||||
export let hasKnownRuleType = rule => rule && enrichRule(rule).type;
|
||||
|
||||
export let splitName = split(' . '),
|
||||
joinName = join(' . ')
|
||||
export let splitName = split(" . "),
|
||||
joinName = join(" . ");
|
||||
|
||||
export let parentName = pipe(
|
||||
splitName,
|
||||
dropLast(1),
|
||||
joinName
|
||||
)
|
||||
splitName,
|
||||
dropLast(1),
|
||||
joinName
|
||||
);
|
||||
export let nameLeaf = pipe(
|
||||
splitName,
|
||||
last
|
||||
)
|
||||
splitName,
|
||||
last
|
||||
);
|
||||
|
||||
export let encodeRuleName = name =>
|
||||
encodeURI(name.replace(/\s\.\s/g, '/').replace(/\s/g, '-'))
|
||||
encodeURI(name.replace(/\s\.\s/g, "/").replace(/\s/g, "-"));
|
||||
export let decodeRuleName = name =>
|
||||
decodeURI(name.replace(/\//g, ' . ').replace(/-/g, ' '))
|
||||
decodeURI(name.replace(/\//g, " . ").replace(/-/g, " "));
|
||||
|
||||
export let ruleParents = dottedName => {
|
||||
let fragments = splitName(dottedName) // dottedName ex. [CDD . événements . rupture]
|
||||
return range(1, fragments.length)
|
||||
.map(nbEl => take(nbEl)(fragments))
|
||||
.reverse() // -> [ [CDD . événements . rupture], [CDD . événements], [CDD] ]
|
||||
}
|
||||
let fragments = splitName(dottedName); // dottedName ex. [CDD . événements . rupture]
|
||||
return range(1, fragments.length)
|
||||
.map(nbEl => take(nbEl)(fragments))
|
||||
.reverse(); // -> [ [CDD . événements . rupture], [CDD . événements], [CDD] ]
|
||||
};
|
||||
/* Les variables peuvent être exprimées dans la formule d'une règle relativement à son propre espace de nom, pour une plus grande lisibilité. Cette fonction résoud cette ambiguité.
|
||||
*/
|
||||
export let disambiguateRuleReference = (
|
||||
allRules,
|
||||
{ dottedName, name },
|
||||
partialName
|
||||
allRules,
|
||||
{ dottedName, name },
|
||||
partialName
|
||||
) => {
|
||||
let pathPossibilities = [
|
||||
[], // the top level namespace
|
||||
...ruleParents(dottedName), // the parents namespace
|
||||
splitName(dottedName) // the rule's own namespace
|
||||
],
|
||||
found = reduce(
|
||||
(res, path) =>
|
||||
when(is(Object), reduced)(
|
||||
do {
|
||||
let dottedNameToCheck = [...path, partialName].join(' . ')
|
||||
findRuleByDottedName(allRules, dottedNameToCheck)
|
||||
}
|
||||
),
|
||||
null,
|
||||
pathPossibilities
|
||||
)
|
||||
let pathPossibilities = [
|
||||
[], // the top level namespace
|
||||
...ruleParents(dottedName), // the parents namespace
|
||||
splitName(dottedName) // the rule's own namespace
|
||||
],
|
||||
found = reduce(
|
||||
(res, path) =>
|
||||
when(is(Object), reduced)(
|
||||
do {
|
||||
let dottedNameToCheck = [...path, partialName].join(" . ");
|
||||
findRuleByDottedName(allRules, dottedNameToCheck);
|
||||
}
|
||||
),
|
||||
null,
|
||||
pathPossibilities
|
||||
);
|
||||
|
||||
return (
|
||||
(found && found.dottedName) ||
|
||||
do {
|
||||
throw new Error(
|
||||
`OUUUUPS la référence '${partialName}' dans la règle '${name}' est introuvable dans la base`
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
return (
|
||||
(found && found.dottedName) ||
|
||||
do {
|
||||
throw new Error(
|
||||
`OUUUUPS la référence '${partialName}' dans la règle '${name}' est introuvable dans la base`
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export let collectDefaults = pipe(
|
||||
map(props(['dottedName', 'defaultValue'])),
|
||||
reject(([, v]) => v === undefined),
|
||||
fromPairs
|
||||
)
|
||||
map(props(["dottedName", "defaultValue"])),
|
||||
reject(([, v]) => v === undefined),
|
||||
fromPairs
|
||||
);
|
||||
|
||||
/****************************************
|
||||
Méthodes de recherche d'une règle */
|
||||
|
||||
export let findRuleByName = (allRules, query) =>
|
||||
(Array.isArray(allRules) ? allRules : Object.values(allRules)).find(
|
||||
({ name }) => name === query
|
||||
)
|
||||
(Array.isArray(allRules) ? allRules : Object.values(allRules)).find(
|
||||
({ name }) => name === query
|
||||
);
|
||||
|
||||
export let findRulesByName = (allRules, query) =>
|
||||
(Array.isArray(allRules) ? allRules : Object.values(allRules)).filter(
|
||||
({ name }) => name === query
|
||||
)
|
||||
(Array.isArray(allRules) ? allRules : Object.values(allRules)).filter(
|
||||
({ name }) => name === query
|
||||
);
|
||||
|
||||
export let findRuleByDottedName = (allRules, dottedName) =>
|
||||
Array.isArray(allRules)
|
||||
? allRules.find(rule => rule.dottedName == dottedName)
|
||||
: allRules[dottedName]
|
||||
Array.isArray(allRules)
|
||||
? allRules.find(rule => rule.dottedName == dottedName)
|
||||
: allRules[dottedName];
|
||||
|
||||
export let findRule = (rules, nameOrDottedName) =>
|
||||
nameOrDottedName.includes(' . ')
|
||||
? findRuleByDottedName(rules, nameOrDottedName)
|
||||
: findRuleByName(rules, nameOrDottedName)
|
||||
nameOrDottedName.includes(" . ")
|
||||
? findRuleByDottedName(rules, nameOrDottedName)
|
||||
: findRuleByName(rules, nameOrDottedName);
|
||||
|
||||
export let findRuleByNamespace = (allRules, ns) =>
|
||||
allRules.filter(propEq('ns', ns))
|
||||
allRules.filter(propEq("ns", ns));
|
||||
|
||||
/*********************************
|
||||
Autres */
|
||||
|
||||
export let queryRule = rule => query => path(query.split(' . '))(rule)
|
||||
export let queryRule = rule => query => path(query.split(" . "))(rule);
|
||||
|
||||
// Redux-form stores the form values as a nested object
|
||||
// This helper makes a dottedName => value Map
|
||||
export let nestedSituationToPathMap = situation => {
|
||||
if (situation == undefined) return {}
|
||||
let rec = (o, currentPath) =>
|
||||
typeof o === 'object'
|
||||
? chain(([k, v]) => rec(v, [...currentPath, trim(k)]), toPairs(o))
|
||||
: [[currentPath.join(' . '), o + '']]
|
||||
if (situation == undefined) return {};
|
||||
let rec = (o, currentPath) =>
|
||||
typeof o === "object"
|
||||
? chain(([k, v]) => rec(v, [...currentPath, trim(k)]), toPairs(o))
|
||||
: [[currentPath.join(" . "), o + ""]];
|
||||
|
||||
return fromPairs(rec(situation, []))
|
||||
}
|
||||
return fromPairs(rec(situation, []));
|
||||
};
|
||||
|
||||
/* Traduction */
|
||||
|
||||
export let translateAll = (translations, flatRules) => {
|
||||
let translationsOf = rule => translations[buildDottedName(rule)],
|
||||
translateProp = (lang, translation) => (rule, prop) => {
|
||||
let propTrans = translation[prop + '.' + lang]
|
||||
if (prop === 'suggestions' && propTrans)
|
||||
return assoc(
|
||||
'suggestions',
|
||||
pipe(
|
||||
toPairs,
|
||||
map(([key, translatedKey]) => [
|
||||
translatedKey,
|
||||
rule.suggestions[key]
|
||||
]),
|
||||
fromPairs
|
||||
)(propTrans),
|
||||
rule
|
||||
)
|
||||
return propTrans ? assoc(prop, propTrans, rule) : rule
|
||||
},
|
||||
translateRule = (lang, translations, props) => rule => {
|
||||
let ruleTrans = translationsOf(rule)
|
||||
return ruleTrans
|
||||
? reduce(translateProp(lang, ruleTrans), rule, props)
|
||||
: rule
|
||||
}
|
||||
let translationsOf = rule => translations[buildDottedName(rule)],
|
||||
translateProp = (lang, translation) => (rule, prop) => {
|
||||
let propTrans = translation[prop + "." + lang];
|
||||
if (prop === "suggestions" && propTrans)
|
||||
return assoc(
|
||||
"suggestions",
|
||||
pipe(
|
||||
toPairs,
|
||||
map(([key, translatedKey]) => [
|
||||
translatedKey,
|
||||
rule.suggestions[key]
|
||||
]),
|
||||
fromPairs
|
||||
)(propTrans),
|
||||
rule
|
||||
);
|
||||
return propTrans ? assoc(prop, propTrans, rule) : rule;
|
||||
},
|
||||
translateRule = (lang, translations, props) => rule => {
|
||||
let ruleTrans = translationsOf(rule);
|
||||
return ruleTrans
|
||||
? reduce(translateProp(lang, ruleTrans), rule, props)
|
||||
: rule;
|
||||
};
|
||||
|
||||
let targets = [
|
||||
'titre',
|
||||
'description',
|
||||
'question',
|
||||
'sous-question',
|
||||
'résumé',
|
||||
'suggestions',
|
||||
'contrôles'
|
||||
]
|
||||
let targets = [
|
||||
"titre",
|
||||
"description",
|
||||
"question",
|
||||
"sous-question",
|
||||
"résumé",
|
||||
"suggestions",
|
||||
"contrôles"
|
||||
];
|
||||
|
||||
return map(translateRule('en', translations, targets), flatRules)
|
||||
}
|
||||
return map(translateRule("en", translations, targets), flatRules);
|
||||
};
|
||||
|
||||
// On enrichit la base de règles avec des propriétés dérivées de celles du YAML
|
||||
export let rules = translateAll(translations, rawRules).map(rule =>
|
||||
enrichRule(rule)
|
||||
)
|
||||
enrichRule(rule)
|
||||
);
|
||||
|
||||
export let rulesFr = rawRules.map(rule => enrichRule(rule))
|
||||
export let rulesFr = rawRules.map(rule => enrichRule(rule));
|
||||
|
||||
export let findParentDependency = (rules, rule) => {
|
||||
// A parent dependency means that one of a rule's parents is not just a namespace holder, it is a boolean question. E.g. is it a fixed-term contract, yes / no
|
||||
// When it is resolved to false, then the whole branch under it is disactivated (non applicable)
|
||||
// It lets those children omit obvious and repetitive parent applicability tests
|
||||
let parentDependencies = ruleParents(rule.dottedName).map(joinName)
|
||||
return pipe(
|
||||
map(parent => findRuleByDottedName(rules, parent)),
|
||||
reject(isNil),
|
||||
find(
|
||||
//Find the first "calculable" parent
|
||||
({ question, unit, formule }) => question && !unit && !formule //implicitly, the format is boolean
|
||||
)
|
||||
)(parentDependencies)
|
||||
}
|
||||
// A parent dependency means that one of a rule's parents is not just a namespace holder, it is a boolean question. E.g. is it a fixed-term contract, yes / no
|
||||
// When it is resolved to false, then the whole branch under it is disactivated (non applicable)
|
||||
// It lets those children omit obvious and repetitive parent applicability tests
|
||||
let parentDependencies = ruleParents(rule.dottedName).map(joinName);
|
||||
return pipe(
|
||||
map(parent => findRuleByDottedName(rules, parent)),
|
||||
reject(isNil),
|
||||
find(
|
||||
//Find the first "calculable" parent
|
||||
({ question, unit, formule }) => question && !unit && !formule //implicitly, the format is boolean
|
||||
)
|
||||
)(parentDependencies);
|
||||
};
|
||||
|
||||
export let getRuleFromAnalysis = analysis => dottedName => {
|
||||
if (!analysis) {
|
||||
throw new Error("[getRuleFromAnalysis] The analysis can't be nil !")
|
||||
}
|
||||
let rule = coerceArray(analysis) // In some simulations, there are multiple "branches" : the analysis is run with e.g. 3 different input situations
|
||||
.map(
|
||||
analysis =>
|
||||
analysis.cache[dottedName]?.explanation || // the cache stores a reference to a variable, the variable is contained in the 'explanation' attribute
|
||||
analysis.targets.find(propEq('dottedName', dottedName))
|
||||
)
|
||||
.filter(Boolean)[0]
|
||||
if (!analysis) {
|
||||
throw new Error("[getRuleFromAnalysis] The analysis can't be nil !");
|
||||
}
|
||||
let rule = coerceArray(analysis) // In some simulations, there are multiple "branches" : the analysis is run with e.g. 3 different input situations
|
||||
.map(
|
||||
analysis =>
|
||||
analysis.cache[dottedName]?.explanation || // the cache stores a reference to a variable, the variable is contained in the 'explanation' attribute
|
||||
analysis.targets.find(propEq("dottedName", dottedName))
|
||||
)
|
||||
.filter(Boolean)[0];
|
||||
|
||||
if (!rule) {
|
||||
throw new Error(
|
||||
`[getRuleFromAnalysis] Unable to find the rule ${dottedName}`
|
||||
)
|
||||
}
|
||||
if (!rule) {
|
||||
throw new Error(
|
||||
`[getRuleFromAnalysis] Unable to find the rule ${dottedName}`
|
||||
);
|
||||
}
|
||||
|
||||
return rule
|
||||
}
|
||||
return rule;
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { IsEmbeddedContext } from 'Components/utils/embeddedContext'
|
||||
import React from 'react'
|
||||
import { Route } from 'react-router'
|
||||
import IframeFooter from './IframeFooter'
|
||||
|
@ -5,12 +6,14 @@ import SimulateurEmbauche from './SimulateurEmbauche'
|
|||
|
||||
export default function Iframes() {
|
||||
return (
|
||||
<div className="ui__ container">
|
||||
<Route
|
||||
path="/iframes/simulateur-embauche"
|
||||
component={SimulateurEmbauche}
|
||||
/>
|
||||
<IframeFooter />
|
||||
</div>
|
||||
<IsEmbeddedContext.Provider value={true}>
|
||||
<div className="ui__ container">
|
||||
<Route
|
||||
path="/iframes/simulateur-embauche"
|
||||
component={SimulateurEmbauche}
|
||||
/>
|
||||
<IframeFooter />
|
||||
</div>
|
||||
</IsEmbeddedContext.Provider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -5,9 +5,10 @@ import SalaryExplanation from 'Components/SalaryExplanation'
|
|||
import Simulation from 'Components/Simulation'
|
||||
import salariéConfig from 'Components/simulationConfigs/salarié.yaml'
|
||||
import withSimulationConfig from 'Components/simulationConfigs/withSimulationConfig'
|
||||
import { IsEmbeddedContext } from 'Components/utils/embeddedContext'
|
||||
import { Markdown } from 'Components/utils/markdown'
|
||||
import withLanguage from 'Components/utils/withLanguage'
|
||||
import withSitePaths from 'Components/utils/withSitePaths'
|
||||
import { createMarkdownDiv } from 'Engine/marked'
|
||||
import { compose } from 'ramda'
|
||||
import emoji from 'react-easy-emoji'
|
||||
import { Helmet } from 'react-helmet'
|
||||
|
@ -18,6 +19,7 @@ export default compose(
|
|||
withTranslation(),
|
||||
withLanguage
|
||||
)(function Salarié({ t, language }) {
|
||||
const isEmbedded = React.useContext(IsEmbeddedContext)
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
|
@ -49,18 +51,19 @@ export default compose(
|
|||
</Banner>
|
||||
)}
|
||||
<SalarySimulation />
|
||||
<SalariéExplications />
|
||||
{!isEmbedded && <SalariéExplications />}
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
const SalariéExplications = withSitePaths(({ sitePaths }) =>
|
||||
createMarkdownDiv(`
|
||||
const SalariéExplications = withSitePaths(({ sitePaths }) => (
|
||||
<Markdown
|
||||
source={`
|
||||
## Calculer son salaire net
|
||||
|
||||
Lors de l'entretien d'embauche l'employeur propose en général une rémunération exprimée en « brut ». Le montant annoncé inclut ainsi les cotisations salariales, qui servent à financer la protection sociale du salarié (retraite, maladie, famille, etc.) et qui sont retranchées du salaire « net » perçu par le salarié.
|
||||
|
||||
Vous pouvez utiliser notre simulateur pour convertir le **salaire brut en net** : il vous suffit pour cela de saisir la rémunération annoncée dans la case salaire brut. La simulation peut-être affinée en répondant aux différentes questions (sur le CDD, statut cadre, etc.).
|
||||
Vous pouvez utiliser notre simulateur pour convertir le **salaire brut en net** : il vous suffit pour cela saisir la rémunération annoncée dans la case salaire brut. La simulation peut-être affinée en répondant aux différentes questions (sur le CDD, statut cadre, etc.).
|
||||
|
||||
Par ailleurs depuis 2019, l'[impôt sur le revenu](/documentation/impôt/impôt-sur-le-revenu) est prélevé à la source. Pour ce faire, la direction générale des finances publiques (DGFiP) transmet à l'employeur le taux d'imposition calculé à partir de la déclaration de revenu du salarié. Si ce taux est inconnu, par exemple lors d'une première année d'activité, l'employeur utilise le [taux neutre](/documentation/impôt/neutre). C'est aussi le taux neutre que nous utilisons dans le simulateur pour calculer le « net après impôt » qui est versé sur le compte bancaire du salarié.
|
||||
|
||||
|
@ -73,8 +76,9 @@ Si vous cherchez à embaucher, vous pouvez calculer le coût total de la rémun
|
|||
En plus du salaire, notre simulateur prend en compte le calcul des avantages en nature (téléphone, véhicule de fonction, etc.), ainsi que la mutuelle santé obligatoire.
|
||||
|
||||
Il existe des [aides différées](/documentation/aides-employeur) à l'embauche qui ne sont pas prises en compte par notre simulateur, vous pouvez les retrouver sur [le portail officiel](http://www.aides-entreprises.fr).
|
||||
`)
|
||||
)
|
||||
`}
|
||||
/>
|
||||
))
|
||||
|
||||
export let SalarySimulation = compose(
|
||||
withSimulationConfig(salariéConfig),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Markdown } from 'Components/utils/markdown'
|
||||
import { ScrollToTop } from 'Components/utils/Scroll'
|
||||
import withSitePaths from 'Components/utils/withSitePaths'
|
||||
import { createMarkdownDiv } from 'Engine/marked'
|
||||
import { all } from 'ramda'
|
||||
import React, { useContext } from 'react'
|
||||
import emoji from 'react-easy-emoji'
|
||||
|
@ -68,7 +68,7 @@ export default withSitePaths(function LocationMeublée({
|
|||
<h1>
|
||||
{emoji(data.icônes)} {data.titre}
|
||||
</h1>
|
||||
{createMarkdownDiv(data.explication)}
|
||||
<Markdown source={data.explication} />
|
||||
{data.plateformes && (
|
||||
<p>
|
||||
{emoji('📱 ')}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react'
|
||||
import { createMarkdownDiv } from 'Engine/marked'
|
||||
import { CheckItem } from 'Ui/Checklist'
|
||||
import { Markdown } from 'Components/utils/markdown'
|
||||
import { update } from 'ramda'
|
||||
import React from 'react'
|
||||
import { CheckItem } from 'Ui/Checklist'
|
||||
|
||||
export default ({ exonérations, dispatch, answers, title }) => {
|
||||
if (!exonérations) return null
|
||||
|
@ -17,7 +17,7 @@ export default ({ exonérations, dispatch, answers, title }) => {
|
|||
<CheckItem
|
||||
name={titre}
|
||||
title={titre}
|
||||
explanations={createMarkdownDiv(explication)}
|
||||
explanations={<Markdown source={explication} />}
|
||||
onChange={checked => {
|
||||
let action = {
|
||||
type: 'UPDATE_ACTIVITY',
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { map } from 'ramda'
|
||||
import { expect } from 'chai'
|
||||
import { map } from 'ramda'
|
||||
import {
|
||||
rules,
|
||||
disambiguateRuleReference,
|
||||
ruleParents,
|
||||
enrichRule,
|
||||
translateAll,
|
||||
nestedSituationToPathMap
|
||||
nestedSituationToPathMap,
|
||||
ruleParents,
|
||||
rules,
|
||||
translateAll
|
||||
} from '../source/engine/rules'
|
||||
|
||||
describe('enrichRule', function() {
|
||||
|
@ -23,14 +23,6 @@ describe('enrichRule', function() {
|
|||
'contrat salarié . CDD'
|
||||
)
|
||||
})
|
||||
|
||||
it('should render Markdown in sub-questions', function() {
|
||||
let rule = { nom: 'quoi', 'sous-question': '**wut**' }
|
||||
expect(enrichRule(rule)).to.have.property(
|
||||
'subquestion',
|
||||
'<p><strong>wut</strong></p>\n'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('rule checks', function() {
|
||||
|
|
204
yarn.lock
204
yarn.lock
|
@ -1754,6 +1754,11 @@ babylon@^6.18.0:
|
|||
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
|
||||
integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
|
||||
|
||||
bail@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.4.tgz#7181b66d508aa3055d3f6c13f0a0c720641dde9b"
|
||||
integrity sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==
|
||||
|
||||
balanced-match@^0.4.2:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
|
||||
|
@ -2458,6 +2463,11 @@ code-point-at@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
|
||||
|
||||
collapse-white-space@^1.0.2:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.5.tgz#c2495b699ab1ed380d29a1091e01063e75dbbe3a"
|
||||
integrity sha512-703bOOmytCYAX9cXYqoikYIx6twmFCXsnzRQheBcTG3nzKYBR4P/+wkYeH+Mvj7qUz8zZDtdyzbxfnEi/kYzRQ==
|
||||
|
||||
collection-visit@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
|
||||
|
@ -3247,7 +3257,7 @@ domexception@^1.0.1:
|
|||
dependencies:
|
||||
webidl-conversions "^4.0.2"
|
||||
|
||||
domhandler@^2.3.0:
|
||||
domhandler@^2.3.0, domhandler@^2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
|
||||
integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
|
||||
|
@ -3822,7 +3832,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
|
|||
assign-symbols "^1.0.0"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
extend@~3.0.2:
|
||||
extend@^3.0.0, extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
@ -4708,6 +4718,17 @@ html-parse-stringify2@2.0.1:
|
|||
dependencies:
|
||||
void-elements "^2.0.1"
|
||||
|
||||
html-to-react@^1.3.4:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/html-to-react/-/html-to-react-1.3.4.tgz#647b3a54fdec73a6461864b129fb0d1eec7d4589"
|
||||
integrity sha512-/tWDdb/8Koi/QEP5YUY1653PcDpBnnMblXRhotnTuhFDjI1Fc6Wzox5d4sw73Xk5rM2OdM5np4AYjT/US/Wj7Q==
|
||||
dependencies:
|
||||
domhandler "^2.4.2"
|
||||
escape-string-regexp "^1.0.5"
|
||||
htmlparser2 "^3.10.0"
|
||||
lodash.camelcase "^4.3.0"
|
||||
ramda "^0.26"
|
||||
|
||||
html-webpack-plugin@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b"
|
||||
|
@ -4721,7 +4742,7 @@ html-webpack-plugin@^3.2.0:
|
|||
toposort "^1.0.0"
|
||||
util.promisify "1.0.0"
|
||||
|
||||
htmlparser2@^3.3.0, htmlparser2@^3.9.1:
|
||||
htmlparser2@^3.10.0, htmlparser2@^3.3.0, htmlparser2@^3.9.1:
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
|
||||
integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
|
||||
|
@ -5066,7 +5087,7 @@ is-boolean-object@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
|
||||
integrity sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M=
|
||||
|
||||
is-buffer@^1.1.5, is-buffer@~1.1.1:
|
||||
is-buffer@^1.1.4, is-buffer@^1.1.5, is-buffer@~1.1.1:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
||||
|
@ -5222,7 +5243,7 @@ is-path-inside@^1.0.0:
|
|||
dependencies:
|
||||
path-is-inside "^1.0.1"
|
||||
|
||||
is-plain-obj@^1.0.0:
|
||||
is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
|
||||
integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
|
||||
|
@ -5295,11 +5316,21 @@ is-what@^3.2.3:
|
|||
resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.2.3.tgz#50f76f1bd8e56967e15765d1d34302513701997b"
|
||||
integrity sha512-c4syLgFnjXTH5qd82Fp/qtUIeM0wA69xbI0KH1QpurMIvDaZFrS8UtAa4U52Dc2qSznaMxHit0gErMp6A/Qk1w==
|
||||
|
||||
is-whitespace-character@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz#b3ad9546d916d7d3ffa78204bca0c26b56257fac"
|
||||
integrity sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ==
|
||||
|
||||
is-windows@^1.0.1, is-windows@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
|
||||
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
|
||||
|
||||
is-word-character@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.3.tgz#264d15541cbad0ba833d3992c34e6b40873b08aa"
|
||||
integrity sha512-0wfcrFgOOOBdgRNT9H33xe6Zi6yhX/uoc4U8NBZGeQQB0ctU1dnlNTyL9JM2646bHDTpsDm1Brb3VPoCIMrd/A==
|
||||
|
||||
is-wsl@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
|
||||
|
@ -5929,10 +5960,10 @@ map-visit@^1.0.0:
|
|||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
marked@^0.3.17:
|
||||
version "0.3.19"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.19.tgz#5d47f709c4c9fc3c216b6d46127280f40b39d790"
|
||||
integrity sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==
|
||||
markdown-escapes@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.3.tgz#6155e10416efaafab665d466ce598216375195f5"
|
||||
integrity sha512-XUi5HJhhV5R74k8/0H2oCbCiYf/u4cO/rX8tnGkRvrqhsr5BRNU6Mg0yt/8UIx1iIS8220BNJsDb7XnILhLepw==
|
||||
|
||||
material-colors@^1.2.1:
|
||||
version "1.2.6"
|
||||
|
@ -5962,6 +5993,13 @@ md5@^2.2.1:
|
|||
crypt "~0.0.1"
|
||||
is-buffer "~1.1.1"
|
||||
|
||||
mdast-add-list-metadata@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mdast-add-list-metadata/-/mdast-add-list-metadata-1.0.1.tgz#95e73640ce2fc1fa2dcb7ec443d09e2bfe7db4cf"
|
||||
integrity sha512-fB/VP4MJ0LaRsog7hGPxgOrSL3gE/2uEdZyDuSEnKCv/8IkYHiDkIQSbChiJoHyxZZXZ9bzckyRk+vNxFzh8rA==
|
||||
dependencies:
|
||||
unist-util-visit-parents "1.1.2"
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
|
@ -6882,7 +6920,7 @@ parse-asn1@^5.0.0:
|
|||
pbkdf2 "^3.0.3"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
parse-entities@^1.1.2:
|
||||
parse-entities@^1.1.0, parse-entities@^1.1.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50"
|
||||
integrity sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==
|
||||
|
@ -7652,7 +7690,7 @@ ramda@0.24.1:
|
|||
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857"
|
||||
integrity sha1-w7d1UZfzW43DUCIoJixMkd22uFc=
|
||||
|
||||
ramda@0.x, ramda@>=0.15.0:
|
||||
ramda@0.x, ramda@>=0.15.0, ramda@^0.26:
|
||||
version "0.26.1"
|
||||
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06"
|
||||
integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==
|
||||
|
@ -7830,6 +7868,19 @@ react-lifecycles-compat@^3.0.4:
|
|||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react-markdown@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-4.1.0.tgz#7fdf840ecbabc803f28156f7411c726b58f25a73"
|
||||
integrity sha512-EOHsEAN+aoP8UVz7vTHx6Z63GJfhrO9KItKlfsiBtVVS9tmSWtUaBTw73+2SObrWiOiE2Cs9qUBL7ORsvVhOrA==
|
||||
dependencies:
|
||||
html-to-react "^1.3.4"
|
||||
mdast-add-list-metadata "1.0.1"
|
||||
prop-types "^15.7.2"
|
||||
remark-parse "^5.0.0"
|
||||
unified "^6.1.5"
|
||||
unist-util-visit "^1.3.0"
|
||||
xtend "^4.0.1"
|
||||
|
||||
react-number-format@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-4.0.8.tgz#f0a0dfbeded9a746f4d8b309926cf55d7effebb2"
|
||||
|
@ -8217,6 +8268,27 @@ relateurl@0.2.x:
|
|||
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
|
||||
integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
|
||||
|
||||
remark-parse@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95"
|
||||
integrity sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==
|
||||
dependencies:
|
||||
collapse-white-space "^1.0.2"
|
||||
is-alphabetical "^1.0.0"
|
||||
is-decimal "^1.0.0"
|
||||
is-whitespace-character "^1.0.0"
|
||||
is-word-character "^1.0.0"
|
||||
markdown-escapes "^1.0.0"
|
||||
parse-entities "^1.1.0"
|
||||
repeat-string "^1.5.4"
|
||||
state-toggle "^1.0.0"
|
||||
trim "0.0.1"
|
||||
trim-trailing-lines "^1.0.0"
|
||||
unherit "^1.0.4"
|
||||
unist-util-remove-position "^1.0.0"
|
||||
vfile-location "^2.0.0"
|
||||
xtend "^4.0.1"
|
||||
|
||||
remove-trailing-separator@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
|
||||
|
@ -8238,7 +8310,7 @@ repeat-element@^1.1.2:
|
|||
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce"
|
||||
integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==
|
||||
|
||||
repeat-string@^1.6.1:
|
||||
repeat-string@^1.5.4, repeat-string@^1.6.1:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
||||
integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
|
||||
|
@ -8250,6 +8322,11 @@ repeating@^2.0.0:
|
|||
dependencies:
|
||||
is-finite "^1.0.0"
|
||||
|
||||
replace-ext@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb"
|
||||
integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=
|
||||
|
||||
request-progress@0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-0.4.0.tgz#c1954e39086aa85269c5660bcee0142a6a70d7e7"
|
||||
|
@ -8850,6 +8927,11 @@ ssri@^6.0.1:
|
|||
dependencies:
|
||||
figgy-pudding "^3.5.1"
|
||||
|
||||
state-toggle@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.2.tgz#75e93a61944116b4959d665c8db2d243631d6ddc"
|
||||
integrity sha512-8LpelPGR0qQM4PnfLiplOQNJcIN1/r2Gy0xKB2zKnIW2YzPMt2sR4I/+gtPjhN7Svh9kw+zqEg2SFwpBO9iNiw==
|
||||
|
||||
static-extend@^0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
|
||||
|
@ -9338,6 +9420,21 @@ trim-right@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
|
||||
integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
|
||||
|
||||
trim-trailing-lines@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz#d2f1e153161152e9f02fabc670fb40bec2ea2e3a"
|
||||
integrity sha512-MUjYItdrqqj2zpcHFTkMa9WAv4JHTI6gnRQGPFLrt5L9a6tRMiDnIqYl8JBvu2d2Tc3lWJKQwlGCp0K8AvCM+Q==
|
||||
|
||||
trim@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd"
|
||||
integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0=
|
||||
|
||||
trough@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.4.tgz#3b52b1f13924f460c3fbfd0df69b587dbcbc762e"
|
||||
integrity sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==
|
||||
|
||||
tslib@^1.9.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
|
||||
|
@ -9393,6 +9490,14 @@ uglify-js@3.4.x:
|
|||
commander "~2.19.0"
|
||||
source-map "~0.6.1"
|
||||
|
||||
unherit@^1.0.4:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.2.tgz#14f1f397253ee4ec95cec167762e77df83678449"
|
||||
integrity sha512-W3tMnpaMG7ZY6xe/moK04U9fBhi6wEiCYHUW5Mop/wQHf12+79EQGwxYejNdhEz2mkqkBlGwm7pxmgBKMVUj0w==
|
||||
dependencies:
|
||||
inherits "^2.0.1"
|
||||
xtend "^4.0.1"
|
||||
|
||||
unicode-canonical-property-names-ecmascript@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
|
||||
|
@ -9416,6 +9521,18 @@ unicode-property-aliases-ecmascript@^1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57"
|
||||
integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==
|
||||
|
||||
unified@^6.1.5:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/unified/-/unified-6.2.0.tgz#7fbd630f719126d67d40c644b7e3f617035f6dba"
|
||||
integrity sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==
|
||||
dependencies:
|
||||
bail "^1.0.0"
|
||||
extend "^3.0.0"
|
||||
is-plain-obj "^1.1.0"
|
||||
trough "^1.0.0"
|
||||
vfile "^2.0.0"
|
||||
x-is-string "^0.1.0"
|
||||
|
||||
union-value@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
|
||||
|
@ -9457,6 +9574,42 @@ unique-slug@^2.0.0:
|
|||
dependencies:
|
||||
imurmurhash "^0.1.4"
|
||||
|
||||
unist-util-is@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-3.0.0.tgz#d9e84381c2468e82629e4a5be9d7d05a2dd324cd"
|
||||
integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==
|
||||
|
||||
unist-util-remove-position@^1.0.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.3.tgz#d91aa8b89b30cb38bad2924da11072faa64fd972"
|
||||
integrity sha512-CtszTlOjP2sBGYc2zcKA/CvNdTdEs3ozbiJ63IPBxh8iZg42SCCb8m04f8z2+V1aSk5a7BxbZKEdoDjadmBkWA==
|
||||
dependencies:
|
||||
unist-util-visit "^1.1.0"
|
||||
|
||||
unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz#3f37fcf351279dcbca7480ab5889bb8a832ee1c6"
|
||||
integrity sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==
|
||||
|
||||
unist-util-visit-parents@1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-1.1.2.tgz#f6e3afee8bdbf961c0e6f028ea3c0480028c3d06"
|
||||
integrity sha512-yvo+MMLjEwdc3RhhPYSximset7rwjMrdt9E41Smmvg25UQIenzrN83cRnF1JMzoMi9zZOQeYXHSDf7p+IQkW3Q==
|
||||
|
||||
unist-util-visit-parents@^2.0.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9"
|
||||
integrity sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==
|
||||
dependencies:
|
||||
unist-util-is "^3.0.0"
|
||||
|
||||
unist-util-visit@^1.1.0, unist-util-visit@^1.3.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.1.tgz#4724aaa8486e6ee6e26d7ff3c8685960d560b1e3"
|
||||
integrity sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==
|
||||
dependencies:
|
||||
unist-util-visit-parents "^2.0.0"
|
||||
|
||||
universal-user-agent@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-2.1.0.tgz#5abfbcc036a1ba490cb941f8fd68c46d3669e8e4"
|
||||
|
@ -9642,6 +9795,28 @@ verror@1.10.0:
|
|||
core-util-is "1.0.2"
|
||||
extsprintf "^1.2.0"
|
||||
|
||||
vfile-location@^2.0.0:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.5.tgz#c83eb02f8040228a8d2b3f10e485be3e3433e0a2"
|
||||
integrity sha512-Pa1ey0OzYBkLPxPZI3d9E+S4BmvfVwNAAXrrqGbwTVXWaX2p9kM1zZ+n35UtVM06shmWKH4RPRN8KI80qE3wNQ==
|
||||
|
||||
vfile-message@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.1.1.tgz#5833ae078a1dfa2d96e9647886cd32993ab313e1"
|
||||
integrity sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==
|
||||
dependencies:
|
||||
unist-util-stringify-position "^1.1.1"
|
||||
|
||||
vfile@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a"
|
||||
integrity sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==
|
||||
dependencies:
|
||||
is-buffer "^1.1.4"
|
||||
replace-ext "1.0.0"
|
||||
unist-util-stringify-position "^1.0.0"
|
||||
vfile-message "^1.0.0"
|
||||
|
||||
vm-browserify@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019"
|
||||
|
@ -10007,6 +10182,11 @@ ws@^6.1.0:
|
|||
dependencies:
|
||||
async-limiter "~1.0.0"
|
||||
|
||||
x-is-string@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82"
|
||||
integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=
|
||||
|
||||
xml-name-validator@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
||||
|
|
Loading…
Reference in New Issue