@micheeeeel/yinyangapp 1.0.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +105 -0
  2. package/dist/bundle.js +2 -1
  3. package/dist/bundle.js.LICENSE.txt +1 -0
  4. package/dist/types/adapters/yinYangAdapter.d.ts +10 -0
  5. package/dist/types/animations/AnimationsMngr.d.ts +7 -19
  6. package/dist/types/api-film.d.ts +22 -0
  7. package/dist/types/api.d.ts +48 -0
  8. package/dist/types/benchmark/runner.d.ts +5 -0
  9. package/dist/types/benchmark/scenarios.d.ts +118 -0
  10. package/dist/types/components/action-image/ActionImageModal.d.ts +42 -0
  11. package/dist/types/components/controller/YinYangController.d.ts +946 -18
  12. package/dist/types/components/controller/action-stack/ActionStackController.d.ts +149 -0
  13. package/dist/types/components/controller/action-stack/ActionStackDragHandler.d.ts +111 -0
  14. package/dist/types/components/controller/action-stack/ActionStackManager.d.ts +118 -0
  15. package/dist/types/components/controller/action-stack/ActionStackState.d.ts +169 -0
  16. package/dist/types/components/controller/actions/ActionProjectionService.d.ts +73 -0
  17. package/dist/types/components/controller/actions/ChildActionMenuController.d.ts +83 -0
  18. package/dist/types/components/controller/actions/CoreEventMenuController.d.ts +90 -0
  19. package/dist/types/components/controller/actions/radialItemMenu.d.ts +117 -0
  20. package/dist/types/components/controller/children/ChildInteractionController.d.ts +38 -0
  21. package/dist/types/components/controller/children/ChildrenOrbitService.d.ts +14 -0
  22. package/dist/types/components/controller/force-field/EventFieldLifecycleController.d.ts +104 -0
  23. package/dist/types/components/controller/force-field/EventFieldRenderer.d.ts +86 -0
  24. package/dist/types/components/controller/force-field/ForceFieldComputationService.d.ts +50 -0
  25. package/dist/types/components/controller/force-field/ForceFieldDetailsPanel.d.ts +639 -0
  26. package/dist/types/components/controller/force-field/ForceFieldLifecycleController.d.ts +53 -0
  27. package/dist/types/components/controller/force-field/ForceFieldRenderer.d.ts +67 -0
  28. package/dist/types/components/controller/force-field/types.d.ts +42 -0
  29. package/dist/types/components/controller/labels/ChildScoresDeltaRenderer.d.ts +33 -0
  30. package/dist/types/components/controller/labels/ContextLabelsRenderer.d.ts +155 -0
  31. package/dist/types/components/controller/labels/WeightPreviewRingRenderer.d.ts +61 -0
  32. package/dist/types/components/controller/odd/ChildrenOrbitManager.d.ts +25 -0
  33. package/dist/types/components/controller/odd/OddViewManager.d.ts +44 -0
  34. package/dist/types/components/controller/search/SearchPanelSynchronizer.d.ts +125 -0
  35. package/dist/types/components/controller/settings/ControllerSettingsApplier.d.ts +50 -0
  36. package/dist/types/components/controller/state/BlockingAnimationTracker.d.ts +17 -0
  37. package/dist/types/components/controller/state/YinYangControllerState.d.ts +176 -0
  38. package/dist/types/components/controller/utils/actionStackMath.d.ts +13 -0
  39. package/dist/types/components/controller/utils/actionStackReorder.d.ts +7 -0
  40. package/dist/types/components/controller/utils/childrenOrbit.d.ts +18 -0
  41. package/dist/types/components/controller/utils/cuttingLabels.d.ts +9 -0
  42. package/dist/types/components/controller/utils/eventFieldStyle.d.ts +13 -0
  43. package/dist/types/components/controller/utils/eventFieldTargets.d.ts +47 -0
  44. package/dist/types/components/controller/utils/forceFieldMetadata.d.ts +4 -0
  45. package/dist/types/components/controller/utils/forceFieldPresentation.d.ts +9 -0
  46. package/dist/types/components/controller/utils/forceFieldStyle.d.ts +10 -0
  47. package/dist/types/components/controller/utils/labelGeometry.d.ts +5 -0
  48. package/dist/types/components/controller/utils/oddCutting.d.ts +2 -0
  49. package/dist/types/components/controller/utils/svgCoordinates.d.ts +9 -0
  50. package/dist/types/components/controller/utils/svgTransform.d.ts +5 -0
  51. package/dist/types/components/controller/utils/textLayout.d.ts +2 -0
  52. package/dist/types/components/controls/VizControlsPanel.d.ts +14 -0
  53. package/dist/types/components/factory/YinYangAppFactory.d.ts +4 -6
  54. package/dist/types/components/model/YinYangModel.d.ts +4 -30
  55. package/dist/types/components/panel/DiagramPanelBridge.d.ts +34 -0
  56. package/dist/types/components/panel/PanelManager.d.ts +150 -0
  57. package/dist/types/components/search/GlobalSearchController.d.ts +396 -0
  58. package/dist/types/components/stack-nav/StackNavOverlay.d.ts +82 -0
  59. package/dist/types/components/view/BorderDrawer.d.ts +203 -13
  60. package/dist/types/components/view/SpikeDrawer.d.ts +37 -31
  61. package/dist/types/components/view/ViewInitializer.d.ts +438 -2
  62. package/dist/types/components/view/YinYangDrawer.d.ts +414 -11
  63. package/dist/types/config/animationConfig.d.ts +37 -0
  64. package/dist/types/config/deltaColors.d.ts +64 -0
  65. package/dist/types/config/labelStyleConfig.d.ts +50 -0
  66. package/dist/types/data/OddCategoryColors.d.ts +12 -2
  67. package/dist/types/data/adverse-action-planner.d.ts +51 -0
  68. package/dist/types/data/adverse-action-planner.test.d.ts +1 -0
  69. package/dist/types/data/amplifier-engine.d.ts +107 -0
  70. package/dist/types/data/amplifier-engine.test.d.ts +1 -0
  71. package/dist/types/data/combo-engine.d.ts +94 -0
  72. package/dist/types/data/combo-engine.test.d.ts +1 -0
  73. package/dist/types/data/odd_generic_descriptions.d.ts +4 -0
  74. package/dist/types/data/odd_labels.d.ts +5 -0
  75. package/dist/types/data/yasuni_actions.d.ts +47 -0
  76. package/dist/types/data/yasuni_adverse_actions.d.ts +2 -0
  77. package/dist/types/data/yasuni_adverse_key_events.d.ts +2 -0
  78. package/dist/types/data/yasuni_cause.d.ts +33 -0
  79. package/dist/types/data/yasuni_graph.d.ts +22 -0
  80. package/dist/types/data/yasuni_key_events.d.ts +61 -0
  81. package/dist/types/data/yasuni_propagation_layers.d.ts +3 -0
  82. package/dist/types/interfaces/IActions.d.ts +1 -0
  83. package/dist/types/interfaces/ICauseGraph.d.ts +9 -0
  84. package/dist/types/interfaces/ICauseModel.d.ts +33 -0
  85. package/dist/types/interfaces/IGraphicsStrategy.d.ts +9 -5
  86. package/dist/types/interfaces/IPropagationLayers.d.ts +27 -0
  87. package/dist/types/interfaces/IViewData.d.ts +12 -0
  88. package/dist/types/interfaces/IYinYangAppFactory.d.ts +3 -3
  89. package/dist/types/interfaces/IYinYangController.d.ts +301 -6
  90. package/dist/types/interfaces/IYinYangGeometry.d.ts +43 -0
  91. package/dist/types/interfaces/IYinYangInternalModel.d.ts +34 -0
  92. package/dist/types/interfaces/IYinYangModel.d.ts +3 -11
  93. package/dist/types/main.d.ts +9 -0
  94. package/dist/types/utils/actionImages.d.ts +14 -0
  95. package/dist/types/utils/actionPropagation.d.ts +74 -0
  96. package/dist/types/utils/appMode.d.ts +5 -0
  97. package/dist/types/utils/causeGraph.d.ts +6 -0
  98. package/dist/types/utils/causeMetrics.d.ts +26 -0
  99. package/dist/types/utils/chainCardHeight.d.ts +27 -0
  100. package/dist/types/utils/d3/D3Element.d.ts +2 -2
  101. package/dist/types/utils/d3/D3GraphicsStrategy.d.ts +21 -4
  102. package/dist/types/utils/deltaChips.d.ts +15 -0
  103. package/dist/types/utils/deltaLabels.d.ts +54 -0
  104. package/dist/types/utils/facetteImages.d.ts +1 -0
  105. package/dist/types/utils/geometryUtils.d.ts +0 -1
  106. package/dist/types/utils/hierBadge.d.ts +44 -0
  107. package/dist/types/utils/idleSphereImage.d.ts +8 -0
  108. package/dist/types/utils/keyEventImages.d.ts +41 -0
  109. package/dist/types/utils/oddLegend.d.ts +30 -0
  110. package/dist/types/utils/positionalEfficiency.d.ts +16 -0
  111. package/dist/types/utils/yinYangWatermark.d.ts +29 -0
  112. package/package.json +27 -12
  113. package/dist/index.html +0 -1
  114. package/dist/types/data/coupe_rase_Orangs-outans/data_Kalimantan.d.ts +0 -3
  115. package/dist/types/data/coupe_rase_Orangs-outans/data_PT_Mayawana_Persada.d.ts +0 -3
  116. package/dist/types/data/data_institu_bancaire.d.ts +0 -3
  117. package/dist/types/interfaces/IOddItem.d.ts +0 -6
  118. package/dist/types/script.d.ts +0 -13
