@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.
- package/README.md +105 -0
- package/dist/bundle.js +2 -1
- package/dist/bundle.js.LICENSE.txt +1 -0
- package/dist/types/adapters/yinYangAdapter.d.ts +10 -0
- package/dist/types/animations/AnimationsMngr.d.ts +7 -19
- package/dist/types/api-film.d.ts +22 -0
- package/dist/types/api.d.ts +48 -0
- package/dist/types/benchmark/runner.d.ts +5 -0
- package/dist/types/benchmark/scenarios.d.ts +118 -0
- package/dist/types/components/action-image/ActionImageModal.d.ts +42 -0
- package/dist/types/components/controller/YinYangController.d.ts +946 -18
- package/dist/types/components/controller/action-stack/ActionStackController.d.ts +149 -0
- package/dist/types/components/controller/action-stack/ActionStackDragHandler.d.ts +111 -0
- package/dist/types/components/controller/action-stack/ActionStackManager.d.ts +118 -0
- package/dist/types/components/controller/action-stack/ActionStackState.d.ts +169 -0
- package/dist/types/components/controller/actions/ActionProjectionService.d.ts +73 -0
- package/dist/types/components/controller/actions/ChildActionMenuController.d.ts +83 -0
- package/dist/types/components/controller/actions/CoreEventMenuController.d.ts +90 -0
- package/dist/types/components/controller/actions/radialItemMenu.d.ts +117 -0
- package/dist/types/components/controller/children/ChildInteractionController.d.ts +38 -0
- package/dist/types/components/controller/children/ChildrenOrbitService.d.ts +14 -0
- package/dist/types/components/controller/force-field/EventFieldLifecycleController.d.ts +104 -0
- package/dist/types/components/controller/force-field/EventFieldRenderer.d.ts +86 -0
- package/dist/types/components/controller/force-field/ForceFieldComputationService.d.ts +50 -0
- package/dist/types/components/controller/force-field/ForceFieldDetailsPanel.d.ts +639 -0
- package/dist/types/components/controller/force-field/ForceFieldLifecycleController.d.ts +53 -0
- package/dist/types/components/controller/force-field/ForceFieldRenderer.d.ts +67 -0
- package/dist/types/components/controller/force-field/types.d.ts +42 -0
- package/dist/types/components/controller/labels/ChildScoresDeltaRenderer.d.ts +33 -0
- package/dist/types/components/controller/labels/ContextLabelsRenderer.d.ts +155 -0
- package/dist/types/components/controller/labels/WeightPreviewRingRenderer.d.ts +61 -0
- package/dist/types/components/controller/odd/ChildrenOrbitManager.d.ts +25 -0
- package/dist/types/components/controller/odd/OddViewManager.d.ts +44 -0
- package/dist/types/components/controller/search/SearchPanelSynchronizer.d.ts +125 -0
- package/dist/types/components/controller/settings/ControllerSettingsApplier.d.ts +50 -0
- package/dist/types/components/controller/state/BlockingAnimationTracker.d.ts +17 -0
- package/dist/types/components/controller/state/YinYangControllerState.d.ts +176 -0
- package/dist/types/components/controller/utils/actionStackMath.d.ts +13 -0
- package/dist/types/components/controller/utils/actionStackReorder.d.ts +7 -0
- package/dist/types/components/controller/utils/childrenOrbit.d.ts +18 -0
- package/dist/types/components/controller/utils/cuttingLabels.d.ts +9 -0
- package/dist/types/components/controller/utils/eventFieldStyle.d.ts +13 -0
- package/dist/types/components/controller/utils/eventFieldTargets.d.ts +47 -0
- package/dist/types/components/controller/utils/forceFieldMetadata.d.ts +4 -0
- package/dist/types/components/controller/utils/forceFieldPresentation.d.ts +9 -0
- package/dist/types/components/controller/utils/forceFieldStyle.d.ts +10 -0
- package/dist/types/components/controller/utils/labelGeometry.d.ts +5 -0
- package/dist/types/components/controller/utils/oddCutting.d.ts +2 -0
- package/dist/types/components/controller/utils/svgCoordinates.d.ts +9 -0
- package/dist/types/components/controller/utils/svgTransform.d.ts +5 -0
- package/dist/types/components/controller/utils/textLayout.d.ts +2 -0
- package/dist/types/components/controls/VizControlsPanel.d.ts +14 -0
- package/dist/types/components/factory/YinYangAppFactory.d.ts +4 -6
- package/dist/types/components/model/YinYangModel.d.ts +4 -30
- package/dist/types/components/panel/DiagramPanelBridge.d.ts +34 -0
- package/dist/types/components/panel/PanelManager.d.ts +150 -0
- package/dist/types/components/search/GlobalSearchController.d.ts +396 -0
- package/dist/types/components/stack-nav/StackNavOverlay.d.ts +82 -0
- package/dist/types/components/view/BorderDrawer.d.ts +203 -13
- package/dist/types/components/view/SpikeDrawer.d.ts +37 -31
- package/dist/types/components/view/ViewInitializer.d.ts +438 -2
- package/dist/types/components/view/YinYangDrawer.d.ts +414 -11
- package/dist/types/config/animationConfig.d.ts +37 -0
- package/dist/types/config/deltaColors.d.ts +64 -0
- package/dist/types/config/labelStyleConfig.d.ts +50 -0
- package/dist/types/data/OddCategoryColors.d.ts +12 -2
- package/dist/types/data/adverse-action-planner.d.ts +51 -0
- package/dist/types/data/adverse-action-planner.test.d.ts +1 -0
- package/dist/types/data/amplifier-engine.d.ts +107 -0
- package/dist/types/data/amplifier-engine.test.d.ts +1 -0
- package/dist/types/data/combo-engine.d.ts +94 -0
- package/dist/types/data/combo-engine.test.d.ts +1 -0
- package/dist/types/data/odd_generic_descriptions.d.ts +4 -0
- package/dist/types/data/odd_labels.d.ts +5 -0
- package/dist/types/data/yasuni_actions.d.ts +47 -0
- package/dist/types/data/yasuni_adverse_actions.d.ts +2 -0
- package/dist/types/data/yasuni_adverse_key_events.d.ts +2 -0
- package/dist/types/data/yasuni_cause.d.ts +33 -0
- package/dist/types/data/yasuni_graph.d.ts +22 -0
- package/dist/types/data/yasuni_key_events.d.ts +61 -0
- package/dist/types/data/yasuni_propagation_layers.d.ts +3 -0
- package/dist/types/interfaces/IActions.d.ts +1 -0
- package/dist/types/interfaces/ICauseGraph.d.ts +9 -0
- package/dist/types/interfaces/ICauseModel.d.ts +33 -0
- package/dist/types/interfaces/IGraphicsStrategy.d.ts +9 -5
- package/dist/types/interfaces/IPropagationLayers.d.ts +27 -0
- package/dist/types/interfaces/IViewData.d.ts +12 -0
- package/dist/types/interfaces/IYinYangAppFactory.d.ts +3 -3
- package/dist/types/interfaces/IYinYangController.d.ts +301 -6
- package/dist/types/interfaces/IYinYangGeometry.d.ts +43 -0
- package/dist/types/interfaces/IYinYangInternalModel.d.ts +34 -0
- package/dist/types/interfaces/IYinYangModel.d.ts +3 -11
- package/dist/types/main.d.ts +9 -0
- package/dist/types/utils/actionImages.d.ts +14 -0
- package/dist/types/utils/actionPropagation.d.ts +74 -0
- package/dist/types/utils/appMode.d.ts +5 -0
- package/dist/types/utils/causeGraph.d.ts +6 -0
- package/dist/types/utils/causeMetrics.d.ts +26 -0
- package/dist/types/utils/chainCardHeight.d.ts +27 -0
- package/dist/types/utils/d3/D3Element.d.ts +2 -2
- package/dist/types/utils/d3/D3GraphicsStrategy.d.ts +21 -4
- package/dist/types/utils/deltaChips.d.ts +15 -0
- package/dist/types/utils/deltaLabels.d.ts +54 -0
- package/dist/types/utils/facetteImages.d.ts +1 -0
- package/dist/types/utils/geometryUtils.d.ts +0 -1
- package/dist/types/utils/hierBadge.d.ts +44 -0
- package/dist/types/utils/idleSphereImage.d.ts +8 -0
- package/dist/types/utils/keyEventImages.d.ts +41 -0
- package/dist/types/utils/oddLegend.d.ts +30 -0
- package/dist/types/utils/positionalEfficiency.d.ts +16 -0
- package/dist/types/utils/yinYangWatermark.d.ts +29 -0
- package/package.json +27 -12
- package/dist/index.html +0 -1
- package/dist/types/data/coupe_rase_Orangs-outans/data_Kalimantan.d.ts +0 -3
- package/dist/types/data/coupe_rase_Orangs-outans/data_PT_Mayawana_Persada.d.ts +0 -3
- package/dist/types/data/data_institu_bancaire.d.ts +0 -3
- package/dist/types/interfaces/IOddItem.d.ts +0 -6
- 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,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,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 @@
|
|
|
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):
|
|
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
|
-
|
|
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):
|
|
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 {
|
|
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:
|
|
12
|
-
createModel(dataSubset:
|
|
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;
|