@micheeeeel/yinyangapp 3.0.0 → 3.1.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 (110) hide show
  1. package/dist/bundle.css +1 -0
  2. package/dist/bundle.js +1 -2
  3. package/dist/types/adapters/yasuniCauseAdapter.d.ts +3 -0
  4. package/dist/types/adapters/yinYangAdapter.d.ts +7 -0
  5. package/dist/types/animations/AnimationsMngr.d.ts +69 -15
  6. package/dist/types/animations/FrameScheduler.d.ts +99 -0
  7. package/dist/types/animations/rotationMotion.d.ts +43 -0
  8. package/dist/types/api.d.ts +17 -2
  9. package/dist/types/benchmark/runner.d.ts +20 -0
  10. package/dist/types/benchmark/scenarios.d.ts +55 -6
  11. package/dist/types/components/controller/YinYangController.d.ts +104 -14
  12. package/dist/types/components/controller/action-stack/ActionStackController.d.ts +16 -1
  13. package/dist/types/components/controller/action-stack/ActionStackDragHandler.d.ts +4 -0
  14. package/dist/types/components/controller/action-stack/ActionStackManager.d.ts +13 -2
  15. package/dist/types/components/controller/action-stack/ActionStackState.d.ts +8 -5
  16. package/dist/types/components/controller/action-stack/StackFocusController.d.ts +8 -7
  17. package/dist/types/components/controller/action-stack/stackChromePalette.d.ts +20 -0
  18. package/dist/types/components/controller/actions/ActionProjectionService.d.ts +16 -1
  19. package/dist/types/components/controller/actions/ChildActionMenuController.d.ts +74 -32
  20. package/dist/types/components/controller/actions/KeyEventController.d.ts +78 -70
  21. package/dist/types/components/controller/actions/{CoreEventMenuController.d.ts → KeyEventMenuController.d.ts} +28 -33
  22. package/dist/types/components/controller/actions/radialItemMenu.d.ts +43 -5
  23. package/dist/types/components/controller/children/ChildInteractionController.d.ts +4 -0
  24. package/dist/types/components/controller/children/ChildrenBuilder.d.ts +3 -1
  25. package/dist/types/components/controller/children/ComponentSwitchCoordinator.d.ts +3 -1
  26. package/dist/types/components/controller/children/IdleFacettesController.d.ts +151 -0
  27. package/dist/types/components/controller/children/idleTabLayout.d.ts +95 -0
  28. package/dist/types/components/controller/children/idleTabMorph.d.ts +45 -0
  29. package/dist/types/components/controller/force-field/EventFieldLifecycleController.d.ts +14 -0
  30. package/dist/types/components/controller/force-field/EventFieldRenderer.d.ts +3 -3
  31. package/dist/types/components/controller/force-field/ForceFieldCanvasPainter.d.ts +99 -0
  32. package/dist/types/components/controller/force-field/ForceFieldComputationService.d.ts +9 -0
  33. package/dist/types/components/controller/force-field/ForceFieldDetailsPanel.d.ts +28 -57
  34. package/dist/types/components/controller/force-field/ForceFieldDetailsPresenter.d.ts +4 -1
  35. package/dist/types/components/controller/force-field/ForceFieldLifecycleController.d.ts +16 -1
  36. package/dist/types/components/controller/force-field/ForceFieldRenderer.d.ts +10 -18
  37. package/dist/types/components/controller/force-field/IncomingForceFieldService.d.ts +2 -2
  38. package/dist/types/components/controller/force-field/PropagationAnimator.d.ts +2 -0
  39. package/dist/types/components/controller/force-field/keyEventPresentation.d.ts +47 -0
  40. package/dist/types/components/controller/force-field/propagation-viz/PropagationCometPlayer.d.ts +4 -0
  41. package/dist/types/components/controller/force-field/propagation-viz/propagationVizLists.d.ts +4 -2
  42. package/dist/types/components/controller/force-field/propagation-viz/propagationVizModel.d.ts +1 -0
  43. package/dist/types/components/controller/force-field/shieldViewModel.d.ts +6 -2
  44. package/dist/types/components/controller/force-field/types.d.ts +2 -1
  45. package/dist/types/components/controller/labels/ChildScoresDeltaRenderer.d.ts +7 -0
  46. package/dist/types/components/controller/labels/ComponentTitlePresenter.d.ts +13 -0
  47. package/dist/types/components/controller/labels/ContextLabelsRenderer.d.ts +16 -0
  48. package/dist/types/components/controller/labels/WeightPreviewRingRenderer.d.ts +6 -0
  49. package/dist/types/components/controller/odd/ChildrenOrbitManager.d.ts +76 -25
  50. package/dist/types/components/controller/odd/OddHighlightEffects.d.ts +2 -0
  51. package/dist/types/components/controller/odd/OddViewManager.d.ts +7 -3
  52. package/dist/types/components/controller/odd/childHighlightStyles.d.ts +45 -3
  53. package/dist/types/components/controller/search/SearchPanelSynchronizer.d.ts +8 -5
  54. package/dist/types/components/controller/settings/ControllerSettingsApplier.d.ts +4 -4
  55. package/dist/types/components/controller/state/ControllerSession.d.ts +3 -3
  56. package/dist/types/components/controller/state/ControllerUiCallbacks.d.ts +10 -0
  57. package/dist/types/components/controller/state/YinYangControllerState.d.ts +20 -9
  58. package/dist/types/components/controller/types.d.ts +9 -2
  59. package/dist/types/components/controller/utils/actionCatalog.d.ts +1 -1
  60. package/dist/types/components/controller/utils/eventFieldTargets.d.ts +19 -13
  61. package/dist/types/components/controller/utils/keyEventPropagationContext.d.ts +4 -0
  62. package/dist/types/components/controller/utils/keyEventTargetBreakdowns.d.ts +4 -0
  63. package/dist/types/components/controller/utils/svgTransform.d.ts +16 -0
  64. package/dist/types/components/controls/VizControlsPanel.d.ts +3 -1
  65. package/dist/types/components/panel/PanelManager.d.ts +92 -22
  66. package/dist/types/components/search/GlobalSearchController.d.ts +13 -6
  67. package/dist/types/components/view/BorderDrawer.d.ts +40 -14
  68. package/dist/types/components/view/IdleTabGridDrawer.d.ts +15 -0
  69. package/dist/types/components/view/SpikeDrawer.d.ts +18 -0
  70. package/dist/types/components/view/ViewInitializer.d.ts +53 -13
  71. package/dist/types/components/view/YinYangDrawer.d.ts +139 -40
  72. package/dist/types/components/view/borderColorCycle.d.ts +76 -0
  73. package/dist/types/components/workspace/facetWeightRuleSetting.d.ts +10 -0
  74. package/dist/types/components/workspace/workspaceTemplate.d.ts +1 -1
  75. package/dist/types/config/animationConfig.d.ts +10 -1
  76. package/dist/types/data/adverse-action-planner.d.ts +3 -3
  77. package/dist/types/data/amplifier-engine.d.ts +6 -6
  78. package/dist/types/data/key-event-effects.d.ts +30 -0
  79. package/dist/types/data/key-event-eligibility.d.ts +24 -0
  80. package/dist/types/data/key-event-propagation.d.ts +13 -0
  81. package/dist/types/data/key-event-types.d.ts +48 -0
  82. package/dist/types/data/key-event-validation.d.ts +11 -0
  83. package/dist/types/data/stability-shield.d.ts +14 -0
  84. package/dist/types/data/yasuni_adverse_key_events.d.ts +1 -1
  85. package/dist/types/data/yasuni_cause.d.ts +7 -0
  86. package/dist/types/data/yasuni_key_events.d.ts +4 -60
  87. package/dist/types/interfaces/ICauseModel.d.ts +12 -1
  88. package/dist/types/interfaces/IGraphicsStrategy.d.ts +9 -2
  89. package/dist/types/interfaces/IPropagationGraph.d.ts +14 -0
  90. package/dist/types/interfaces/IViewData.d.ts +10 -0
  91. package/dist/types/interfaces/IYinYangController.d.ts +25 -7
  92. package/dist/types/interfaces/IYinYangInternalModel.d.ts +5 -0
  93. package/dist/types/main.d.ts +0 -1
  94. package/dist/types/utils/actionIconFit.d.ts +23 -0
  95. package/dist/types/utils/actionPropagation.d.ts +6 -4
  96. package/dist/types/utils/causeMetrics.d.ts +50 -0
  97. package/dist/types/utils/chainCardHeight.d.ts +87 -4
  98. package/dist/types/utils/collapseAnimation.d.ts +39 -0
  99. package/dist/types/utils/d3/D3GraphicsStrategy.d.ts +28 -5
  100. package/dist/types/utils/deltaChips.d.ts +0 -4
  101. package/dist/types/utils/exportControls.d.ts +8 -0
  102. package/dist/types/utils/facetWeightLabel.d.ts +13 -0
  103. package/dist/types/utils/facetteImages.d.ts +6 -0
  104. package/dist/types/utils/glowHalo.d.ts +74 -0
  105. package/dist/types/utils/hierBadge.d.ts +1 -1
  106. package/dist/types/utils/keyEventImages.d.ts +1 -1
  107. package/dist/types/utils/menuIconSize.d.ts +17 -0
  108. package/dist/types/utils/spreadAngles.d.ts +8 -0
  109. package/package.json +4 -1
  110. package/dist/bundle.js.LICENSE.txt +0 -1