@@ -0,0 +1,51 @@
1
+ import type { ComboSlot } from "./yasuni_actions";
2
+ /**
3
+ * Candidat à l'insertion — la projection commune d'une action adverse
4
+ * (combos, jamais d'entrave différée) et d'un Événement adverse (entrave
5
+ * différée, jamais de combos). Une ActionDefinition est assignable telle
6
+ * quelle ; une KeyEventDefinition se projette en
7
+ * `{ id, delayedEffect: keyEvent }` (elle porte directement
8
+ * targetedActionIds/withinNextN).
9
+ */
10
+ export interface AdverseCandidate {
11
+ id: string;
12
+ combos?: ComboSlot[];
13
+ delayedEffect?: {
14
+ targetedActionIds: string[];
15
+ withinNextN?: number;
16
+ };
17
+ }
18
+ export interface PlannerStackItem {
19
+ actionId: string;
20
+ slotIndex: number;
21
+ }
22
+ export interface AdversePlacement {
23
+ actionId: string;
24
+ /** Slot d'insertion au moment où cette insertion est appliquée (les
25
+ * précédentes du plan étant déjà faites) — pas un slot final. */
26
+ slotIndex: number;
27
+ }
28
+ export interface PlanAdverseInsertionsParams {
29
+ /** Items adverses disponibles (pas encore dans la pile). */
30
+ candidates: AdverseCandidate[];
31
+ /** Pile courante, tous types d'items confondus. */
32
+ stack: PlannerStackItem[];
33
+ count: number;
34
+ /** Générateur dans [0, 1) — injectable pour des tests déterministes. */
35
+ rng?: () => number;
36
+ }
37
+ /** Tire une graine au hasard puis absorbe sa chaîne (prérequis d'abord,
38
+ * dépendantes ensuite) avant de retirer une nouvelle graine — une "graine"
39
+ * sans aucun lien combo forme à elle seule un groupe d'un seul élément.
40
+ * Les groupes sont ce qui distingue, au placement (§3), un bloc d'actions
41
+ * liées d'un trou entre deux groupes sans rapport. */
42
+ export declare function selectAdverseChainGroups(candidates: AdverseCandidate[], count: number, rng: () => number): AdverseCandidate[][];
43
+ /** Version à plat de {@link selectAdverseChainGroups}, dans l'ordre des
44
+ * `candidates` d'origine — sans information de groupe. */
45
+ export declare function selectAdverseChain(candidates: AdverseCandidate[], count: number, rng: () => number): AdverseCandidate[];
46
+ /** Profondeur = longueur du plus long chemin de prérequis adverses menant
47
+ * à l'action (0 sans prérequis). Un cycle, jamais attendu au catalogue,
48
+ * est coupé à la profondeur courante plutôt que de boucler. */
49
+ export declare function adverseDepth(action: AdverseCandidate, pool: Map<string, AdverseCandidate>, visiting?: Set<string>): number;
50
+ export declare function orderAdverseActions(picked: AdverseCandidate[], rng: () => number): AdverseCandidate[];
51
+ export declare function planAdverseInsertions(params: PlanAdverseInsertionsParams): AdversePlacement[];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,107 @@
1
+ import type { KeyEventDefinition, KeyEventEffect } from "./yasuni_key_events";
2
+ import type { ActionStackItem } from "../components/controller/action-stack/ActionStackState";
3
+ /** Ce qu'une source d'effet différé doit fournir — la partie "effet" d'une
4
+ * KeyEventDefinition (Événement Clé ou adverse, seule espèce de source). */
5
+ export interface AmplifierSourceDefinition {
6
+ targetedActionIds: string[];
7
+ withinNextN?: number;
8
+ effect: KeyEventEffect;
9
+ }
10
+ export interface AmplifierResult {
11
+ /** KeyEventDefinition.id — résoluble dans yasuniKeyEventMap (fusion des
12
+ * catalogues positif et adverse) pour distinguer les deux au rendu. */
13
+ sourceId: string;
14
+ name: string;
15
+ /** Bonus de score EFFECTIF déjà réduit selon la position (voir
16
+ * positionalBonus) — jamais le nominal du catalogue tel quel.
17
+ * Fractionnaire en général : le score est une échelle continue. */
18
+ scoreBonus: number;
19
+ /** Bonus de poids EFFECTIF, arrondi PAR SOURCE (pas sur le total) :
20
+ * le poids est une échelle entière, et arrondir ici garantit que la
21
+ * valeur affichée sur la carte est exactement celle qui s'applique —
22
+ * y compris un 0 honnête en bord de fenêtre. */
23
+ weightBonus: number;
24
+ }
25
+ /** Détail de l'amplification d'une action ciblée par une source —
26
+ * miroir de PrereqBreakdown côté combos, pour l'affichage carte. */
27
+ export interface AmplifierTargetBreakdown {
28
+ id: string;
29
+ /** Slot où l'action a été jouée après la source — absent si jamais
30
+ * jouée dans la fenêtre withinNextN. */
31
+ slotIndex?: number;
32
+ /** Efficacité positionnelle Beta(t) ∈ [0, 1], 0 si non jouée dans la fenêtre. */
33
+ positional: number;
34
+ /** true si l'action a été jouée après la source ET dans sa fenêtre
35
+ * withinNextN — false confond volontairement "jamais jouée" et "jouée
36
+ * mais hors fenêtre" : dans les deux cas elle ne rapporte rien aujourd'hui. */
37
+ played: boolean;
38
+ /** Mêmes conventions qu'AmplifierResult (0 quand played=false). */
39
+ effectiveScoreBonus: number;
40
+ effectiveWeightBonus: number;
41
+ }
42
+ /**
43
+ * Retourne toutes les sources qui touchent `targetItem` : Événements
44
+ * (kind="keyEvent", Clés comme adverses),
45
+ * actifs (cochés), positionnés AVANT lui dans la pile (slotIndex strictement
46
+ * inférieur — recalculé dynamiquement à chaque appel, donc toujours à jour
47
+ * après un glisser-déposer), et dont la liste `targetedActionIds` contient
48
+ * l'actionId de `targetItem` — à condition que `targetItem` reste dans la
49
+ * fenêtre `withinNextN` de la source (si définie), pendant inverse du
50
+ * `withinLastN` des combos. Le bonus retourné est déjà réduit selon la
51
+ * position de `targetItem` dans cette fenêtre (voir positionalBonus) : le
52
+ * catalogue ne donne que le plafond, atteint au pic de la courbe.
53
+ *
54
+ * `targetItem` lui-même n'a pas besoin d'être actif : l'appelant décide déjà
55
+ * s'il calcule un delta pour un item actif ou non (mêmes conventions que
56
+ * evaluateCombo/composeEffectiveDelta).
57
+ */
58
+ export declare function evaluateAmplifiers(targetItem: ActionStackItem, allItems: ActionStackItem[], activeItemIds: Set<string>, keyEventMap: Map<string, KeyEventDefinition>): AmplifierResult[];
59
+ /**
60
+ * true si `keyEventItem` (un Événement Clé joué, kind="keyEvent") amplifie
61
+ * ACTUELLEMENT au moins une de ses actions ciblées — mêmes conditions que
62
+ * isAmplifying mais lues depuis l'événement plutôt que depuis l'action : sert
63
+ * à distinguer visuellement un bloc Événement Clé "actif" (au moins une
64
+ * action ciblée jouée après lui, active, dans sa fenêtre withinNextN) d'un
65
+ * bloc simplement présent (joué mais rien ne l'active encore) — le bloc
66
+ * lui-même reste affiché dans les deux cas, voir buildKeyEventBlocksForComponent.
67
+ */
68
+ export declare function isKeyEventCurrentlyActive(keyEventItem: ActionStackItem, allItems: ActionStackItem[], activeItemIds: Set<string>, keyEventMap: Map<string, KeyEventDefinition>): boolean;
69
+ /**
70
+ * Répartition par action ciblée d'une source RÉELLEMENT placée dans la pile
71
+ * (`sourceItem`) — une entrée par `targetedActionIds`, y compris les actions
72
+ * jamais jouées ou hors fenêtre (played=false). Miroir des `prereqBreakdowns`
73
+ * de ComboResult, pour l'affichage carte (position %, icône "barres de gain
74
+ * par slot"). `allItems` doit inclure TOUS les items de la pile, actifs ou
75
+ * non (même convention que playedHistory côté combos — "joué" ne dépend pas
76
+ * de la case à cocher) ; si plusieurs occurrences d'une même action existent
77
+ * après la source, seule la plus proche (première jouée après elle) compte,
78
+ * symétrique du lastIndexOf des combos.
79
+ */
80
+ export declare function getAmplifierTargetBreakdown(source: AmplifierSourceDefinition, sourceItem: ActionStackItem, allItems: ActionStackItem[]): AmplifierTargetBreakdown[];
81
+ /**
82
+ * Compose le delta de score effectif avec les sources déclenchées — somme de
83
+ * tous les scoreBonus, déjà réduits selon la position (commutatif par
84
+ * construction), appliquée dans la direction du delta (voir
85
+ * applyDirectionalBonus). Appliqué APRÈS composeEffectiveDelta (combos) —
86
+ * jamais sur le baseDelta brut.
87
+ */
88
+ export declare function composeAmplifiedDelta(effectiveDelta: number, results: AmplifierResult[]): number;
89
+ /**
90
+ * Compose un weightDelta brut avec les sources déclenchées — somme des
91
+ * weightBonus (déjà entiers, arrondis par source à l'évaluation), appliquée
92
+ * dans la direction du weightDelta de l'action : une action qui allège le
93
+ * poids est renforcée (ou entravée) vers l'allègement, une action qui
94
+ * l'alourdit vers l'alourdissement, et une action sans effet de poids n'en
95
+ * gagne pas. Entier par construction : plus d'arrondi final susceptible
96
+ * d'absorber silencieusement l'effet d'une source.
97
+ */
98
+ export declare function composeAmplifiedWeightDelta(weightDelta: number, results: AmplifierResult[]): number;
99
+ /**
100
+ * L'unique item actif de kind="action", s'il y en a exactement un — jamais un
101
+ * Événement Clé, qui n'a pas de "satellite source" au sens propre. Utilisé
102
+ * partout où le code déduit "l'action actuellement active" à partir de la
103
+ * pile : sans ce filtre, un Événement Clé actif se fait passer pour l'action
104
+ * active dès qu'il est seul dans la pile (son nom/son id se substituent alors
105
+ * à ceux de l'action qu'il est censé amplifier).
106
+ */
107
+ export declare function findSoleActiveAction(items: ActionStackItem[]): ActionStackItem | undefined;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,94 @@
1
+ import type { ActionDefinition } from "./yasuni_actions";
2
+ /**
3
+ * Intervalles du multiplicateur combo.
4
+ *
5
+ * Le multiplicateur est une interpolation linéaire entre un plancher et un
6
+ * plafond, pilotée par prereqAvgRatio ∈ [0, 1] :
7
+ *
8
+ * m = plancher + (plafond − plancher) × prereqAvgRatio
9
+ *
10
+ * Les deux types partagent la même largeur d'intervalle (1) et se touchent en
11
+ * ×1, le point neutre "rien de spécial ne se passe" :
12
+ *
13
+ * - bonus [1, 2] → m = 1 + avgRatio
14
+ * Les requires sont des DÉCLENCHEURS. Aucun joué → ×1 (neutre, pas de
15
+ * malus) ; tous parfaits et bien placés → ×2.
16
+ * - dangereux [0, 1] → m = avgRatio
17
+ * Les requires sont des PROTECTEURS et le risque est permanent
18
+ * (triggered = true en continu). Protection parfaite → ×1 (risque
19
+ * annulé) ; aucune protection → ×0 (l'action ne rapporte plus rien).
20
+ *
21
+ * Largeurs égales de part et d'autre : un bonus et un risque de qualité égale
22
+ * s'annulent exactement dans composeEffectiveDelta, ce qui rend l'arbitrage
23
+ * lisible sans avoir à connaître un barème. Le multiplicateur affiché EST
24
+ * l'avgRatio (au décalage de plancher près) — aucune traduction mentale.
25
+ */
26
+ /** Détail de la contribution d'un prérequis au multiplicateur combo. */
27
+ export interface PrereqBreakdown {
28
+ id: string;
29
+ label?: string;
30
+ ratio: number;
31
+ positional: number;
32
+ factor: number;
33
+ /** true si le prérequis/protecteur a déjà été joué au moins une fois (s >= 0),
34
+ * indépendamment de sa performance. Permet à l'UI de distinguer "jamais joué"
35
+ * (ratio/positional = 0 par convention, sans signification réelle) d'un
36
+ * prérequis réellement joué mais sous-performant. */
37
+ played: boolean;
38
+ }
39
+ /** Réglages "Combos" du panneau de contrôle — voir YinYangControllerState.combos.
40
+ * Bornés (false) par défaut : comportement actuel. */
41
+ export interface ComboEngineSettings {
42
+ /** Lève le plafond à 1 sur le ratio des prérequis DÉCLENCHEURS (non
43
+ * dangereux), autorisant une cascade de combos à dépasser ×2. */
44
+ uncappedChainedPerformance?: boolean;
45
+ /** Lève le plafond à 1 sur le ratio des prérequis PROTECTEURS d'un combo
46
+ * dangereux, permettant à m = avgRatio de dépasser ×1. */
47
+ dangerousComboCanBecomeBonus?: boolean;
48
+ }
49
+ export interface ComboResult {
50
+ triggered: boolean;
51
+ name?: string;
52
+ comboId?: string;
53
+ description?: string;
54
+ type?: string;
55
+ effectiveDelta: number;
56
+ baseDelta: number;
57
+ deltaMultiplier: number;
58
+ maxDeltaMultiplier: number;
59
+ prereqAvgRatio?: number;
60
+ prereqBreakdowns?: PrereqBreakdown[];
61
+ requires?: string[];
62
+ withinLastN?: number;
63
+ }
64
+ /**
65
+ * Évalue tous les slots combo d'une action et retourne ceux qui sont déclenchés.
66
+ * Tous les slots satisfaits sont retournés (pas d'arrêt au premier).
67
+ *
68
+ * @param action L'action que le joueur est sur le point de jouer
69
+ * @param playedHistory Les IDs des actions jouées avant celle-ci (ordre chronologique)
70
+ * @param prereqRatioMap (optionnel) actionId → ratio de performance (actualDelta / baseDelta,
71
+ * clampé dans [0, 1]). Si fourni, le multiplicateur est pondéré par la
72
+ * performance réelle des prérequis :
73
+ * effectiveDm = (dangereux ? 0 : 1) + avg(ratio × Beta(t))
74
+ * où t est la position normalisée du prérequis dans la fenêtre.
75
+ * @returns Tableau de ComboResult pour chaque slot (vide si aucun combo défini)
76
+ */
77
+ export declare function evaluateCombo(action: ActionDefinition, playedHistory: string[], prereqRatioMap?: Map<string, number>, settings?: ComboEngineSettings): ComboResult[];
78
+ /**
79
+ * Compose le delta effectif à partir de plusieurs résultats combo (formule additive centrée).
80
+ * Chaque multiplicateur exprime un écart par rapport à 1 (neutre).
81
+ *
82
+ * Formule : baseDelta × (Σ multiplicateurs − (n − 1))
83
+ *
84
+ * Exemples :
85
+ * - 1 combo ×1.4 → baseDelta × 1.4
86
+ * - 2 combos ×1.4 + ×-0.5 → baseDelta × (1.4 + (−0.5)) = baseDelta × 0.9
87
+ * - aucun combo → baseDelta × 1 = baseDelta
88
+ */
89
+ export declare function composeEffectiveDelta(baseDelta: number, results: ComboResult[]): number;
90
+ /**
91
+ * Retourne true si l'action donnée est requise par au moins
92
+ * une autre action dans le catalogue.
93
+ */
94
+ export declare function isPrerequisiteOf(actionId: string, allActions: ActionDefinition[]): boolean;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export interface OddGenericEntry {
2
+ description: string;
3
+ }
4
+ export declare const oddGenericDescriptionsFr: Record<string, OddGenericEntry>;
@@ -0,0 +1,5 @@
1
+ export type OddLabelEntry = {
2
+ label: string;
3
+ shortLabel: string;
4
+ };
5
+ export declare const oddLabelsFr: Record<string, OddLabelEntry>;
@@ -0,0 +1,47 @@
1
+ export interface ComboCondition {
2
+ requires?: string[];
3
+ withinLastN?: number;
4
+ }
5
+ export interface ComboEffect {
6
+ /**
7
+ * Seul `type` décide de l'amplitude : "dangereux" parcourt [0, 1] (les
8
+ * requires sont des protecteurs), les autres [1, 2] (les requires sont des
9
+ * déclencheurs). Le curseur dans l'intervalle est la performance réelle des
10
+ * prérequis — voir combo-engine.ts. Pas de palier à choisir au cas par cas.
11
+ */
12
+ type: "preparation" | "exploitation" | "stabilisation" | "dangereux";
13
+ name: string;
14
+ comboId: string;
15
+ description: string;
16
+ }
17
+ export interface ComboSlot {
18
+ condition: ComboCondition;
19
+ effect: ComboEffect;
20
+ }
21
+ export interface ActionDefinition {
22
+ id: string;
23
+ name: string;
24
+ shortDescription: string;
25
+ description: string;
26
+ baseDelta: number;
27
+ targeting: "unique" | "shared";
28
+ combos?: ComboSlot[];
29
+ /**
30
+ * Variation d'importance (poids) appliquée uniquement au satellite ciblé
31
+ * au moment du jeu — jamais aux autres satellites référençant la même
32
+ * action, jamais par propagation. Volontairement plafonné à ±1 : les
33
+ * ajustements de poids plus importants sont réservés aux futures actions
34
+ * "cercle global" (portée multi-satellites, tier super-pouvoir).
35
+ */
36
+ weightDelta?: number;
37
+ /** Acteur à l'origine d'une action adverse (pouvoir politique, industrie…),
38
+ * affiché en note de provenance sur sa carte. */
39
+ origin?: string;
40
+ }
41
+ /**
42
+ * Une action adverse dégrade directement son satellite : c'est le signe de
43
+ * son baseDelta, pas un drapeau à part, qui la distingue — une seule source
44
+ * de vérité pour le moteur (propagation, combos) comme pour l'affichage.
45
+ */
46
+ export declare function isAdverseAction(action: ActionDefinition): boolean;
47
+ export declare const yasuniActions: ActionDefinition[];
@@ -0,0 +1,2 @@
1
+ import type { ActionDefinition } from "./yasuni_actions";
2
+ export declare const yasuniAdverseActions: ActionDefinition[];
@@ -0,0 +1,2 @@
1
+ import type { KeyEventDefinition } from "./yasuni_key_events";
2
+ export declare const yasuniAdverseKeyEvents: KeyEventDefinition[];
@@ -0,0 +1,33 @@
1
+ export interface Cutting {
2
+ id: number;
3
+ name: string;
4
+ score?: number;
5
+ /** Importance du satellite dans sa facette ; chaque satellite vaut 1 par défaut. */
6
+ weight?: number;
7
+ /** Présentation succincte du problème ou enjeu représenté par ce cutting. */
8
+ description?: string;
9
+ actionIds: string[];
10
+ }
11
+ export interface ODD {
12
+ id: string;
13
+ name: string;
14
+ /** Présentation contextuelle du rôle de cet ODD dans la composante parente. */
15
+ description?: string;
16
+ cuttings: Cutting[];
17
+ }
18
+ export interface Composante {
19
+ id: string;
20
+ name: string;
21
+ orientation?: "yin" | "yang";
22
+ /** Vue d'ensemble des enjeux et des dynamiques propres à cette composante. */
23
+ description?: string;
24
+ odds: ODD[];
25
+ }
26
+ export interface Sphere {
27
+ name: string;
28
+ description: string;
29
+ composantes: Composante[];
30
+ }
31
+ export declare const yasuniSphere: Sphere;
32
+ /** Backward-compatible alias — all existing callers continue to work unchanged. */
33
+ export declare const yasuniCause: Composante[];
@@ -0,0 +1,22 @@
1
+ import { CauseGraph } from "../interfaces/ICauseGraph";
2
+ /**
3
+ * Yasuní sparse interconnection matrix W (adjacency list form) — SIGNED.
4
+ *
5
+ * Node format: componentId::oddId (contextualized SDG node).
6
+ * w in [-1..+1], expert-driven bands (absolute value):
7
+ * - 0.2 weak
8
+ * - 0.4 moderate
9
+ * - 0.6 strong
10
+ * - 0.8 structuring
11
+ *
12
+ * Sign convention:
13
+ * - w > 0 : A↑ causes B↑ (same direction)
14
+ * - w < 0 : A↑ causes B↓ (opposite direction)
15
+ *
16
+ * NOTE: This file intentionally includes a few additional contextualized nodes (e.g.,
17
+ * biodiversity_habitat_fragmentation::ODD_2, indigenous_rights::ODD_3/4/11) to show that
18
+ * the node count is not constrained to 17. If your engine builds node state strictly from
19
+ * yasuni_cause.ts, add these nodes there (or have the engine lazily init missing nodes).
20
+ */
21
+ export declare const yasuniInterconnectionGraph: CauseGraph;
22
+ export default yasuniInterconnectionGraph;
@@ -0,0 +1,61 @@
1
+ export interface KeyEventEffect {
2
+ /**
3
+ * Bonus ADDITIF de score (en points), au pic de la fenêtre positionnelle —
4
+ * réduit vers 0 aux bords, voir positionalBonus (amplifier-engine.ts).
5
+ * Appliqué dans la direction du delta effectif de l'action (après combos),
6
+ * jamais sur une action au delta nul. Additif et non multiplicatif : un
7
+ * ratio réduit par la position devenait fractionnaire et se faisait
8
+ * absorber par l'arrondi du poids ; un montant en points permet aussi à
9
+ * un futur malus (bonus négatif) de s'annuler exactement avec lui.
10
+ */
11
+ scoreBonus: number;
12
+ /**
13
+ * Bonus ADDITIF de poids (en points entiers), au pic de la fenêtre.
14
+ * Renforce le weightDelta de l'action ciblée dans sa propre direction
15
+ * (alléger ou alourdir) — sans effet sur une action sans weightDelta.
16
+ * L'arrondi à l'entier se fait par événement à l'évaluation, jamais sur
17
+ * un total fractionnaire : ce que la carte affiche est ce qui s'applique.
18
+ */
19
+ weightBonus: number;
20
+ }
21
+ export interface KeyEventDefinition {
22
+ id: string;
23
+ name: string;
24
+ shortDescription: string;
25
+ description: string;
26
+ /** Facette (Composante.id) depuis laquelle l'événement se déclenche. */
27
+ originComposanteId: string;
28
+ /**
29
+ * Actions amplifiées (par id), même logique que ComboCondition.requires.
30
+ * Cohérence thématique obligatoire avec la facette d'origine.
31
+ */
32
+ targetedActionIds: string[];
33
+ /**
34
+ * Fenêtre temporelle AVANT laquelle l'amplification s'arrête — pendant
35
+ * inverse de ComboCondition.withinLastN : une action ciblée jouée plus de
36
+ * withinNextN slots après l'événement n'est plus amplifiée. Oblige le
37
+ * joueur à réserver des emplacements libres après l'événement plutôt que
38
+ * de le placer systématiquement tout en bas de la pile.
39
+ */
40
+ withinNextN?: number;
41
+ effect: KeyEventEffect;
42
+ /** Acteur à l'origine d'un Événement adverse (pouvoir politique,
43
+ * industrie…), affiché en note de provenance sur son bloc — les
44
+ * Événements Clés positifs n'en ont pas (ils émanent de la cause). */
45
+ origin?: string;
46
+ }
47
+ /**
48
+ * Un Événement adverse est une KeyEventDefinition ordinaire dont l'effet est
49
+ * un MALUS (bonus négatifs) — même critère de signe qu'isAdverseAction, pas
50
+ * un drapeau. Catalogue séparé (yasuni_adverse_key_events.ts), jamais listé
51
+ * dans yasuniKeyEvents : le menu radial du cercle central et l'arbre
52
+ * RECHERCHE, qui itèrent ce tableau, l'ignorent donc structurellement — seul
53
+ * yasuniKeyEventMap (moteur, rendu de la pile) fusionne les deux catalogues.
54
+ */
55
+ export declare function isAdverseKeyEvent(keyEvent: KeyEventDefinition): boolean;
56
+ export declare const yasuniKeyEvents: KeyEventDefinition[];
57
+ /** Lookup O(1) par id, même convention que les autres catalogues — fusionne
58
+ * Événements Clés ET Événements adverses : le moteur et le rendu de la pile
59
+ * résolvent les deux ici, tandis que les surfaces utilisateur (menu radial,
60
+ * arbre RECHERCHE) itèrent yasuniKeyEvents, sans les adverses. */
61
+ export declare const yasuniKeyEventMap: Map<string, KeyEventDefinition>;
@@ -0,0 +1,3 @@
1
+ import { PropagationLayersConfig } from "../interfaces/IPropagationLayers";
2
+ export declare const yasuniPropagationLayers: PropagationLayersConfig;
3
+ export default yasuniPropagationLayers;
@@ -0,0 +1 @@
1
+ export type { ActionDefinition, ComboSlot, ComboCondition, ComboEffect, } from "../data/yasuni_actions";
@@ -0,0 +1,9 @@
1
+ export type CauseNodeId = `${string}::${string}`;
2
+ export interface CauseEdge {
3
+ to: CauseNodeId;
4
+ w: number;
5
+ rationale?: string;
6
+ /** Entry-point cutting in the target ODD's intra chain (Phase 6+7 / incoming-mode entry). */
7
+ targetedCutting?: number;
8
+ }
9
+ export type CauseGraph = Record<CauseNodeId, CauseEdge[]>;
@@ -0,0 +1,33 @@
1
+ import { YinYangOrientation } from "./IYinYangInternalModel";
2
+ export interface CauseOdd {
3
+ id: string;
4
+ name?: string;
5
+ shortName?: string;
6
+ libelle?: string;
7
+ libelleCourt?: string;
8
+ oddCutting: CauseOddCutting[];
9
+ }
10
+ export interface CauseOddCutting {
11
+ id: number;
12
+ name?: string;
13
+ shortName?: string;
14
+ libelle: string;
15
+ libelleCourt?: string;
16
+ score: number;
17
+ weight: number;
18
+ }
19
+ export interface CauseComponent {
20
+ id: string;
21
+ name?: string;
22
+ shortName?: string;
23
+ description?: string;
24
+ orientation: YinYangOrientation;
25
+ odds: CauseOdd[];
26
+ /** Somme brute des poids de tous les satellites de la facette. */
27
+ perimeterWeight: number;
28
+ }
29
+ export interface Cause {
30
+ id: string;
31
+ name: string;
32
+ components: CauseComponent[];
33
+ }
@@ -6,18 +6,22 @@ export interface IGraphicsStrategy {
6
6
  defs: D3Element;
7
7
  initialize(svgSelector: string, w: number, svgElement?: IGraphicElement, defElement?: IGraphicElement): IGraphicElement;
8
8
  resizeGroup(group: IGraphicElement, scaleFactor: number, centerX: Number, centerY: Number): void;
9
- drawArc(parent: IGraphicElement, cx: number, cy: number, innerRadius: number, outerRadius: number, startAngle: number, endAngle: number, fill: string): void;
10
- drawArc(parent: IGraphicElement, cx: number, cy: number, innerRadius: number, outerRadius: number, startAngle: number, endAngle: number, fill: string): void;
9
+ drawArc(parent: IGraphicElement, cx: number, cy: number, innerRadius: number, outerRadius: number, startAngle: number, endAngle: number, fill: string, cornerRadius?: number): IGraphicElement;
11
10
  drawCircle(parent: IGraphicElement, cx: number, cy: number, radius: number, fill: string, opacity?: number): IGraphicElement;
12
11
  createLinearGradient(id: string, x1: string, y1: string, x2: string, y2: string, stops: {
13
12
  offset: string;
14
13
  color: string;
15
14
  opacity: number;
16
15
  }[], gradientUnits: string): IGraphicElement;
17
- createYinOrYangArcMask(id: string, cx: number, cy: number, innerRadius: number, outerRadius: number, startAngle: number, endAngle: number, type: "yin" | "yang"): void;
16
+ createRadialGradient(id: string, cx: string, cy: string, r: string, stops: {
17
+ offset: string;
18
+ color: string;
19
+ opacity: number;
20
+ }[], gradientUnits: string): IGraphicElement;
21
+ createYinOrYangArcMask(id: string, cx: number, cy: number, innerRadius: number, outerRadius: number, startAngle: number, endAngle: number, type: "yin" | "yang", blendOpacity?: number): string;
18
22
  createBorderMask(id: string, cx: number, cy: number, innerRadius: number, outerRadius: number): void;
19
23
  changeBorderColors(gradient: any, duration: number, colors: string[]): void;
20
24
  drawLineWithGradient(parent: IGraphicElement, x1: number, y1: number, x2: number, y2: number, gradientId: string): void;
21
- createUnderlyingCircleGradient(id: string, color: string): void;
22
- createUnderlyingCircleWithArcMask(maskId: string, gradientId: string, parent: IGraphicElement, cx: number, cy: number, radius: number): void;
25
+ createUnderlyingCircleGradient(id: string, color: string, spread?: number, intensity?: number): string;
26
+ createUnderlyingCircleWithArcMask(maskId: string | undefined, gradientId: string, parent: IGraphicElement, cx: number, cy: number, radius: number): void;
23
27
  }
