2017-06-28 07:31:37 +00:00
import R from 'ramda'
import React from 'react'
import { anyNull , val } from './traverse-common-functions'
import { Node , Leaf } from './traverse-common-jsx'
2017-07-16 21:58:06 +00:00
import { makeJsx , evaluateNode , rewriteNode , evaluateArray , evaluateArrayWithFilter , evaluateObject , parseObject , collectNodeMissing } from './evaluation'
2017-07-13 19:55:59 +00:00
let constantNode = constant => ( { nodeValue : constant } )
2017-06-28 07:31:37 +00:00
let transformPercentage = s =>
R . contains ( '%' ) ( s ) ?
+ s . replace ( '%' , '' ) / 100
: + s
2017-06-29 06:51:40 +00:00
export let decompose = ( recurse , k , v ) => {
let
subProps = R . dissoc ( 'composantes' ) ( v ) ,
2017-07-16 21:58:06 +00:00
explanation = v . composantes . map ( c =>
2017-06-29 06:51:40 +00:00
( {
... recurse (
R . objOf ( k ,
{
... subProps ,
... R . dissoc ( 'attributs' ) ( c )
} )
) ,
composante : c . nom ? { nom : c . nom } : c . attributs
} )
2017-07-11 14:39:05 +00:00
)
2017-06-29 06:51:40 +00:00
2017-07-13 19:55:59 +00:00
let jsx = ( nodeValue , explanation ) =>
< Node
2017-06-29 06:51:40 +00:00
classes = "mecanism composantes"
name = "composantes"
2017-07-13 19:55:59 +00:00
value = { nodeValue }
2017-06-29 06:51:40 +00:00
child = {
< ul >
2017-07-11 14:39:05 +00:00
{ explanation . map ( ( c , i ) =>
2017-06-29 06:51:40 +00:00
[ < li className = "composante" key = { JSON . stringify ( c . composante ) } >
< ul className = "composanteAttributes" >
{ R . toPairs ( c . composante ) . map ( ( [ k , v ] ) =>
< li >
< span > { k } : < / s p a n >
< span > { v } < / s p a n >
< / l i >
) }
< / u l >
< div className = "content" >
2017-07-13 19:55:59 +00:00
{ makeJsx ( c ) }
2017-06-29 06:51:40 +00:00
< / d i v >
< / l i > ,
2017-07-11 14:39:05 +00:00
i < ( explanation . length - 1 ) && < li className = "composantesSymbol" > < i className = "fa fa-plus-circle" aria - hidden = "true" > < / i > < / l i >
2017-07-13 19:55:59 +00:00
] )
2017-06-29 06:51:40 +00:00
}
< / u l >
}
/ >
2017-07-13 19:55:59 +00:00
2017-07-28 11:42:48 +00:00
let filter = situationGate => c => ( ! situationGate ( "sys.filter" ) || ! c . composante || ! c . composante [ 'dû par' ] ) || c . composante [ 'dû par' ] == situationGate ( "sys.filter" )
2017-07-17 12:01:48 +00:00
2017-07-13 19:55:59 +00:00
return {
explanation ,
jsx ,
2017-07-16 21:58:06 +00:00
evaluate : evaluateArrayWithFilter ( filter , R . add , 0 ) ,
2017-07-13 19:55:59 +00:00
category : 'mecanism' ,
name : 'composantes' ,
type : 'numeric'
2017-06-29 06:51:40 +00:00
}
}
2017-06-28 10:08:32 +00:00
export let mecanismOneOf = ( recurse , k , v ) => {
2017-07-09 17:42:45 +00:00
if ( ! R . is ( Array , v ) ) throw 'should be array'
let explanation = R . map ( recurse , v )
2017-07-13 19:55:59 +00:00
let jsx = ( nodeValue , explanation ) =>
< Node
2017-06-28 10:08:32 +00:00
classes = "mecanism conditions list"
2017-07-09 17:42:45 +00:00
name = 'une de ces conditions'
2017-07-13 19:55:59 +00:00
value = { nodeValue }
2017-06-28 10:08:32 +00:00
child = {
< ul >
2017-07-13 19:55:59 +00:00
{ explanation . map ( item => < li key = { item . name || item . text } > { makeJsx ( item ) } < / l i > ) }
2017-06-28 10:08:32 +00:00
< / u l >
2017-06-28 07:31:37 +00:00
}
2017-06-28 10:08:32 +00:00
/ >
2017-07-13 19:55:59 +00:00
2017-08-18 15:21:43 +00:00
let evaluate = ( situationGate , parsedRules , node ) => {
let evaluateOne = child => evaluateNode ( situationGate , parsedRules , child ) ,
explanation = R . map ( evaluateOne , node . explanation ) ,
values = R . pluck ( "nodeValue" , explanation ) ,
nodeValue = R . any ( R . equals ( true ) , values ) ? true :
( R . any ( R . equals ( null ) , values ) ? null : false )
let collectMissing = node => node . nodeValue == null ? R . chain ( collectNodeMissing , node . explanation ) : [ ]
return rewriteNode ( node , nodeValue , explanation , collectMissing )
}
2017-07-13 19:55:59 +00:00
return {
2017-08-18 15:21:43 +00:00
evaluate ,
2017-07-13 19:55:59 +00:00
jsx ,
explanation ,
category : 'mecanism' ,
name : 'une de ces conditions' ,
type : 'boolean'
2017-06-28 10:08:32 +00:00
}
}
export let mecanismAllOf = ( recurse , k , v ) => {
2017-07-09 17:42:45 +00:00
if ( ! R . is ( Array , v ) ) throw 'should be array'
let explanation = R . map ( recurse , v )
2017-07-13 19:55:59 +00:00
let jsx = ( nodeValue , explanation ) =>
< Node
2017-07-09 17:42:45 +00:00
classes = "mecanism conditions list"
name = 'toutes ces conditions'
2017-07-13 19:55:59 +00:00
value = { nodeValue }
2017-07-09 17:42:45 +00:00
child = {
< ul >
2017-07-13 19:55:59 +00:00
{ explanation . map ( item => < li key = { item . name || item . text } > { makeJsx ( item ) } < / l i > ) }
2017-07-09 17:42:45 +00:00
< / u l >
}
/ >
2017-07-13 19:55:59 +00:00
return {
evaluate : evaluateArray ( R . and , true ) ,
jsx ,
explanation ,
category : 'mecanism' ,
name : 'toutes ces conditions' ,
type : 'boolean'
2017-07-09 17:42:45 +00:00
}
2017-06-28 10:08:32 +00:00
}
2017-06-28 07:31:37 +00:00
2017-08-02 13:28:33 +00:00
export let mecanismNumericalSwitch = ( recurse , k , v ) => {
2017-07-12 19:57:54 +00:00
if ( R . is ( String , v ) ) {
// This seems an undue limitation
2017-08-16 09:21:42 +00:00
// Or a logical one if we decide to keep this mecanism specialized as opposed to "variations"
2017-07-12 19:57:54 +00:00
return mecanismPercentage ( recurse , k , v )
}
if ( ! R . is ( Object , v ) || R . keys ( v ) . length == 0 ) {
2017-08-02 13:28:33 +00:00
throw 'Le mécanisme "aiguillage numérique" et ses sous-logiques doivent contenir au moins une proposition'
2017-07-12 19:57:54 +00:00
}
2017-08-16 09:21:42 +00:00
// les termes sont les coupes (condition, conséquence) de l'aiguillage numérique
let terms = R . toPairs ( v )
// la conséquence peut être un 'string' ou un autre aiguillage numérique
2017-07-12 19:57:54 +00:00
let parseCondition = ( [ condition , consequence ] ) => {
let
conditionNode = recurse ( condition ) , // can be a 'comparison', a 'variable', TODO a 'negation'
2017-08-02 13:28:33 +00:00
consequenceNode = mecanismNumericalSwitch ( recurse , condition , consequence )
2017-07-12 19:57:54 +00:00
2017-08-02 12:41:00 +00:00
let evaluate = ( situationGate , parsedRules , node ) => {
let collectMissing = node => {
let missingOnTheLeft = collectNodeMissing ( node . explanation . condition ) ,
investigate = node . explanation . condition . nodeValue !== false ,
missingOnTheRight = investigate ? collectNodeMissing ( node . explanation . consequence ) : [ ]
return R . concat ( missingOnTheLeft , missingOnTheRight )
2017-07-14 09:31:39 +00:00
}
2017-07-12 19:57:54 +00:00
2017-08-02 12:41:00 +00:00
let explanation = R . evolve ( {
condition : R . curry ( evaluateNode ) ( situationGate , parsedRules ) ,
consequence : R . curry ( evaluateNode ) ( situationGate , parsedRules )
2017-08-16 09:21:42 +00:00
} , node . explanation )
2017-08-02 12:41:00 +00:00
return {
... node ,
collectMissing ,
explanation ,
nodeValue : explanation . consequence . nodeValue ,
condValue : explanation . condition . nodeValue
}
}
2017-07-13 19:55:59 +00:00
let jsx = ( nodeValue , { condition , consequence } ) =>
< div className = "condition" >
{ makeJsx ( condition ) }
< div >
{ makeJsx ( consequence ) }
< / d i v >
< / d i v >
2017-07-12 19:57:54 +00:00
return {
evaluate ,
2017-07-13 19:55:59 +00:00
jsx ,
explanation : { condition : conditionNode , consequence : consequenceNode } ,
2017-07-12 19:57:54 +00:00
category : 'condition' ,
text : condition ,
condition : conditionNode ,
type : 'boolean' ,
}
}
let evaluateTerms = ( situationGate , parsedRules , node ) => {
2017-08-16 11:41:30 +00:00
let
evaluateOne = child => evaluateNode ( situationGate , parsedRules , child ) ,
explanation = R . map ( evaluateOne , node . explanation ) ,
2017-07-12 19:57:54 +00:00
choice = R . find ( node => node . condValue , explanation ) ,
2017-08-16 09:21:42 +00:00
nonFalsyTerms = R . filter ( node => node . condValue !== false , explanation ) ,
getFirst = ( prop ) => R . pipe ( R . head , R . prop ( prop ) ) ( nonFalsyTerms ) ,
nodeValue =
// voilà le "numérique" dans le nom de ce mécanisme : il renvoie zéro si aucune condition n'est vérifiée
R . isEmpty ( nonFalsyTerms ) ? 0 :
// c'est un 'null', on renvoie null car des variables sont manquantes
getFirst ( 'condValue' ) == null ? null :
// c'est un true, on renvoie la valeur de la conséquence
getFirst ( 'nodeValue' )
2017-07-12 19:57:54 +00:00
2017-07-28 09:42:57 +00:00
let collectMissing = node => {
let choice = R . find ( node => node . condValue , node . explanation )
return choice ? collectNodeMissing ( choice ) : R . chain ( collectNodeMissing , node . explanation )
}
2017-07-13 19:55:59 +00:00
return rewriteNode ( node , nodeValue , explanation , collectMissing )
2017-07-12 19:57:54 +00:00
}
let explanation = R . map ( parseCondition , terms )
2017-07-13 19:55:59 +00:00
let jsx = ( nodeValue , explanation ) =>
< Node
2017-08-02 13:28:33 +00:00
classes = "mecanism numericalSwitch list"
name = "aiguillage numérique"
2017-07-13 19:55:59 +00:00
value = { nodeValue }
2017-07-12 19:57:54 +00:00
child = {
< ul >
2017-07-13 19:55:59 +00:00
{ explanation . map ( item => < li key = { item . name || item . text } > { makeJsx ( item ) } < / l i > ) }
2017-07-12 19:57:54 +00:00
< / u l >
}
/ >
2017-07-13 19:55:59 +00:00
return {
evaluate : evaluateTerms ,
jsx ,
explanation ,
category : 'mecanism' ,
2017-08-02 13:28:33 +00:00
name : "aiguillage numérique" ,
2017-07-13 19:55:59 +00:00
type : 'boolean || numeric' // lol !
2017-07-12 19:57:54 +00:00
}
2017-06-28 10:08:32 +00:00
}
export let mecanismPercentage = ( recurse , k , v ) => {
let reg = /^(\d+(\.\d+)?)\%$/
if ( R . test ( reg ) ( v ) )
return {
type : 'numeric' ,
2017-07-13 19:55:59 +00:00
category : 'percentage' ,
2017-06-28 10:08:32 +00:00
nodeValue : R . match ( reg ) ( v ) [ 1 ] / 100 ,
explanation : null ,
jsx :
< span className = "percentage" >
< span className = "name" > { v } < / s p a n >
< / s p a n >
}
else {
let node = recurse ( v )
2017-07-13 20:20:53 +00:00
let evaluate = ( situation , parsedRules , node ) => evaluateNode ( situation , parsedRules , node . explanation )
let jsx = ( nodeValue , explanation ) => makeJsx ( explanation )
2017-06-28 10:08:32 +00:00
return {
2017-07-13 20:20:53 +00:00
evaluate ,
jsx ,
2017-06-28 10:08:32 +00:00
type : 'numeric' ,
category : 'percentage' ,
2017-07-13 20:20:53 +00:00
explanation : node
2017-06-28 10:08:32 +00:00
}
}
}
export let mecanismSum = ( recurse , k , v ) => {
2017-07-09 22:14:22 +00:00
let explanation = v . map ( recurse )
2017-06-28 10:08:32 +00:00
2017-07-13 19:55:59 +00:00
let evaluate = evaluateArray ( R . add , 0 )
let jsx = ( nodeValue , explanation ) =>
< Node
2017-06-28 10:08:32 +00:00
classes = "mecanism somme"
name = "somme"
2017-07-13 19:55:59 +00:00
value = { nodeValue }
2017-06-28 10:08:32 +00:00
child = {
< ul >
2017-07-13 19:55:59 +00:00
{ explanation . map ( v => < li key = { v . name || v . text } > { makeJsx ( v ) } < / l i > ) }
2017-06-28 10:08:32 +00:00
< / u l >
2017-06-28 07:31:37 +00:00
}
2017-06-28 10:08:32 +00:00
/ >
2017-07-13 19:55:59 +00:00
return {
evaluate ,
jsx ,
explanation ,
category : 'mecanism' ,
name : 'somme' ,
type : 'numeric'
2017-06-28 10:08:32 +00:00
}
}
export let mecanismProduct = ( recurse , k , v ) => {
2017-06-29 06:51:40 +00:00
if ( v . composantes ) { //mécanisme de composantes. Voir known-mecanisms.md/composantes
return decompose ( recurse , k , v )
}
2017-07-12 09:50:34 +00:00
// Preprocessing step to parse percentages
let wrap = x => ( { taux : x } ) ,
value = R . evolve ( { taux : wrap } , v )
2017-07-11 15:39:50 +00:00
2017-07-12 09:50:34 +00:00
let objectShape = {
assiette : false ,
taux : constantNode ( 1 ) ,
facteur : constantNode ( 1 ) ,
plafond : constantNode ( Infinity )
}
let effect = ( { assiette , taux , facteur , plafond } ) => {
let mult = ( base , rate , facteur , plafond ) => Math . min ( base , plafond ) * rate * facteur
return ( val ( taux ) === 0 || val ( taux ) === false || val ( assiette ) === 0 || val ( facteur ) === 0 ) ?
2017-06-28 10:08:32 +00:00
0
: anyNull ( [ taux , assiette , facteur , plafond ] ) ?
null
: mult ( val ( assiette ) , val ( taux ) , val ( facteur ) , val ( plafond ) )
2017-07-11 15:39:50 +00:00
}
2017-07-12 09:50:34 +00:00
let explanation = parseObject ( recurse , objectShape , value ) ,
evaluate = evaluateObject ( objectShape , effect )
2017-07-11 15:39:50 +00:00
2017-07-13 19:55:59 +00:00
let jsx = ( nodeValue , explanation ) =>
< Node
2017-06-28 10:08:32 +00:00
classes = "mecanism multiplication"
name = "multiplication"
2017-07-13 19:55:59 +00:00
value = { nodeValue }
2017-06-28 10:08:32 +00:00
child = {
< ul className = "properties" >
< li key = "assiette" >
< span className = "key" > assiette : < / s p a n >
2017-07-13 19:55:59 +00:00
< span className = "value" > { makeJsx ( explanation . assiette ) } < / s p a n >
2017-06-28 10:08:32 +00:00
< / l i >
2017-07-12 09:50:34 +00:00
{ explanation . taux . nodeValue != 1 &&
2017-06-28 10:08:32 +00:00
< li key = "taux" >
< span className = "key" > taux : < / s p a n >
2017-07-13 19:55:59 +00:00
< span className = "value" > { makeJsx ( explanation . taux ) } < / s p a n >
2017-06-28 10:08:32 +00:00
< / l i > }
2017-07-12 09:50:34 +00:00
{ explanation . facteur . nodeValue != 1 &&
2017-06-28 10:08:32 +00:00
< li key = "facteur" >
< span className = "key" > facteur : < / s p a n >
2017-07-13 19:55:59 +00:00
< span className = "value" > { makeJsx ( explanation . facteur ) } < / s p a n >
2017-06-28 10:08:32 +00:00
< / l i > }
2017-07-12 09:50:34 +00:00
{ explanation . plafond . nodeValue != Infinity &&
2017-06-28 10:08:32 +00:00
< li key = "plafond" >
< span className = "key" > plafond : < / s p a n >
2017-07-13 19:55:59 +00:00
< span className = "value" > { makeJsx ( explanation . plafond ) } < / s p a n >
2017-06-28 10:08:32 +00:00
< / l i > }
< / u l >
2017-06-28 07:31:37 +00:00
}
2017-06-28 10:08:32 +00:00
/ >
2017-07-13 19:55:59 +00:00
return {
evaluate ,
jsx ,
explanation ,
category : 'mecanism' ,
name : 'multiplication' ,
type : 'numeric'
2017-06-28 10:08:32 +00:00
}
}
export let mecanismScale = ( recurse , k , v ) => {
// Sous entendu : barème en taux marginaux.
// A étendre (avec une propriété type ?) quand les règles en contiendront d'autres.
if ( v . composantes ) { //mécanisme de composantes. Voir known-mecanisms.md/composantes
2017-06-29 06:51:40 +00:00
return decompose ( recurse , k , v )
2017-06-28 07:31:37 +00:00
2017-06-28 10:08:32 +00:00
}
2017-06-28 07:31:37 +00:00
2017-06-28 10:08:32 +00:00
if ( v [ 'multiplicateur des tranches' ] == null )
throw "un barème nécessite pour l'instant une propriété 'multiplicateur des tranches'"
2017-06-28 07:31:37 +00:00
2017-07-13 19:55:59 +00:00
/ * o n r é é c r i t e n p l u s b a s n i v e a u l e s t r a n c h e s :
` en-dessous de: 1 `
devient
` ` `
de : 0
à : 1
` ` `
* /
let tranches = v [ 'tranches' ] . map ( t =>
2017-06-28 10:08:32 +00:00
R . has ( 'en-dessous de' ) ( t ) ? { de : 0 , 'à' : t [ 'en-dessous de' ] , taux : t . taux }
: R . has ( 'au-dessus de' ) ( t ) ? { de : t [ 'au-dessus de' ] , 'à' : Infinity , taux : t . taux }
2017-07-13 19:55:59 +00:00
: t )
let aliased = {
... v ,
multiplicateur : v [ 'multiplicateur des tranches' ]
}
let objectShape = {
assiette : false ,
multiplicateur : false
}
let effect = ( { assiette , multiplicateur , tranches } ) => {
2017-06-28 10:08:32 +00:00
//TODO appliquer retreat() à de, à, taux pour qu'ils puissent contenir des calculs ou pour les cas où toutes les tranches n'ont pas un multiplicateur commun (ex. plafond sécurité sociale). Il faudra alors vérifier leur nullité comme ça :
/ *
nulled = assiette . nodeValue == null || R . any (
R . pipe (
R . values , R . map ( val ) , R . any ( R . equals ( null ) )
)
) ( tranches ) ,
* /
// nulled = anyNull([assiette, multiplicateur]),
2017-07-13 19:55:59 +00:00
let nulled = val ( assiette ) == null || val ( multiplicateur ) == null
2017-06-28 07:31:37 +00:00
2017-07-13 19:55:59 +00:00
return nulled ?
2017-06-28 10:08:32 +00:00
null
: tranches . reduce ( ( memo , { de : min , 'à' : max , taux } ) =>
( val ( assiette ) < ( min * val ( multiplicateur ) ) )
? memo + 0
: memo
+ ( Math . min ( val ( assiette ) , max * val ( multiplicateur ) ) - ( min * val ( multiplicateur ) ) )
* transformPercentage ( taux )
, 0 )
2017-07-13 19:55:59 +00:00
}
2017-06-28 07:31:37 +00:00
2017-07-13 19:55:59 +00:00
let explanation = {
... parseObject ( recurse , objectShape , aliased ) ,
tranches
} ,
evaluate = evaluateObject ( objectShape , effect )
let jsx = ( nodeValue , explanation ) =>
< Node
2017-06-28 10:08:32 +00:00
classes = "mecanism barème"
name = "barème"
value = { nodeValue }
child = {
< ul className = "properties" >
< li key = "assiette" >
< span className = "key" > assiette : < / s p a n >
2017-07-13 19:55:59 +00:00
< span className = "value" > { makeJsx ( explanation . assiette ) } < / s p a n >
2017-06-28 10:08:32 +00:00
< / l i >
< li key = "multiplicateur" >
< span className = "key" > multiplicateur des tranches : < / s p a n >
2017-07-13 19:55:59 +00:00
< span className = "value" > { makeJsx ( explanation . multiplicateur ) } < / s p a n >
2017-06-28 10:08:32 +00:00
< / l i >
< table className = "tranches" >
< thead >
< tr >
< th > Tranches de l ' assiette < / t h >
< th > Taux < / t h >
< / t r >
2017-07-13 19:55:59 +00:00
{ explanation . tranches . map ( ( { 'en-dessous de' : maxOnly , 'au-dessus de' : minOnly , de : min , 'à' : max , taux } ) =>
2017-06-28 10:08:32 +00:00
< tr key = { min || minOnly || 0 } >
< td >
{ maxOnly ? 'En dessous de ' + maxOnly
: minOnly ? 'Au dessus de ' + minOnly
: ` De ${ min } à ${ max } ` }
< / t d >
< td > { taux } < / t d >
< / t r >
) }
< / t h e a d >
< / t a b l e >
< / u l >
}
/ >
2017-07-13 19:55:59 +00:00
return {
evaluate ,
jsx ,
explanation ,
category : 'mecanism' ,
name : 'barème' ,
barème : 'en taux marginaux' ,
type : 'numeric'
2017-06-28 10:08:32 +00:00
}
}
2017-06-28 07:31:37 +00:00
2017-06-28 10:08:32 +00:00
export let mecanismMax = ( recurse , k , v ) => {
2017-07-11 15:39:50 +00:00
let explanation = v . map ( recurse )
2017-06-28 10:08:32 +00:00
2017-07-13 19:55:59 +00:00
let evaluate = evaluateArray ( R . max , Number . NEGATIVE _INFINITY )
let jsx = ( nodeValue , explanation ) =>
< Node
2017-06-28 10:08:32 +00:00
classes = "mecanism list maximum"
name = "le maximum de"
2017-07-13 19:55:59 +00:00
value = { nodeValue }
2017-06-28 10:08:32 +00:00
child = {
< ul >
2017-07-11 15:39:50 +00:00
{ explanation . map ( ( item , i ) =>
2017-06-28 10:08:32 +00:00
< li key = { i } >
< div className = "description" > { v [ i ] . description } < / d i v >
2017-07-13 19:55:59 +00:00
{ makeJsx ( item ) }
2017-06-28 10:08:32 +00:00
< / l i >
) }
< / u l >
2017-06-28 07:31:37 +00:00
}
2017-06-28 10:08:32 +00:00
/ >
2017-07-13 19:55:59 +00:00
return {
evaluate ,
jsx ,
explanation ,
type : 'numeric' ,
category : 'mecanism' ,
name : 'le maximum de'
2017-06-28 10:08:32 +00:00
}
}
2017-06-29 12:26:24 +00:00
export let mecanismComplement = ( recurse , k , v ) => {
if ( v . composantes ) { //mécanisme de composantes. Voir known-mecanisms.md/composantes
return decompose ( recurse , k , v )
}
2017-07-12 09:50:34 +00:00
let objectShape = { cible : false , montant : false }
let effect = ( { cible , montant } ) => {
let nulled = val ( cible ) == null
return nulled ? null : R . subtract ( val ( montant ) , R . min ( val ( cible ) , val ( montant ) ) )
}
let explanation = parseObject ( recurse , objectShape , v )
2017-06-29 12:26:24 +00:00
return {
2017-07-12 09:50:34 +00:00
evaluate : evaluateObject ( objectShape , effect ) ,
explanation ,
2017-06-29 12:26:24 +00:00
type : 'numeric' ,
category : 'mecanism' ,
name : 'complément pour atteindre' ,
jsx : < Node
classes = "mecanism list complement"
name = "complément pour atteindre"
child = {
< ul className = "properties" >
< li key = "cible" >
< span className = "key" > montant calculé : < / s p a n >
2017-07-13 19:55:59 +00:00
< span className = "value" > { makeJsx ( explanation . cible ) } < / s p a n >
2017-06-29 12:26:24 +00:00
< / l i >
< li key = "mini" >
< span className = "key" > montant à atteindre : < / s p a n >
2017-07-13 19:55:59 +00:00
< span className = "value" > { makeJsx ( explanation . montant ) } < / s p a n >
2017-06-29 12:26:24 +00:00
< / l i >
< / u l >
}
/ >
}
}
2017-06-28 10:08:32 +00:00
export let mecanismError = ( recurse , k , v ) => {
throw "Le mécanisme est inconnu !"
}