@@ -1,8 +1,7 @@
1
1
  import { IYinYangView } from "../../../interfaces/IYinYangView";
2
2
  import { YinYangInternalModel } from "../../../interfaces/IYinYangInternalModel";
3
3
  import { type KeyEventDefinition } from "../../../data/yasuni_key_events";
4
- import { ChildrenOrbitEntry } from "../utils/childrenOrbit";
5
- import { CoreEventMenuController } from "./CoreEventMenuController";
4
+ import { KeyEventMenuController } from "./KeyEventMenuController";
6
5
  import { ActionStackController } from "../action-stack/ActionStackController";
7
6
  import { ForceFieldDetailsPanel } from "../force-field/ForceFieldDetailsPanel";
8
7
  import { EventFieldRenderer } from "../force-field/EventFieldRenderer";
@@ -15,10 +14,8 @@ import { ActionStackManager } from "../action-stack/ActionStackManager";
15
14
  export type KeyEventControllerDeps = {
16
15
  actionStackController: ActionStackController;
17
16
  actionStackManager: ActionStackManager;
18
- animateChildrenHide: () => void;
19
- buildChildrenOrbitData: () => ChildrenOrbitEntry[];
20
17
  closeChildActionMenu: () => void;
21
- coreEventMenuController: CoreEventMenuController;
18
+ keyEventMenuController: KeyEventMenuController;
22
19
  eventFieldLifecycleController: EventFieldLifecycleController;
23
20
  eventFieldRenderer: EventFieldRenderer;
24
21
  forceFieldDetailsPanel: ForceFieldDetailsPanel;
@@ -27,52 +24,93 @@ export type KeyEventControllerDeps = {
27
24
  y: number;
28
25
  } | null;
29
26
  getCurrentComponentOrUndefined: () => YinYangInternalModel["components"][number] | undefined;
27
+ /** Satellite-facette d'une facette en sous-état Idle « facettes » : centre
28
+ * rendu et rayon, ou null s'il n'est pas (encore) affiché. */
29
+ getFacetteSatelliteAnchor: (componentId: string) => {
30
+ center: {
31
+ x: number;
32
+ y: number;
33
+ };
34
+ radius: number;
35
+ } | null;
36
+ /** Vrai quand le sous-état Idle « facettes » est affiché. */
37
+ isIdleFacettesActive: () => boolean;
38
+ /** Amène le diagramme en Idle « facettes » (referme la Facette ouverte,
39
+ * bascule le sous-état) ; résolu une fois les satellites-facettes sortis. */
40
+ showIdleFacettes: () => Promise<void>;
30
41
  navigateToPrereqAction: (actionId: string) => void;
31
- prepareForComponentSwitch: (targetComponentId: string) => void;
32
42
  session: ControllerSession;
33
43
  state: YinYangControllerState;
34
44
  titlePresenter: ComponentTitlePresenter;
35
45
  ui: ControllerUiCallbacks;
36
46
  view: IYinYangView;
37
47
  };