@@ -0,0 +1,27 @@
1
+ export interface LocalCuttingEdgeRef {
2
+ cuttingId: number;
3
+ rationale?: string;
4
+ }
5
+ export interface LocalCuttingEdge {
6
+ toCuttingId: number;
7
+ w: number;
8
+ rationale?: string;
9
+ /** Pointers to next cuttings in the causal chain — resolved from the same flat array. */
10
+ targetedCuttings?: LocalCuttingEdgeRef[];
11
+ }
12
+ export interface BridgeCuttingEdge {
13
+ fromComponentId?: string;
14
+ fromOddId: string;
15
+ fromCuttingId: number;
16
+ toComponentId?: string;
17
+ toOddId: string;
18
+ toCuttingId: number;
19
+ w: number;
20
+ rationale?: string;
21
+ }
22
+ export interface PropagationLayersConfig {
23
+ intraOddByComponent: Record<string, Record<string, LocalCuttingEdge[]>>;
24
+ bridgeEdgesByComponent: Record<string, BridgeCuttingEdge[]>;
25
+ localK?: number;
26
+ bridgeK?: number;
27
+ }
@@ -2,4 +2,16 @@ export interface IViewData {
2
2
  minEdge: number;
3
3
  containerId: string;
4
4
  borderAnimationDuration: number;
5
+ /** Poids de ce satellite relatif à la moyenne de sa fratrie (1 = moyenne),
6
+ * déjà utilisé pour dériver minEdge dans YinYangController.createYinYangChildren.
7
+ * Reporté ici tel quel pour que le satellite compense sa propre taille de
8
+ * police (voir YinYangDrawer.renderChildStateLabel) sans redériver le
9
+ * calcul. Absent pour les patterns qui ne sont pas des satellites. */
10
+ weightRatio?: number;
11
+ /** Poids brut (échelle absolue [WEIGHT_MIN, WEIGHT_MAX], voir causeMetrics.ts),
12
+ * distinct de weightRatio qui est relatif à la fratrie : sert à savoir
13
+ * combien de graduations remplir dans la jauge de poids du satellite
14
+ * (voir YinYangDrawer.renderChildWeightGauge). Absent pour les patterns
15
+ * qui ne sont pas des satellites. */
16
+ weight?: number;
5
17
  }
@@ -2,14 +2,14 @@ import { YinYangModel } from "../components/model/YinYangModel";
2
2
  import { IYinYangView } from "./IYinYangView";
3
3
  import { IYinYangController } from "./IYinYangController";
4
4
  import { AnimationsMngr } from "../animations/AnimationsMngr";
5
- import { IOddItem } from "../interfaces/IOddItem";
5
+ import { YinYangInternalModel } from "./IYinYangInternalModel";
6
6
  import { IGraphicsStrategy } from "./IGraphicsStrategy";
7
7
  import { IViewData } from "./IViewData";
8
8
  export interface IYinYangAppFactory {
9
9
  graphicsStrategy: IGraphicsStrategy;
10
10
  animator: AnimationsMngr;
11
- create(modelData: IOddItem[], viewData: IViewData, isEnemy: boolean, parentKey?: string | null): IYinYangController;
12
- createModel(dataSubset: IOddItem[], isEnemy: boolean, parentKey?: string | null): YinYangModel;
11
+ create(modelData: YinYangInternalModel, viewData: IViewData, parentKey?: string | null): IYinYangController;
12
+ createModel(dataSubset: YinYangInternalModel, parentKey?: string | null): YinYangModel;
13
13
  createView(): IYinYangView;
14
14
  createController(model: YinYangModel, view: IYinYangView): IYinYangController;
15
15
  createAnimationsManager(): AnimationsMngr;