38
- /** Événements Clés : menu radial du cœur, aperçu de carte, champ
39
- * d'événement et ajout à la pile. */
48
+ /** Événements Clés : menu radial des satellites-facettes, aperçu de carte,
49
+ * champ d'événement et ajout à la pile. */
40
50
  export declare class KeyEventController {
41
51
  private deps;
52
+ /** Aperçu effacé par le dernier clic sur un satellite-facette, avec
53
+ * l'instant de l'effacement — voir restorePreviewClearedByDoubleClick. */
54
+ private previewClearedBySwitch;
42
55
  constructor(deps: KeyEventControllerDeps);
56
+ /** Facette dont les bulles d'Événements Clés sont déployées, ou null. */
57
+ getKeyEventMenuFacetteId(): string | null;
58
+ private notifyKeyEventMenuState;
59
+ /**
60
+ * Clic sur un satellite-facette (Idle « facettes ») : déploie ses bulles
61
+ * d'Événements Clés, ou les replie si elles l'étaient déjà — même règle
62
+ * que le clic sur un satellite de cutting pour ses boutons d'action. Un
63
+ * seul menu à la fois : ouvrir celui d'une facette replie celui d'une
64
+ * autre.
65
+ */
66
+ toggleKeyEventMenu(componentId: string): void;
43
67
  /**
44
- * Appelé par YinYangDrawer quand le petit cercle "œil" du lobe dominant
45
- * (yin ou yang, selon Composante.orientation) est cliqué — jamais l'autre
46
- * lobe, jamais un satellite (garde déjà appliquée côté YinYangDrawer, même
47
- * principe que onDiagramOddArcClicked pour les arcs ODD). Ouvre/ferme le
48
- * menu radial des Événements Clés de la facette active.
68
+ * Double-clic sur un satellite-facette (entrée dans sa Facette) : son
69
+ * premier clic a déjà basculé (ou replié) les bulles, effaçant au passage
70
+ * l'aperçu en cours — celui-là même dont le souffle doit se poursuivre
71
+ * dans la Facette. On le rétablit s'il vient d'être effacé.
49
72
  */
50
- onCoreEventNucleusClicked(): void;
51
- notifyKeyEventMenuState(open: boolean): void;
52
- private toggleCoreEventMenu;
73
+ restorePreviewClearedByDoubleClick(): void;
74
+ /** Replie les bulles du satellite-facette ouvert — et l'aperçu qu'elles
75
+ * portaient. No-op si aucun menu n'est déployé. */
76
+ closeKeyEventMenu(): void;
77
+ /** Les satellites-facettes sont sortis : un Événement Clé encore en aperçu
78
+ * (revenu d'une Facette) retrouve ses bulles sur le satellite-facette
79
+ * d'origine, sa bulle allumée, et son souffle en part. */
80
+ onIdleFacettesShown(): void;
81
+ /** Les satellites-facettes rentrent (bascule vers les arcs ou ouverture
82
+ * d'une Facette) : leurs bulles rentrent avec eux. L'aperçu, lui, reste
83
+ * en place jusqu'au choix d'une autre action ou d'un autre événement —
84
+ * invisible en Idle « arcs », il retrouve son souffle dans une Facette
85
+ * concernée ou au retour des satellites-facettes. */
86
+ onIdleFacettesHidden(): void;
53
87
  /**
54
88
  * Fermeture du Champ d'événement : l'Événement Clé en aperçu et les bulles
55
- * du menu cœur — chemin unique partagé par la fermeture de facette
89
+ * du satellite-facette — chemin unique partagé par la fermeture de facette
56
90
  * (closeCurrentComposante) et par l'exclusivité action/événement
57
91
  * (openActionMenuFromChild). No-op si rien n'est ouvert.
58
92
  *
59
93
  * hide() d'abord pour la rétraction immédiate du souffle (le geste
60
94
  * d'ouverture joué à l'envers — cf. prepareForComponentSwitch),
61
- * updateCoreEventMenu() ensuite pour replier les bulles et laisser
95
+ * updateKeyEventMenu() ensuite pour replier les bulles et laisser
62
96
  * refreshTargets constater qu'il n'y a plus rien à dessiner. La carte du
63
97
  * panneau RECHERCHE part avec : elle décrit l'Événement Clé qu'on vient de
64
98
  * retirer du diagramme, et rien ne garantit qu'un autre bloc prenne sa
65
99
  * place (ouvrir un satellite n'affiche qu'un descriptif, pas un bloc).
66
100
  */
67
101
  closeKeyEventField(): void;
68
- updateCoreEventMenu(): void;
102
+ updateKeyEventMenu(): void;
69
103
  /**
70
104
  * Événements Clés qui pilotent le Champ d'événement en ce moment — source
71
105
  * unique de vérité pour EventFieldLifecycleController (cibles) comme pour
72
106
  * getEventFieldSource (point d'émission).
73
107
  *
108
+ * Rien en Idle « arcs ». En Idle « facettes », le souffle relie le
109
+ * satellite-facette d'origine aux AUTRES satellites-facettes atteints ; en
110
+ * Facette, il part du cœur vers les satellites de cutting.
111
+ *
74
112
  * Deux régimes, mêmes règles de priorité que le champ de force d'action :
75
- * un APERÇU (clic sur une bulle du menu cœur ou sur l'entrée de l'arbre
113
+ * un APERÇU (clic sur une bulle d'un satellite-facette ou sur l'entrée de l'arbre
76
114
  * RECHERCHE) prend toujours la main — c'est le geste que l'utilisateur
77
115
  * vient de faire, quel que soit l'onglet ; sinon, en mode STACK, ce sont
78
116
  * les Événements Clés COCHÉS de la pile qui décident, exactement comme les
@@ -87,25 +125,10 @@ export declare class KeyEventController {
87
125
  * l'arc de sa facette d'origine).
88
126
  */
89
127
  getEventFieldKeyEvents(): KeyEventDefinition[];
90
- /**
91
- * Point d'émission du Champ d'événement : le CŒUR du yin/yang, c'est-à-dire
92
- * le disque central du lobe correspondant à l'orientation de la facette
93
- * courante — le cœur noir du yang sur une facette Yang, le cœur blanc du
94
- * yin sur une facette Yin. Ce n'est PAS le centre géométrique du symbole :
95
- * les deux lobes ont des rayons qui varient avec le score, donc le cœur se
96
- * déplace le long de l'axe vertical au fil de la partie, d'où la
97
- * relecture de la géométrie à chaque frame. Injecté dans
98
- * EventFieldLifecycleController (getEventFieldSource), rappelé à chaque
99
- * frame de son animation.
100
- *
101
- * `geometry.yin/yang.centerY` est la position CANONIQUE (pré-rotation) :
102
- * pendant une rotation Yin/Yang (AnimationsMngr), le cœur visible se
103
- * déplace via un `transform` écrit à même `graphElementGroup` à chaque
104
- * frame, sans jamais toucher `geometry`. On lit donc la position réelle
105
- * via getLiveLobeCoreCenter plutôt que la géométrie statique, pour que les
106
- * anneaux du champ d'événement suivent le cœur qui tourne au lieu de
107
- * naître à une origine figée.
108
- */
128
+ /** Événements Clés cochés de la pile, dans l'ordre de la pile, réduits à
129
+ * ceux qui ont une bulle dans le mode courant. */
130
+ private getCheckedStackKeyEvents;
131
+ /** Origin satellite while visible; its facet arc carries the field after navigation. */
109
132
  getEventFieldSource(): {
110
133
  center: {
111
134
  x: number;
@@ -113,18 +136,6 @@ export declare class KeyEventController {
113
136
  } | null;
114
137
  radius: number;
115
138
  };
116
- /**
117
- * Résout un point porté par `lobeGroup` (coordonnées locales, ici le
118
- * centre canonique du cœur) dans le repère de globalGroup — celui où
119
- * EventFieldRenderer dessine (voir EventFieldLifecycleController,
120
- * getGlobalGroupNode). Passe par les CTM SVG plutôt que de reparser
121
- * l'attribut `transform` (comme getChildRenderedCenter le fait pour une
122
- * simple translation) : le transform posé sur graphElementGroup pendant
123
- * une rotation combine rotate ET translate, et cette composition suit
124
- * fidèlement AnimationsMngr sans dépendre de sa formule exacte — un
125
- * changement futur de celle-ci n'a pas besoin d'être répercuté ici.
126
- */
127
- private getLiveLobeCoreCenter;
128
139
  /**
129
140
  * Rejoue l'aperçu d'un Événement Clé depuis une navigation Recherche
130
141
  * (historique précédent/suivant) — pendant minimal de searchNavigateToAction,
@@ -139,41 +150,35 @@ export declare class KeyEventController {
139
150
  *
140
151
  * Volontairement plus étroit que previewKeyEvent : ni carte redessinée, ni
141
152
  * notification de navigation (donc pas d'entrée d'historique en double) —
142
- * le panneau montre déjà cet événement, c'est le diagramme qui le rattrape.
143
- * On garde en revanche l'exclusivité action/événement : les deux champs ne
144
- * cohabitent jamais.
145
- *
146
- * Si la facette courante n'est plus celle de l'événement (l'utilisateur a
147
- * navigué ailleurs pendant le mode STACK), on revient d'abord sur sa facette
148
- * d'origine — mêmes gestes que searchSetKeyEventMenuOpen : l'aperçu survit
149
- * au switch (prepareForComponentSwitch le garde vivant, destination =
150
- * origine) et le menu cœur se redéploie à l'arrivée avec sa bulle active.
153
+ * le panneau montre déjà cet événement, c'est le diagramme qui le rattrape :
154
+ * bascule en Idle « facettes » (une Facette ouverte se referme), bulles du
155
+ * satellite-facette d'origine déployées, celle de l'événement allumée.
151
156
  */
152
157
  restoreKeyEventDiagramState(keyEventId: string): void;
153
158
  /**
154
159
  * Dépli/repli du groupe "Événements Clés" depuis la hiérarchie RECHERCHE —
155
- * pendant exact du clic sur le cœur du yin/yang (onCoreEventNucleusClicked),
156
- * pour que l'arbre et le diagramme montrent le même menu déployé : ouvrir le
157
- * groupe déploie les bulles de la facette, le refermer les rétracte (même
158
- * règle que le dépli d'un Satellite, qui déploie ses boutons d'Action).
160
+ * pendant exact du clic sur un satellite-facette, pour que l'arbre et le
161
+ * diagramme montrent le même menu déployé : ouvrir le groupe bascule en
162
+ * Idle « facettes » (une Facette ouverte se referme) et déploie les bulles
163
+ * de ce satellite-facette, le refermer les rétracte.
159
164
  *
160
165
  * Le repli passe par closeKeyEventField plutôt que par le toggle : il doit
161
166
  * aussi emporter l'Événement Clé en aperçu (et sa carte), sinon une bulle
162
167
  * validée resterait allumée sous un groupe replié.
163
168
  */
164
169
  searchSetKeyEventMenuOpen(componentIndex: number, open: boolean): void;
165
- /** Ouverture idempotente du menu cœur — no-op s'il est déjà déployé (le
166
- * toggle le refermerait). */
167
- openCoreEventMenu(): void;
170
+ /** Ouverture idempotente des bulles d'un satellite-facette — no-op si
171
+ * elles sont déjà déployées (le toggle les refermerait). */
172
+ openKeyEventMenu(componentId: string): void;
168
173
  /** Seul point de mutation de activeKeyEventId — resynchronise la ligne
169
174
  * Événement Clé du titre (voir getCurrentSatelliteTitle) à chaque
170
175
  * changement, exactement comme setActiveChildKey le fait pour le
171
176
  * satellite. */
172
177
  setActiveKeyEventId(keyEventId: string | null): void;
173
178
  /**
174
- * Clic sur une bulle du menu cœur. En STACK : clic sur le libellé de son
175
- * item de pile — celui en focus s'il s'agit de cet événement, sinon le
176
- * plus récent ; rien s'il n'est pas dans la pile. Ailleurs : aperçu.
179
+ * Clic sur une bulle d'un satellite-facette. En STACK : clic sur le libellé de son
180
+ * item coché de pile — celui en focus s'il s'agit de cet événement, sinon le
181
+ * plus récent ; rien s'il n'est pas coché dans la pile. Ailleurs : aperçu.
177
182
  */
178
183
  onKeyEventBubbleClick(keyEvent: KeyEventDefinition): void;
179
184
  /** Aperçu — 1er clic sur un Événement Clé : affiche sa carte descriptive
@@ -189,4 +194,7 @@ export declare class KeyEventController {
189
194
  x: number;
190
195
  y: number;
191
196
  }): void;
197
+ /** En Idle « tab » : sélectionne une facette pour le titre dynamique, sans
198
+ * ouvrir/fermer les bulles d'événements. Rafraîchit le titre. */
199
+ selectKeyEventFacetteForTab(componentId: string): void;
192
200
  }
@@ -1,41 +1,36 @@
1
1
  import { IYinYangView } from "../../../interfaces/IYinYangView";
2
2
  import { type KeyEventDefinition } from "../../../data/yasuni_key_events";
3
3
  import { type Point } from "./radialItemMenu";
4
- type CoreEventMenuContext = {
5
- /** null/false ferme le menu (même logique que activeActionMenuChildKey côté satellite). */
6
- isOpen: boolean;
7
- keyEventsForActiveFacette: KeyEventDefinition[];
4
+ type KeyEventMenuContext = {
5
+ /** Satellite-facette (Idle « facettes ») qui porte le menu, ou null pour
6
+ * le refermer : centre rendu et rayon du satellite. */
7
+ anchor: {
8
+ center: Point;
9
+ radius: number;
10
+ } | null;
11
+ /** Centre du cercle global : l'éventail s'ouvre vers l'extérieur, sur
12
+ * l'axe centre → satellite, comme les boutons d'action d'un satellite. */
13
+ parentCenter: Point;
14
+ keyEvents: KeyEventDefinition[];
8
15
  /** Id de l'événement actuellement en aperçu (carte affichée), ou null. */
9
16
  activeKeyEventId: string | null;
10
- /** Même valeur que le contrôle "Distance boutons" du groupe "Grappe Actions"
11
- * (state.menu.itemDistance) — pas de contrôle dédié : voir le calcul de
12
- * offsetDistance plus bas, qui la réutilise telle quelle. */
13
- childActionMenuItemDistance: number;
14
- /** Distance centre du cercle central → satellites de la facette active
15
- * (moyenne des rayons d'orbite réels, cf. buildChildrenOrbitData) — le
16
- * "connu" dont dérive offsetDistance plus bas. */
17
- childrenOrbitRadius: number;
18
- /** Taille des bulles — contrôle dédié "Taille boutons" du groupe
19
- * "Événements clés" (state.menu.coreEventMenuItemScale) : les Événements
20
- * Clés se dimensionnent indépendamment des boutons d'action des
21
- * satellites. */
22
- coreEventMenuItemScale: number;
23
- coreEventIconFontScale: number;
24
- /** Ajustement fin (px) de la distance des boutons, de part et d'autre de
25
- * la longueur auto-calculée — contrôle "Distance boutons" du groupe
26
- * "Événements clés", voir state.menu.coreEventMenuDistanceOffset. */
27
- coreEventMenuDistanceOffset: number;
17
+ /** Distance satellite → bulles : même base que les boutons d'action
18
+ * (smallCircleRadius × state.menu.itemDistance, voir
19
+ * ChildActionMenuController), ajustée par keyEventMenuDistanceOffset. */
20
+ offsetDistance: number;
21
+ /** Rayon des bulles — contrôle dédié "Taille boutons" du groupe
22
+ * "Événements clés" (state.menu.keyEventMenuItemScale). */
23
+ itemRadius: number;
24
+ keyEventIconFontScale: number;
28
25
  };
29
26
  /**
30
- * Menu radial des Événements Clés, déclenché par un clic sur le cercle
31
- * central (yin-yang) de la facette active — même langage visuel et même
32
- * sémantique de clic que ChildActionMenuController (bulles + icône,
33
- * chorégraphie D3 en éventail factorisée dans radialItemMenu.ts ; clic =
34
- * aperçu, glisser vers la pile = validation), mais ancré sur
35
- * le centre fixe de la facette plutôt que sur un satellite, et déployé à
36
- * angle égal sur 360° plutôt que sur un axe source.
27
+ * Menu radial des Événements Clés d'une facette, déployé autour de son
28
+ * satellite-facette (sous-état Idle « facettes ») — même langage visuel et
29
+ * même sémantique que ChildActionMenuController autour d'un satellite de
30
+ * cutting (bulles + icône, chorégraphie D3 en éventail factorisée dans
31
+ * radialItemMenu.ts ; clic = aperçu, glisser vers la pile = validation).
37
32
  */
38
- export declare class CoreEventMenuController {
33
+ export declare class KeyEventMenuController {
39
34
  private readonly view;
40
35
  /** Clic sur une bulle — aperçu, ou focus de son item de pile en STACK
41
36
  * (voir KeyEventController.onKeyEventBubbleClick). */
@@ -48,11 +43,11 @@ export declare class CoreEventMenuController {
48
43
  * SearchPanelSynchronizer.startActionDrag, entièrement générique).
49
44
  * Retourne une poignée d'annulation, conservée dans activeDragCancel. */
50
45
  private readonly startKeyEventDrag;
51
- private coreEventMenuGroup;
46
+ private keyEventMenuGroup;
52
47
  /** Groupe séparé pour les traits centre → bulle, abaissé au fond du
53
48
  * z-order (voir ensureLineLayer) pour qu'ils s'affichent derrière le
54
49
  * disque central et les satellites plutôt que par-dessus. */
55
- private coreEventLineLayer;
50
+ private keyEventLineLayer;
56
51
  /** Poignée d'annulation du glisser-déposer en cours (voir startKeyEventDrag),
57
52
  * ou null si aucun glisser n'est en cours — même rôle que
58
53
  * ChildActionMenuController.activeDragCancel. */
@@ -80,7 +75,7 @@ export declare class CoreEventMenuController {
80
75
  private _onHoverCb?;
81
76
  setOnHover(cb: (keyEventId: string | null) => void): void;
82
77
  clearImmediately(): void;
83
- update(context: CoreEventMenuContext): void;
78
+ update(context: KeyEventMenuContext): void;
84
79
  /** Restyle les seuls liens (impulsion allumée/éteinte) sans toucher à leur
85
80
  * géométrie : le survol ne doit rien réanimer. */
86
81
  private setHoveredKeyEvent;
@@ -20,6 +20,19 @@ export type RadialMenuItemPosition<T> = {
20
20
  * cercle central — pas d'axe source à respecter, maximise l'écart
21
21
  * angulaire entre bulles).
22
22
  */
23
+ /** Lueur d'une bulle : équivalent de `drop-shadow(0 0 ${blur}px ${color})`. */
24
+ export type RadialItemGlow = {
25
+ color: string;
26
+ blur: number;
27
+ } | null;
28
+ /**
29
+ * Habille le halo pré-rendu d'une bulle (cercle `${dataRole}-halo`, créé
30
+ * sous la plaque) : un disque à dégradé radial au lieu d'un drop-shadow sur
31
+ * la plaque. `null` l'éteint.
32
+ */
33
+ export declare function styleRadialItemHalo(group: d3.Selection<SVGGElement, unknown, null, undefined>, dataRole: string, radius: number, glow: RadialItemGlow): void;
34
+ /** Allume / éteint le halo de survol d'une bulle, sans perdre sa lueur propre. */
35
+ export declare function setRadialItemHaloHighlight(group: d3.Selection<SVGGElement, unknown, null, undefined>, dataRole: string, highlighted: boolean): void;
23
36
  export declare function computeFanPositions<T extends {
24
37
  id: string;
25
38
  }>(items: T[], opts: {
@@ -31,6 +44,14 @@ export declare function computeFanPositions<T extends {
31
44
  itemRadius: number;
32
45
  keyPrefix: string;
33
46
  }): RadialMenuItemPosition<T>[];
47
+ /**
48
+ * Recale des bulles DÉJÀ rendues sur de nouvelles positions (frame d'orbite) :
49
+ * ni data join, ni transition, ni listeners. Une bulle encore en ouverture
50
+ * n'est pas touchée directement — sa transition relit la cible mise à jour
51
+ * ici (liveItemTransformTween). Les bulles absentes de `positions` (en
52
+ * sortie) restent à leur chorégraphie.
53
+ */
54
+ export declare function followRadialItems<T>(groupNode: SVGGElement, dataRole: string, positions: RadialMenuItemPosition<T>[]): void;
34
55
  /**
35
56
  * Referme et retire toutes les bulles d'un menu radial (repli en
36
57
  * éventail), utilisé à la fois quand update() ne reçoit plus de
@@ -48,8 +69,10 @@ export declare function renderRadialItemsChoreography<T>(params: {
48
69
  groupNode: SVGGElement;
49
70
  dataRole: string;
50
71
  positions: RadialMenuItemPosition<T>[];
51
- exitAnimationCenter: Point;
52
- enterCenter: Point;
72
+ /** Un point unique, ou un point par bulle (bulles détachées : chacune naît
73
+ * de son propre satellite source et y retourne). */
74
+ exitAnimationCenter: Point | ((d: RadialMenuItemPosition<T>) => Point);
75
+ enterCenter: Point | ((d: RadialMenuItemPosition<T>) => Point);
53
76
  getIconUrl: (id: string) => string;
54
77
  /** Décor optionnel inséré entre la plaque (cercle) et le pictogramme, sur
55
78
  * la seule sélection enter() — c'est par là que le menu des Événements
@@ -86,7 +109,7 @@ export declare function styleRadialItemLinks<T extends {
86
109
  }>(groupNode: SVGGElement | null, dataRole: string, getStyle: (d: RadialMenuItemPosition<T>) => RadialItemLinkStyle): void;
87
110
  /**
88
111
  * Chorégraphie D3 des liens parent → item, rendus dans un groupe SÉPARÉ de
89
- * celui des bulles (voir CoreEventMenuController : ce groupe est glissé plus
112
+ * celui des bulles (voir KeyEventMenuController : ce groupe est glissé plus
90
113
  * tôt dans le z-order pour passer derrière les satellites et le disque
91
114
  * central, alors que les bulles restent devant dans leur propre groupe).
92
115
  * Anime directement x2/y2 des lignes : un lien entrant grandit depuis le bord
@@ -101,8 +124,23 @@ export declare function renderRadialItemLinks<T extends {
101
124
  groupNode: SVGGElement;
102
125
  dataRole: string;
103
126
  positions: RadialMenuItemPosition<T>[];
104
- center: Point;
127
+ /** Centre du parent — un seul, ou un par bulle (bulles détachées). */
128
+ center: Point | ((d: RadialMenuItemPosition<T>) => Point);
105
129
  /** Rayon du disque parent : le faisceau démarre à son bord. 0 = au centre. */
106
- startRadius?: number;
130
+ startRadius?: number | ((d: RadialMenuItemPosition<T>) => number);
107
131
  getStyle?: (d: RadialMenuItemPosition<T>) => RadialItemLinkStyle;
108
132
  }): void;
133
+ /**
134
+ * Pendant de followRadialItems pour les faisceaux : origine, extrémité et
135
+ * dégradé recalés sur les nouvelles positions, sans data join ni transition.
136
+ * Un faisceau encore en ouverture garde sa transition, qui relit la cible.
137
+ */
138
+ export declare function followRadialItemLinks<T extends {
139
+ id: string;
140
+ }>(params: {
141
+ groupNode: SVGGElement;
142
+ dataRole: string;
143
+ positions: RadialMenuItemPosition<T>[];
144
+ center: Point | ((d: RadialMenuItemPosition<T>) => Point);
145
+ startRadius?: number | ((d: RadialMenuItemPosition<T>) => number);
146
+ }): void;
@@ -32,6 +32,9 @@ export declare class ChildInteractionController {
32
32
  setChildrenHiddenState(childControllers: IYinYangController[], hidden: boolean): void;
33
33
  attachChildToggleHandler(childController: IYinYangController, childOddMap: Map<string, ChildOddMeta>): void;
34
34
  attachChildHoverHandler(childController: IYinYangController, childOddMap: Map<string, ChildOddMeta>): void;
35
+ private backgroundClickContainer;
36
+ /** Un seul écouteur par conteneur : le SVG racine survit aux recréations de
37
+ * satellites, et cette méthode est rappelée à chacune. */
35
38
  attachBackgroundClickHandler(): void;
36
39
  enterOddView(oddId: string): void;
37
40
  exitOddView(): void;
@@ -41,6 +44,7 @@ export declare class ChildInteractionController {
41
44
  private applyChildActiveStyle;
42
45
  /** Filtre courant d'un satellite : la mise en valeur d'un ODD prime sur le
43
46
  * style "actif", qui prime lui-même sur l'état neutre. */
47
+ private resolveGlowFor;
44
48
  private resolveFilterFor;
45
49
  private getChildOffset;
46
50
  }
@@ -29,6 +29,8 @@ export type ChildrenBuilderDeps = {
29
29
  getCurrentComponentOrUndefined: () => YinYangInternalModel["components"][number] | undefined;
30
30
  getKey: () => string;
31
31
  renderOppositeChildrenForceField: (orbitData?: ChildrenOrbitEntry[], angleOffset?: number) => void;
32
+ /** Exécute `run` sans rendu du champ de force (les appels sont ignorés). */
33
+ suppressForceFieldRender: (run: () => void) => void;
32
34
  getRotationState: () => {
33
35
  clockWise: boolean;
34
36
  durationMs: number;
@@ -66,7 +68,7 @@ export declare class ChildrenBuilder {
66
68
  /** Ratio de taille d'un satellite (rayon relatif à la baseline uniforme de
67
69
  * sa facette) à partir de son poids et du poids moyen de sa fratrie —
68
70
  * voir WEIGHT_SIZE_FLOOR_OFFSET pour le resserrement. */
69
- private static weightToSizeRatio;
71
+ static weightToSizeRatio(weight: number, averageWeight: number): number;
70
72
  /** Ratio of a component's heaviest satellite radius to its own uniform
71
73
  * baseline radius. Mirrors the per-cutting weight-based scaling applied
72
74
  * in createYinYangChildren(). */
@@ -32,10 +32,12 @@ export type ComponentSwitchCoordinatorDeps = {
32
32
  cuttingIndex: number;
33
33
  }>;
34
34
  clearActiveChild: () => void;
35
- clearChildren: () => void;
36
35
  createYinYangChildren: () => void;
37
36
  detailsPresenter: ForceFieldDetailsPresenter;
38
37
  disableOuterSpark: () => void;
38
+ /** Réaligne le sous-état Idle (arcs / facettes) : ce chemin quitte Idle
39
+ * sans passer par setChildrenEnabled(). */
40
+ syncIdleView: () => void;
39
41
  eventFieldLifecycleController: EventFieldLifecycleController;
40
42
  eventFieldRenderer: EventFieldRenderer;
41
43
  focusChildByOddCutting: (oddId: string, cuttingIndex: number, forceOpen?: boolean) => void;
@@ -0,0 +1,151 @@
1
+ import { IYinYangView } from "../../../interfaces/IYinYangView";
2
+ import { IYinYangController } from "../../../interfaces/IYinYangController";
3
+ import { IYinYangAppFactory } from "../../../interfaces/IYinYangAppFactory";
4
+ import { YinYangInternalModel } from "../../../interfaces/IYinYangInternalModel";
5
+ import { IdleView, YinYangControllerState } from "../state/YinYangControllerState";
6
+ /** Crochets de l'hôte autour du sous-état « tab » — voir
7
+ * `IYinYangController.setIdleTabHooks`. */
8
+ export type IdleTabHooks = {
9
+ /** Avant le calcul de la grille (l'hôte peut agrandir le conteneur du
10
+ * diagramme) ; la grille attend sa résolution. */
11
+ beforeEnter?: () => Promise<void> | void;
12
+ /** Une fois les satellites revenus à leur place radiale. */
13
+ afterLeave?: () => Promise<void> | void;
14
+ };
15
+ export type IdleFacettesControllerDeps = {
16
+ view: IYinYangView;
17
+ state: YinYangControllerState;
18
+ factory: IYinYangAppFactory;
19
+ getKey: () => string;
20
+ getInternalModel: () => YinYangInternalModel;
21
+ setChildrenHiddenState: (children: IYinYangController[], hidden: boolean) => void;
22
+ animateChildren: (children: IYinYangController[], show: boolean) => Promise<void>;
23
+ applyChildrenFitScale: () => void;
24
+ /** Double-clic sur un satellite-facette : ouvre cette Facette, comme son arc. */
25
+ openFacette: (componentIndex: number, componentId: string) => void;
26
+ /** Clic sur un satellite-facette : déploie/replie ses Événements Clés. */
27
+ onSatelliteClick: (componentId: string) => void;
28
+ /** En Idle « tab » : sélectionne la facette pour le titre (sans déployer les bulles). */
29
+ selectKeyEventFacetteForTab: (componentId: string) => void;
30
+ /** Double-clic, juste avant d'ouvrir la Facette : annule l'effet de bord
31
+ * du premier clic sur l'aperçu en cours. */
32
+ onSatelliteDoubleClick: () => void;
33
+ /** Satellites-facettes sortis (fin d'animation) : les bulles et le souffle
34
+ * peuvent s'y accrocher. */
35
+ onSatellitesShown: () => void;
36
+ /** Satellites-facettes rentrés : leurs bulles rentrent avec eux. */
37
+ onSatellitesHidden: () => void;
38
+ onIdleViewChange?: (view: IdleView) => void;
39
+ };
40
+ /**
41
+ * Sous-états Idle « facettes » et « tab » : les arcs de bordure rentrent
42
+ * sous l'illustration, et chaque facette en ressort sous la forme d'un
43
+ * satellite montrant son propre yin/yang, dimensionné selon son poids.
44
+ * - « facettes » : à l'angle du milieu de son arc ;
45
+ * - « tab » : dans une grille régulière (voir idleTabLayout), l'illustration
46
+ * réduite au centre, l'image de la facette en fond de sa case et les
47
+ * facettes d'une même notion parente regroupées (IdleTabGridDrawer).
48
+ *
49
+ * Les satellites sortent toujours à leur place radiale ; « tab » les y
50
+ * reprend pour les faire glisser jusqu'à leur case (idleTabMorph), et
51
+ * inversement — la grille n'est qu'une transformation posée sur eux.
52
+ *
53
+ * Les satellites-facettes vivent à part des satellites de cutting d'une
54
+ * Facette (childControllers) : ni champ de force, ni menu d'action, ni
55
+ * orbite ne les concernent. Les transitions sont sérialisées — chaque étape
56
+ * relit l'état voulu au moment de s'exécuter, de sorte que des bascules
57
+ * rapprochées convergent vers le dernier état demandé sans se chevaucher.
58
+ */
59
+ export declare class IdleFacettesController {
60
+ private deps;
61
+ private satellites;
62
+ private satelliteByComponentId;
63
+ /** Disposition des satellites-facettes actuellement sortis (null : aucun). */
64
+ private shownLayout;
65
+ /** Grille en place (sous-état « tab ») et échelle du motif à rétablir en
66
+ * revenant à la disposition radiale. */
67
+ private tab;
68
+ /** Groupe enveloppe de chaque satellite-facette (porte la grille). */
69
+ private wrappers;
70
+ /** Position et facteur d'échelle posés par la grille, par satellite. */
71
+ private tabPlacement;
72
+ private readonly tabGrid;
73
+ private tabHooks;
74
+ /** Vrai une fois les satellites-facettes arrivés à leur place (fin de
75
+ * l'animation de sortie) : les bulles n'ont de point d'ancrage qu'alors. */
76
+ private settled;
77
+ private queue;
78
+ private escapeListener;
79
+ constructor(deps: IdleFacettesControllerDeps);
80
+ setTabHooks(hooks: IdleTabHooks | null): void;
81
+ getView(): IdleView;
82
+ /** Vrai dès qu'un sous-état à satellites-facettes (« facettes » ou
83
+ * « tab ») est l'état visé en Idle (arcs repliés ou en train de l'être). */
84
+ isActive(): boolean;
85
+ setView(view: IdleView): Promise<void>;
86
+ /** Centre et rayon du satellite-facette d'une facette, une fois sorti. */
87
+ getSatelliteAnchor(componentId: string): {
88
+ center: {
89
+ x: number;
90
+ y: number;
91
+ };
92
+ radius: number;
93
+ } | null;
94
+ toggleView(): Promise<void>;
95
+ /** Aligne l'affichage sur l'état voulu (Idle + sous-état). À appeler à
96
+ * chaque entrée/sortie d'Idle. */
97
+ sync(): Promise<void>;
98
+ private isIdle;
99
+ private wantedLayout;
100
+ private applyDesiredState;
101
+ /** Arcs repliés sous l'illustration, puis satellites jaillissant du centre
102
+ * jusqu'à leur place radiale. */
103
+ private show;
104
+ /** Satellites rentrant au centre, puis arcs ressortant jusqu'au bord. */
105
+ private hide;
106
+ /** Les satellites glissent de leur place radiale à leur case ; dans le même
107
+ * mouvement, l'illustration rapetisse, l'anneau d'images s'efface (chaque
108
+ * case porte la sienne) et la grille apparaît. */
109
+ private morphToTab;
110
+ /** Mouvement inverse : chaque satellite regagne sa place radiale. */
111
+ private morphToRadial;
112
+ private morph;
113
+ private patternCenter;
114
+ /** Place radiale d'un satellite, dans le repère du motif. */
115
+ private radialPlace;
116
+ /** Satellites à leur place : les bulles peuvent s'y accrocher. */
117
+ private settle;
118
+ /** Satellites en mouvement : leurs bulles rentrent. */
119
+ private unsettle;
120
+ /** Mise en page de la grille, dans le repère du SVG : sur toute la place
121
+ * que le conteneur du diagramme offre autour de l'illustration (le SVG
122
+ * déborde visiblement), au moins sur le carré du SVG. */
123
+ private computeTabLayout;
124
+ /** Plus grand rectangle centré sur l'illustration qui tienne dans le
125
+ * conteneur du SVG, padding exclu, en unités du SVG (le conteneur peut
126
+ * être mis à l'échelle par l'hôte : on ramène ses dimensions à celles du
127
+ * SVG). */
128
+ private tabArea;
129
+ private fadeImageRing;
130
+ private computeSizeRatios;
131
+ private createSatellites;
132
+ /** Glisse un groupe enveloppe entre le satellite et le groupe des enfants
133
+ * du motif : il porte la transformation de la grille, sans interférer
134
+ * avec celles que d'autres posent sur le satellite lui-même. */
135
+ private wrap;
136
+ private attachClickHandler;
137
+ /** Double-clic. Le sous-état « facettes » reste mémorisé : refermer la
138
+ * Facette y ramène.
139
+ * On replie d'abord les satellites-facettes et on redéploie les arcs (la
140
+ * Facette met en valeur l'arc actif), puis on ouvre la Facette. */
141
+ private openFacette;
142
+ /** Détache les satellites-facettes courants (pour les faire rentrer puis
143
+ * les détruire) et prévient que leurs bulles doivent rentrer avec eux. */
144
+ private takeSatellites;
145
+ /** Fin de vie : satellites-facettes détruits sur place (sans animation de
146
+ * rentrée), grille retirée, écouteur Échap détaché. */
147
+ destroy(): void;
148
+ private destroySatellites;
149
+ private attachEscapeListener;
150
+ private detachEscapeListener;
151
+ }