@memberjunction/ng-whiteboard 0.0.1 → 5.41.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 (62) hide show
  1. package/README.md +302 -28
  2. package/dist/lib/whiteboard-agent-sees-popover.component.d.ts +31 -0
  3. package/dist/lib/whiteboard-agent-sees-popover.component.d.ts.map +1 -0
  4. package/dist/lib/whiteboard-agent-sees-popover.component.js +132 -0
  5. package/dist/lib/whiteboard-agent-sees-popover.component.js.map +1 -0
  6. package/dist/lib/whiteboard-board.component.d.ts +458 -0
  7. package/dist/lib/whiteboard-board.component.d.ts.map +1 -0
  8. package/dist/lib/whiteboard-board.component.js +2357 -0
  9. package/dist/lib/whiteboard-board.component.js.map +1 -0
  10. package/dist/lib/whiteboard-context-menu.d.ts +57 -0
  11. package/dist/lib/whiteboard-context-menu.d.ts.map +1 -0
  12. package/dist/lib/whiteboard-context-menu.js +69 -0
  13. package/dist/lib/whiteboard-context-menu.js.map +1 -0
  14. package/dist/lib/whiteboard-export.d.ts +94 -0
  15. package/dist/lib/whiteboard-export.d.ts.map +1 -0
  16. package/dist/lib/whiteboard-export.js +592 -0
  17. package/dist/lib/whiteboard-export.js.map +1 -0
  18. package/dist/lib/whiteboard-host.component.d.ts +174 -0
  19. package/dist/lib/whiteboard-host.component.d.ts.map +1 -0
  20. package/dist/lib/whiteboard-host.component.js +758 -0
  21. package/dist/lib/whiteboard-host.component.js.map +1 -0
  22. package/dist/lib/whiteboard-pages.component.d.ts +83 -0
  23. package/dist/lib/whiteboard-pages.component.d.ts.map +1 -0
  24. package/dist/lib/whiteboard-pages.component.js +211 -0
  25. package/dist/lib/whiteboard-pages.component.js.map +1 -0
  26. package/dist/lib/whiteboard-snapshot.component.d.ts +30 -0
  27. package/dist/lib/whiteboard-snapshot.component.d.ts.map +1 -0
  28. package/dist/lib/whiteboard-snapshot.component.js +91 -0
  29. package/dist/lib/whiteboard-snapshot.component.js.map +1 -0
  30. package/dist/lib/whiteboard-srcdoc.pipe.d.ts +60 -0
  31. package/dist/lib/whiteboard-srcdoc.pipe.d.ts.map +1 -0
  32. package/dist/lib/whiteboard-srcdoc.pipe.js +75 -0
  33. package/dist/lib/whiteboard-srcdoc.pipe.js.map +1 -0
  34. package/dist/lib/whiteboard-state.d.ts +1113 -0
  35. package/dist/lib/whiteboard-state.d.ts.map +1 -0
  36. package/dist/lib/whiteboard-state.js +1396 -0
  37. package/dist/lib/whiteboard-state.js.map +1 -0
  38. package/dist/lib/whiteboard-toolbar.component.d.ts +95 -0
  39. package/dist/lib/whiteboard-toolbar.component.d.ts.map +1 -0
  40. package/dist/lib/whiteboard-toolbar.component.js +344 -0
  41. package/dist/lib/whiteboard-toolbar.component.js.map +1 -0
  42. package/dist/lib/whiteboard-tools.d.ts +103 -0
  43. package/dist/lib/whiteboard-tools.d.ts.map +1 -0
  44. package/dist/lib/whiteboard-tools.js +748 -0
  45. package/dist/lib/whiteboard-tools.js.map +1 -0
  46. package/dist/lib/whiteboard-widget-bridge.d.ts +217 -0
  47. package/dist/lib/whiteboard-widget-bridge.d.ts.map +1 -0
  48. package/dist/lib/whiteboard-widget-bridge.js +254 -0
  49. package/dist/lib/whiteboard-widget-bridge.js.map +1 -0
  50. package/dist/lib/whiteboard-zoom.component.d.ts +55 -0
  51. package/dist/lib/whiteboard-zoom.component.d.ts.map +1 -0
  52. package/dist/lib/whiteboard-zoom.component.js +139 -0
  53. package/dist/lib/whiteboard-zoom.component.js.map +1 -0
  54. package/dist/lib/whiteboard.module.d.ts +29 -0
  55. package/dist/lib/whiteboard.module.d.ts.map +1 -0
  56. package/dist/lib/whiteboard.module.js +78 -0
  57. package/dist/lib/whiteboard.module.js.map +1 -0
  58. package/dist/public-api.d.ts +49 -0
  59. package/dist/public-api.d.ts.map +1 -0
  60. package/dist/public-api.js +59 -0
  61. package/dist/public-api.js.map +1 -0
  62. package/package.json +43 -6
@@ -0,0 +1,344 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { WHITEBOARD_FONT_SIZES } from './whiteboard-state';
4
+ import * as i0 from "@angular/core";
5
+ const _forTrack0 = ($index, $item) => $item.Tool;
6
+ const _forTrack1 = ($index, $item) => $item.Key;
7
+ const _forTrack2 = ($index, $item) => $item.Kind;
8
+ function RealtimeWhiteboardToolbarComponent_For_2_Conditional_4_For_2_Template(rf, ctx) { if (rf & 1) {
9
+ const _r5 = i0.ɵɵgetCurrentView();
10
+ i0.ɵɵdomElementStart(0, "span", 17);
11
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Conditional_4_For_2_Template_span_click_0_listener() { const color_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.PenColorChange.emit(color_r6)); });
12
+ i0.ɵɵdomElementEnd();
13
+ } if (rf & 2) {
14
+ const color_r6 = ctx.$implicit;
15
+ const ctx_r2 = i0.ɵɵnextContext(3);
16
+ i0.ɵɵstyleProp("background", color_r6);
17
+ i0.ɵɵclassProp("sel", ctx_r2.PenColor === color_r6);
18
+ } }
19
+ function RealtimeWhiteboardToolbarComponent_For_2_Conditional_4_For_5_Template(rf, ctx) { if (rf & 1) {
20
+ const _r7 = i0.ɵɵgetCurrentView();
21
+ i0.ɵɵdomElementStart(0, "span", 18);
22
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Conditional_4_For_5_Template_span_click_0_listener() { const width_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.PenWidthChange.emit(width_r8)); });
23
+ i0.ɵɵdomElementEnd();
24
+ } if (rf & 2) {
25
+ const width_r8 = ctx.$implicit;
26
+ const ɵ$index_19_r9 = ctx.$index;
27
+ const ctx_r2 = i0.ɵɵnextContext(3);
28
+ i0.ɵɵclassMap("w" + (ɵ$index_19_r9 + 1));
29
+ i0.ɵɵclassProp("sel", ctx_r2.PenWidth === width_r8);
30
+ } }
31
+ function RealtimeWhiteboardToolbarComponent_For_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
32
+ const _r4 = i0.ɵɵgetCurrentView();
33
+ i0.ɵɵdomElementStart(0, "span", 12);
34
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Conditional_4_Template_span_click_0_listener($event) { i0.ɵɵrestoreView(_r4); return i0.ɵɵresetView($event.stopPropagation()); });
35
+ i0.ɵɵrepeaterCreate(1, RealtimeWhiteboardToolbarComponent_For_2_Conditional_4_For_2_Template, 1, 4, "span", 13, i0.ɵɵrepeaterTrackByIdentity);
36
+ i0.ɵɵdomElementStart(3, "span", 14);
37
+ i0.ɵɵrepeaterCreate(4, RealtimeWhiteboardToolbarComponent_For_2_Conditional_4_For_5_Template, 1, 4, "span", 15, i0.ɵɵrepeaterTrackByIdentity);
38
+ i0.ɵɵdomElementEnd();
39
+ i0.ɵɵdomElementStart(6, "span", 16);
40
+ i0.ɵɵtext(7);
41
+ i0.ɵɵdomElementEnd()();
42
+ } if (rf & 2) {
43
+ const ctx_r2 = i0.ɵɵnextContext(2);
44
+ i0.ɵɵadvance();
45
+ i0.ɵɵrepeater(ctx_r2.PenColors);
46
+ i0.ɵɵadvance(3);
47
+ i0.ɵɵrepeater(ctx_r2.PenWidths);
48
+ i0.ɵɵadvance(3);
49
+ i0.ɵɵtextInterpolate1("violet = ", ctx_r2.AgentName, "'s");
50
+ } }
51
+ function RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
52
+ const _r11 = i0.ɵɵgetCurrentView();
53
+ i0.ɵɵdomElementStart(0, "span", 26);
54
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_For_2_Template_span_click_0_listener() { const size_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.PickTextSize(size_r12)); });
55
+ i0.ɵɵtext(1);
56
+ i0.ɵɵdomElementEnd();
57
+ } if (rf & 2) {
58
+ const size_r12 = ctx.$implicit;
59
+ const ctx_r2 = i0.ɵɵnextContext(3);
60
+ i0.ɵɵclassProp("sel", ctx_r2.TextSize === size_r12);
61
+ i0.ɵɵdomProperty("title", size_r12 + " px");
62
+ i0.ɵɵadvance();
63
+ i0.ɵɵtextInterpolate(size_r12);
64
+ } }
65
+ function RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_For_5_Template(rf, ctx) { if (rf & 1) {
66
+ const _r13 = i0.ɵɵgetCurrentView();
67
+ i0.ɵɵdomElementStart(0, "span", 27);
68
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_For_5_Template_span_click_0_listener() { const fam_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.PickTextFamily(fam_r14.Key)); });
69
+ i0.ɵɵtext(1, "Ag");
70
+ i0.ɵɵdomElementEnd();
71
+ } if (rf & 2) {
72
+ const fam_r14 = ctx.$implicit;
73
+ const ctx_r2 = i0.ɵɵnextContext(3);
74
+ i0.ɵɵstyleProp("font-family", fam_r14.Stack);
75
+ i0.ɵɵclassProp("sel", ctx_r2.TextFamily === fam_r14.Key);
76
+ i0.ɵɵdomProperty("title", fam_r14.Title);
77
+ } }
78
+ function RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_For_10_Template(rf, ctx) { if (rf & 1) {
79
+ const _r15 = i0.ɵɵgetCurrentView();
80
+ i0.ɵɵdomElementStart(0, "span", 17);
81
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_For_10_Template_span_click_0_listener() { const color_r16 = i0.ɵɵrestoreView(_r15).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.PickTextColor(color_r16)); });
82
+ i0.ɵɵdomElementEnd();
83
+ } if (rf & 2) {
84
+ const color_r16 = ctx.$implicit;
85
+ const ctx_r2 = i0.ɵɵnextContext(3);
86
+ i0.ɵɵstyleProp("background", color_r16);
87
+ i0.ɵɵclassProp("sel", ctx_r2.TextColor === color_r16);
88
+ } }
89
+ function RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
90
+ const _r10 = i0.ɵɵgetCurrentView();
91
+ i0.ɵɵdomElementStart(0, "span", 19);
92
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_Template_span_click_0_listener($event) { i0.ɵɵrestoreView(_r10); return i0.ɵɵresetView($event.stopPropagation()); });
93
+ i0.ɵɵrepeaterCreate(1, RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_For_2_Template, 2, 4, "span", 20, i0.ɵɵrepeaterTrackByIdentity);
94
+ i0.ɵɵdomElementStart(3, "span", 21);
95
+ i0.ɵɵrepeaterCreate(4, RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_For_5_Template, 2, 5, "span", 22, _forTrack1);
96
+ i0.ɵɵdomElementStart(6, "span", 23);
97
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_Template_span_click_6_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.ToggleTextBold()); });
98
+ i0.ɵɵdomElement(7, "i", 24);
99
+ i0.ɵɵdomElementEnd()();
100
+ i0.ɵɵdomElementStart(8, "span", 25);
101
+ i0.ɵɵrepeaterCreate(9, RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_For_10_Template, 1, 4, "span", 13, i0.ɵɵrepeaterTrackByIdentity);
102
+ i0.ɵɵdomElementEnd();
103
+ i0.ɵɵdomElementStart(11, "span", 16);
104
+ i0.ɵɵtext(12);
105
+ i0.ɵɵdomElementEnd()();
106
+ } if (rf & 2) {
107
+ const ctx_r2 = i0.ɵɵnextContext(2);
108
+ i0.ɵɵadvance();
109
+ i0.ɵɵrepeater(ctx_r2.TextSizes);
110
+ i0.ɵɵadvance(3);
111
+ i0.ɵɵrepeater(ctx_r2.TextFamilies);
112
+ i0.ɵɵadvance(2);
113
+ i0.ɵɵclassProp("sel", ctx_r2.TextBold);
114
+ i0.ɵɵadvance(3);
115
+ i0.ɵɵrepeater(ctx_r2.PenColors);
116
+ i0.ɵɵadvance(3);
117
+ i0.ɵɵtextInterpolate1("violet = ", ctx_r2.AgentName, "'s");
118
+ } }
119
+ function RealtimeWhiteboardToolbarComponent_For_2_Conditional_6_For_2_Template(rf, ctx) { if (rf & 1) {
120
+ const _r18 = i0.ɵɵgetCurrentView();
121
+ i0.ɵɵdomElementStart(0, "span", 30);
122
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Conditional_6_For_2_Template_span_click_0_listener() { const shape_r19 = i0.ɵɵrestoreView(_r18).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.ShapeKindChange.emit(shape_r19.Kind)); });
123
+ i0.ɵɵdomElement(1, "i");
124
+ i0.ɵɵdomElementEnd();
125
+ } if (rf & 2) {
126
+ const shape_r19 = ctx.$implicit;
127
+ const ctx_r2 = i0.ɵɵnextContext(3);
128
+ i0.ɵɵclassProp("sel", ctx_r2.ShapeKind === shape_r19.Kind);
129
+ i0.ɵɵdomProperty("title", shape_r19.Title);
130
+ i0.ɵɵadvance();
131
+ i0.ɵɵclassMap(shape_r19.Icon);
132
+ } }
133
+ function RealtimeWhiteboardToolbarComponent_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
134
+ const _r17 = i0.ɵɵgetCurrentView();
135
+ i0.ɵɵdomElementStart(0, "span", 28);
136
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Conditional_6_Template_span_click_0_listener($event) { i0.ɵɵrestoreView(_r17); return i0.ɵɵresetView($event.stopPropagation()); });
137
+ i0.ɵɵrepeaterCreate(1, RealtimeWhiteboardToolbarComponent_For_2_Conditional_6_For_2_Template, 2, 5, "span", 29, _forTrack2);
138
+ i0.ɵɵdomElementStart(3, "span", 16);
139
+ i0.ɵɵtext(4, "drag to draw");
140
+ i0.ɵɵdomElementEnd()();
141
+ } if (rf & 2) {
142
+ const ctx_r2 = i0.ɵɵnextContext(2);
143
+ i0.ɵɵadvance();
144
+ i0.ɵɵrepeater(ctx_r2.ShapeKinds);
145
+ } }
146
+ function RealtimeWhiteboardToolbarComponent_For_2_Template(rf, ctx) { if (rf & 1) {
147
+ const _r1 = i0.ɵɵgetCurrentView();
148
+ i0.ɵɵdomElementStart(0, "button", 7);
149
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_For_2_Template_button_click_0_listener() { const entry_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SelectTool(entry_r2.Tool)); });
150
+ i0.ɵɵdomElement(1, "i");
151
+ i0.ɵɵdomElementStart(2, "span", 8);
152
+ i0.ɵɵtext(3);
153
+ i0.ɵɵdomElementEnd();
154
+ i0.ɵɵconditionalCreate(4, RealtimeWhiteboardToolbarComponent_For_2_Conditional_4_Template, 8, 1, "span", 9);
155
+ i0.ɵɵconditionalCreate(5, RealtimeWhiteboardToolbarComponent_For_2_Conditional_5_Template, 13, 3, "span", 10);
156
+ i0.ɵɵconditionalCreate(6, RealtimeWhiteboardToolbarComponent_For_2_Conditional_6_Template, 5, 0, "span", 11);
157
+ i0.ɵɵdomElementEnd();
158
+ } if (rf & 2) {
159
+ const entry_r2 = ctx.$implicit;
160
+ const ctx_r2 = i0.ɵɵnextContext();
161
+ i0.ɵɵclassProp("active", ctx_r2.ActiveTool === entry_r2.Tool);
162
+ i0.ɵɵdomProperty("title", entry_r2.Title);
163
+ i0.ɵɵadvance();
164
+ i0.ɵɵclassMap(entry_r2.Icon);
165
+ i0.ɵɵadvance(2);
166
+ i0.ɵɵtextInterpolate(entry_r2.Kbd);
167
+ i0.ɵɵadvance();
168
+ i0.ɵɵconditional(entry_r2.Tool === "pen" && ctx_r2.ActiveTool === "pen" ? 4 : -1);
169
+ i0.ɵɵadvance();
170
+ i0.ɵɵconditional(entry_r2.Tool === "text" && ctx_r2.ActiveTool === "text" ? 5 : -1);
171
+ i0.ɵɵadvance();
172
+ i0.ɵɵconditional(entry_r2.Tool === "shape" && ctx_r2.ActiveTool === "shape" ? 6 : -1);
173
+ } }
174
+ /**
175
+ * USER pen palette — categorical ink colors. Violet is deliberately EXCLUDED:
176
+ * violet is the reserved ownership hue of the agent's marks.
177
+ */
178
+ export const WHITEBOARD_PEN_COLORS = ['#cbd5e1', '#fbbf24', '#5cc0ed', '#4ade80', '#f87171'];
179
+ /** Available pen stroke widths (px). */
180
+ export const WHITEBOARD_PEN_WIDTHS = [2, 4, 7];
181
+ /**
182
+ * The floating left-edge toolbar of the live whiteboard: tool buttons with kbd hints,
183
+ * the pen color/width flyout (with the "violet = agent's" reservation note), the shape
184
+ * flyout, and undo/redo. Pure presentational — all state in/out via bindings.
185
+ */
186
+ export class RealtimeWhiteboardToolbarComponent {
187
+ constructor() {
188
+ /** The currently active tool. */
189
+ this.ActiveTool = 'select';
190
+ /** Selected pen ink color (from {@link WHITEBOARD_PEN_COLORS}). */
191
+ this.PenColor = WHITEBOARD_PEN_COLORS[0];
192
+ /** Selected pen stroke width. */
193
+ this.PenWidth = 4;
194
+ /** Selected shape kind for drag-create. */
195
+ this.ShapeKind = 'rect';
196
+ /** Selected text font size (curated steps; 12 matches the CSS default). */
197
+ this.TextSize = 12;
198
+ /** Selected text font family. */
199
+ this.TextFamily = 'sans';
200
+ /** Selected text bold state (labels render bold by default). */
201
+ this.TextBold = true;
202
+ /** Selected text color (null = the theme default; palette excludes the agent's violet). */
203
+ this.TextColor = null;
204
+ /** Whether undo / redo are available (drives nothing visually but kept for a11y). */
205
+ this.CanUndo = false;
206
+ this.CanRedo = false;
207
+ /** Display name of the session's agent (the pen flyout note: "violet = Sage's"). */
208
+ this.AgentName = 'Agent';
209
+ this.ToolChange = new EventEmitter();
210
+ this.PenColorChange = new EventEmitter();
211
+ this.PenWidthChange = new EventEmitter();
212
+ this.ShapeKindChange = new EventEmitter();
213
+ this.TextSizeChange = new EventEmitter();
214
+ this.TextFamilyChange = new EventEmitter();
215
+ this.TextBoldChange = new EventEmitter();
216
+ this.TextColorChange = new EventEmitter();
217
+ /** A style choice was made — the board applies it to the selected text/sticky item (if any). */
218
+ this.StyleSelection = new EventEmitter();
219
+ this.Undo = new EventEmitter();
220
+ this.Redo = new EventEmitter();
221
+ this.Tools = [
222
+ { Tool: 'select', Icon: 'fa-solid fa-arrow-pointer', Title: 'Select / move', Kbd: 'V' },
223
+ { Tool: 'pan', Icon: 'fa-regular fa-hand', Title: 'Pan', Kbd: 'H' },
224
+ { Tool: 'pen', Icon: 'fa-solid fa-pen', Title: 'Pen', Kbd: 'P' },
225
+ { Tool: 'shape', Icon: 'fa-regular fa-square', Title: 'Shapes', Kbd: 'R' },
226
+ { Tool: 'sticky', Icon: 'fa-regular fa-note-sticky', Title: 'Sticky note', Kbd: 'S' },
227
+ { Tool: 'text', Icon: 'fa-solid fa-font', Title: 'Text', Kbd: 'T' },
228
+ { Tool: 'markdown', Icon: 'fa-brands fa-markdown', Title: 'Markdown panel', Kbd: 'M' },
229
+ { Tool: 'html', Icon: 'fa-solid fa-code', Title: 'HTML widget (sandboxed)', Kbd: 'W' },
230
+ { Tool: 'image', Icon: 'fa-regular fa-image', Title: 'Paste / insert image', Kbd: 'I' },
231
+ { Tool: 'connector', Icon: 'fa-solid fa-arrow-trend-up', Title: 'Connector', Kbd: 'C' },
232
+ { Tool: 'eraser', Icon: 'fa-solid fa-eraser', Title: 'Eraser', Kbd: 'E' }
233
+ ];
234
+ this.PenColors = WHITEBOARD_PEN_COLORS;
235
+ this.PenWidths = WHITEBOARD_PEN_WIDTHS;
236
+ this.ShapeKinds = [
237
+ { Kind: 'rect', Icon: 'fa-regular fa-square', Title: 'Rectangle' },
238
+ { Kind: 'ellipse', Icon: 'fa-regular fa-circle', Title: 'Ellipse' },
239
+ { Kind: 'diamond', Icon: 'fa-regular fa-square wb-diamond', Title: 'Diamond' }
240
+ ];
241
+ this.TextSizes = WHITEBOARD_FONT_SIZES;
242
+ this.TextFamilies = [
243
+ { Key: 'sans', Title: 'Sans-serif', Stack: 'inherit' },
244
+ { Key: 'serif', Title: 'Serif', Stack: 'Georgia, "Times New Roman", serif' },
245
+ { Key: 'mono', Title: 'Monospace', Stack: 'var(--mj-font-mono, ui-monospace, "SF Mono", Menlo, monospace)' }
246
+ ];
247
+ }
248
+ SelectTool(tool) {
249
+ this.ToolChange.emit(tool);
250
+ }
251
+ // Each pick updates the chosen style for NEW text AND restyles the current
252
+ // text/sticky selection (the board ignores StyleSelection when nothing applies).
253
+ PickTextSize(size) {
254
+ this.TextSizeChange.emit(size);
255
+ this.StyleSelection.emit({ FontSize: size });
256
+ }
257
+ PickTextFamily(family) {
258
+ this.TextFamilyChange.emit(family);
259
+ this.StyleSelection.emit({ FontFamily: family });
260
+ }
261
+ ToggleTextBold() {
262
+ const next = !this.TextBold;
263
+ this.TextBoldChange.emit(next);
264
+ this.StyleSelection.emit({ Bold: next });
265
+ }
266
+ PickTextColor(color) {
267
+ this.TextColorChange.emit(color);
268
+ this.StyleSelection.emit({ Color: color });
269
+ }
270
+ TrackTool(index, entry) {
271
+ return entry.Tool;
272
+ }
273
+ static { this.ɵfac = function RealtimeWhiteboardToolbarComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RealtimeWhiteboardToolbarComponent)(); }; }
274
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RealtimeWhiteboardToolbarComponent, selectors: [["mj-realtime-whiteboard-toolbar"]], inputs: { ActiveTool: "ActiveTool", PenColor: "PenColor", PenWidth: "PenWidth", ShapeKind: "ShapeKind", TextSize: "TextSize", TextFamily: "TextFamily", TextBold: "TextBold", TextColor: "TextColor", CanUndo: "CanUndo", CanRedo: "CanRedo", AgentName: "AgentName" }, outputs: { ToolChange: "ToolChange", PenColorChange: "PenColorChange", PenWidthChange: "PenWidthChange", ShapeKindChange: "ShapeKindChange", TextSizeChange: "TextSizeChange", TextFamilyChange: "TextFamilyChange", TextBoldChange: "TextBoldChange", TextColorChange: "TextColorChange", StyleSelection: "StyleSelection", Undo: "Undo", Redo: "Redo" }, decls: 8, vars: 2, consts: [[1, "board-toolbar"], ["type", "button", 1, "tool", 3, "active", "title"], [1, "tool-sep"], ["type", "button", "title", "Undo", 1, "tool", 3, "click", "disabled"], [1, "fa-solid", "fa-rotate-left"], ["type", "button", "title", "Redo", 1, "tool", 3, "click", "disabled"], [1, "fa-solid", "fa-rotate-right"], ["type", "button", 1, "tool", 3, "click", "title"], [1, "kbd"], [1, "pen-flyout"], [1, "pen-flyout", "text-flyout"], [1, "pen-flyout", "shape-flyout"], [1, "pen-flyout", 3, "click"], [1, "pen-c", 3, "sel", "background"], [1, "pen-w"], [3, "class", "sel"], [1, "pen-note"], [1, "pen-c", 3, "click"], [3, "click"], [1, "pen-flyout", "text-flyout", 3, "click"], [1, "txt-s", 3, "sel", "title"], [1, "txt-fams"], [1, "txt-f", 3, "sel", "title", "fontFamily"], ["title", "Bold", 1, "txt-f", "txt-b", 3, "click"], [1, "fa-solid", "fa-bold"], [1, "txt-colors"], [1, "txt-s", 3, "click", "title"], [1, "txt-f", 3, "click", "title"], [1, "pen-flyout", "shape-flyout", 3, "click"], [1, "shape-c", 3, "sel", "title"], [1, "shape-c", 3, "click", "title"]], template: function RealtimeWhiteboardToolbarComponent_Template(rf, ctx) { if (rf & 1) {
275
+ i0.ɵɵdomElementStart(0, "div", 0);
276
+ i0.ɵɵrepeaterCreate(1, RealtimeWhiteboardToolbarComponent_For_2_Template, 7, 9, "button", 1, _forTrack0);
277
+ i0.ɵɵdomElement(3, "div", 2);
278
+ i0.ɵɵdomElementStart(4, "button", 3);
279
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_Template_button_click_4_listener() { return ctx.Undo.emit(); });
280
+ i0.ɵɵdomElement(5, "i", 4);
281
+ i0.ɵɵdomElementEnd();
282
+ i0.ɵɵdomElementStart(6, "button", 5);
283
+ i0.ɵɵdomListener("click", function RealtimeWhiteboardToolbarComponent_Template_button_click_6_listener() { return ctx.Redo.emit(); });
284
+ i0.ɵɵdomElement(7, "i", 6);
285
+ i0.ɵɵdomElementEnd()();
286
+ } if (rf & 2) {
287
+ i0.ɵɵadvance();
288
+ i0.ɵɵrepeater(ctx.Tools);
289
+ i0.ɵɵadvance(3);
290
+ i0.ɵɵdomProperty("disabled", !ctx.CanUndo);
291
+ i0.ɵɵadvance(2);
292
+ i0.ɵɵdomProperty("disabled", !ctx.CanRedo);
293
+ } }, dependencies: [CommonModule], styles: ["\n\n\n\n[_nghost-%COMP%] {\n display: block;\n position: absolute;\n left: 14px;\n top: 14px;\n z-index: 10;\n}\n\n.board-toolbar[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 6px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg, 12px);\n box-shadow: var(--mj-shadow-xl, 0 20px 25px -5px rgba(0, 0, 0, 0.3));\n}\n\n.tool[_ngcontent-%COMP%] {\n position: relative;\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md, 8px);\n border: 0;\n cursor: pointer;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13.5px;\n display: grid;\n place-items: center;\n transition: all 130ms ease;\n font-family: inherit;\n}\n.tool[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.tool.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #fff);\n box-shadow: var(--mj-shadow-brand, 0 4px 14px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent));\n}\n.tool[_ngcontent-%COMP%]:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.tool[_ngcontent-%COMP%]:disabled:hover {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n.tool[_ngcontent-%COMP%] .kbd[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 1px;\n right: 3px;\n font-size: 7px;\n font-weight: 700;\n color: currentColor;\n opacity: 0.55;\n}\n\n.tool-sep[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 4px;\n}\n\n\n\n.pen-flyout[_ngcontent-%COMP%] {\n position: absolute;\n left: calc(100% + 10px);\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 8px 11px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full, 9999px);\n box-shadow: var(--mj-shadow-xl, 0 20px 25px -5px rgba(0, 0, 0, 0.3));\n white-space: nowrap;\n cursor: default;\n}\n.pen-flyout[_ngcontent-%COMP%]::before {\n content: \"\";\n position: absolute;\n left: -5px;\n top: calc(50% - 5px);\n width: 9px;\n height: 9px;\n transform: rotate(45deg);\n background: var(--mj-bg-surface-card);\n border-left: 1px solid var(--mj-border-default);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.pen-c[_ngcontent-%COMP%] {\n width: 17px;\n height: 17px;\n border-radius: 50%;\n cursor: pointer;\n border: 2px solid transparent;\n}\n.pen-c.sel[_ngcontent-%COMP%] {\n border-color: var(--mj-text-inverse, #fff);\n box-shadow: 0 0 0 2px var(--mj-brand-primary);\n}\n\n.pen-w[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 7px;\n padding-left: 9px;\n border-left: 1px solid var(--mj-border-default);\n}\n.pen-w[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n border-radius: 99px;\n background: var(--mj-text-secondary);\n cursor: pointer;\n}\n.pen-w[_ngcontent-%COMP%] .w1[_ngcontent-%COMP%] { width: 14px; height: 2px; }\n.pen-w[_ngcontent-%COMP%] .w2[_ngcontent-%COMP%] { width: 14px; height: 4px; }\n.pen-w[_ngcontent-%COMP%] .w3[_ngcontent-%COMP%] { width: 14px; height: 7px; }\n.pen-w[_ngcontent-%COMP%] span.sel[_ngcontent-%COMP%] {\n background: var(--mj-brand-accent, var(--mj-brand-primary));\n outline: 2px solid color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n outline-offset: 2px;\n}\n\n.pen-note[_ngcontent-%COMP%] {\n font-size: 9.5px;\n color: var(--mj-text-muted);\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding-left: 9px;\n border-left: 1px solid var(--mj-border-default);\n}\n\n\n\n.shape-c[_ngcontent-%COMP%] {\n width: 22px;\n height: 22px;\n border-radius: var(--mj-radius-md, 8px);\n display: grid;\n place-items: center;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 12px;\n}\n.shape-c[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n.shape-c.sel[_ngcontent-%COMP%] {\n color: var(--mj-brand-accent, var(--mj-brand-primary));\n outline: 2px solid color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n outline-offset: 1px;\n}\n.shape-c[_ngcontent-%COMP%] i.wb-diamond[_ngcontent-%COMP%] {\n transform: rotate(45deg);\n font-size: 10px;\n}\n\n\n\n.text-flyout[_ngcontent-%COMP%] {\n gap: 6px;\n}\n.txt-s[_ngcontent-%COMP%] {\n min-width: 20px;\n height: 20px;\n padding: 0 3px;\n border-radius: var(--mj-radius-md, 8px);\n display: grid;\n place-items: center;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 10px;\n font-weight: 700;\n}\n.txt-s[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n.txt-s.sel[_ngcontent-%COMP%] {\n color: var(--mj-brand-accent, var(--mj-brand-primary));\n outline: 2px solid color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n outline-offset: 1px;\n}\n\n.txt-fams[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding-left: 9px;\n border-left: 1px solid var(--mj-border-default);\n}\n.txt-f[_ngcontent-%COMP%] {\n width: 22px;\n height: 22px;\n border-radius: var(--mj-radius-md, 8px);\n display: grid;\n place-items: center;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 11px;\n font-weight: 600;\n}\n.txt-f[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n.txt-f.sel[_ngcontent-%COMP%] {\n color: var(--mj-brand-accent, var(--mj-brand-primary));\n outline: 2px solid color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n outline-offset: 1px;\n}\n.txt-b[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.txt-colors[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 9px;\n padding-left: 9px;\n border-left: 1px solid var(--mj-border-default);\n}"] }); }
294
+ }
295
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RealtimeWhiteboardToolbarComponent, [{
296
+ type: Component,
297
+ args: [{ standalone: true, selector: 'mj-realtime-whiteboard-toolbar', imports: [CommonModule], template: "<div class=\"board-toolbar\">\n @for (entry of Tools; track entry.Tool) {\n <button type=\"button\"\n class=\"tool\"\n [class.active]=\"ActiveTool === entry.Tool\"\n [title]=\"entry.Title\"\n (click)=\"SelectTool(entry.Tool)\">\n <i [class]=\"entry.Icon\"></i><span class=\"kbd\">{{ entry.Kbd }}</span>\n\n @if (entry.Tool === 'pen' && ActiveTool === 'pen') {\n <span class=\"pen-flyout\" (click)=\"$event.stopPropagation()\">\n @for (color of PenColors; track color) {\n <span class=\"pen-c\"\n [class.sel]=\"PenColor === color\"\n [style.background]=\"color\"\n (click)=\"PenColorChange.emit(color)\"></span>\n }\n <span class=\"pen-w\">\n @for (width of PenWidths; track width; let i = $index) {\n <span [class]=\"'w' + (i + 1)\"\n [class.sel]=\"PenWidth === width\"\n (click)=\"PenWidthChange.emit(width)\"></span>\n }\n </span>\n <span class=\"pen-note\">violet = {{ AgentName }}'s</span>\n </span>\n }\n\n @if (entry.Tool === 'text' && ActiveTool === 'text') {\n <span class=\"pen-flyout text-flyout\" (click)=\"$event.stopPropagation()\">\n @for (size of TextSizes; track size) {\n <span class=\"txt-s\"\n [class.sel]=\"TextSize === size\"\n [title]=\"size + ' px'\"\n (click)=\"PickTextSize(size)\">{{ size }}</span>\n }\n <span class=\"txt-fams\">\n @for (fam of TextFamilies; track fam.Key) {\n <span class=\"txt-f\"\n [class.sel]=\"TextFamily === fam.Key\"\n [title]=\"fam.Title\"\n [style.fontFamily]=\"fam.Stack\"\n (click)=\"PickTextFamily(fam.Key)\">Ag</span>\n }\n <span class=\"txt-f txt-b\"\n [class.sel]=\"TextBold\"\n title=\"Bold\"\n (click)=\"ToggleTextBold()\"><i class=\"fa-solid fa-bold\"></i></span>\n </span>\n <span class=\"txt-colors\">\n @for (color of PenColors; track color) {\n <span class=\"pen-c\"\n [class.sel]=\"TextColor === color\"\n [style.background]=\"color\"\n (click)=\"PickTextColor(color)\"></span>\n }\n </span>\n <span class=\"pen-note\">violet = {{ AgentName }}'s</span>\n </span>\n }\n\n @if (entry.Tool === 'shape' && ActiveTool === 'shape') {\n <span class=\"pen-flyout shape-flyout\" (click)=\"$event.stopPropagation()\">\n @for (shape of ShapeKinds; track shape.Kind) {\n <span class=\"shape-c\"\n [class.sel]=\"ShapeKind === shape.Kind\"\n [title]=\"shape.Title\"\n (click)=\"ShapeKindChange.emit(shape.Kind)\"><i [class]=\"shape.Icon\"></i></span>\n }\n <span class=\"pen-note\">drag to draw</span>\n </span>\n }\n </button>\n }\n\n <div class=\"tool-sep\"></div>\n <button type=\"button\" class=\"tool\" title=\"Undo\" [disabled]=\"!CanUndo\" (click)=\"Undo.emit()\">\n <i class=\"fa-solid fa-rotate-left\"></i>\n </button>\n <button type=\"button\" class=\"tool\" title=\"Redo\" [disabled]=\"!CanRedo\" (click)=\"Redo.emit()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n </button>\n</div>\n", styles: ["/* Floating left-edge board toolbar \u2014 ported pixel-faithfully from\n plans/realtime/mockups/whiteboard.html (.board-toolbar / .tool / .pen-flyout). */\n\n:host {\n display: block;\n position: absolute;\n left: 14px;\n top: 14px;\n z-index: 10;\n}\n\n.board-toolbar {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 6px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg, 12px);\n box-shadow: var(--mj-shadow-xl, 0 20px 25px -5px rgba(0, 0, 0, 0.3));\n}\n\n.tool {\n position: relative;\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md, 8px);\n border: 0;\n cursor: pointer;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 13.5px;\n display: grid;\n place-items: center;\n transition: all 130ms ease;\n font-family: inherit;\n}\n.tool:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.tool.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, #fff);\n box-shadow: var(--mj-shadow-brand, 0 4px 14px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent));\n}\n.tool:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.tool:disabled:hover {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n.tool .kbd {\n position: absolute;\n bottom: 1px;\n right: 3px;\n font-size: 7px;\n font-weight: 700;\n color: currentColor;\n opacity: 0.55;\n}\n\n.tool-sep {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 4px;\n}\n\n/* ---------- pen / shape flyout ---------- */\n.pen-flyout {\n position: absolute;\n left: calc(100% + 10px);\n top: 50%;\n transform: translateY(-50%);\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 8px 11px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full, 9999px);\n box-shadow: var(--mj-shadow-xl, 0 20px 25px -5px rgba(0, 0, 0, 0.3));\n white-space: nowrap;\n cursor: default;\n}\n.pen-flyout::before {\n content: \"\";\n position: absolute;\n left: -5px;\n top: calc(50% - 5px);\n width: 9px;\n height: 9px;\n transform: rotate(45deg);\n background: var(--mj-bg-surface-card);\n border-left: 1px solid var(--mj-border-default);\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.pen-c {\n width: 17px;\n height: 17px;\n border-radius: 50%;\n cursor: pointer;\n border: 2px solid transparent;\n}\n.pen-c.sel {\n border-color: var(--mj-text-inverse, #fff);\n box-shadow: 0 0 0 2px var(--mj-brand-primary);\n}\n\n.pen-w {\n display: flex;\n align-items: center;\n gap: 7px;\n padding-left: 9px;\n border-left: 1px solid var(--mj-border-default);\n}\n.pen-w span {\n border-radius: 99px;\n background: var(--mj-text-secondary);\n cursor: pointer;\n}\n.pen-w .w1 { width: 14px; height: 2px; }\n.pen-w .w2 { width: 14px; height: 4px; }\n.pen-w .w3 { width: 14px; height: 7px; }\n.pen-w span.sel {\n background: var(--mj-brand-accent, var(--mj-brand-primary));\n outline: 2px solid color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n outline-offset: 2px;\n}\n\n.pen-note {\n font-size: 9.5px;\n color: var(--mj-text-muted);\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding-left: 9px;\n border-left: 1px solid var(--mj-border-default);\n}\n\n/* shape flyout reuses pen-flyout chrome */\n.shape-c {\n width: 22px;\n height: 22px;\n border-radius: var(--mj-radius-md, 8px);\n display: grid;\n place-items: center;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 12px;\n}\n.shape-c:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n.shape-c.sel {\n color: var(--mj-brand-accent, var(--mj-brand-primary));\n outline: 2px solid color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n outline-offset: 1px;\n}\n.shape-c i.wb-diamond {\n transform: rotate(45deg);\n font-size: 10px;\n}\n\n/* ---------- text-style flyout (reuses pen-flyout chrome) ---------- */\n.text-flyout {\n gap: 6px;\n}\n.txt-s {\n min-width: 20px;\n height: 20px;\n padding: 0 3px;\n border-radius: var(--mj-radius-md, 8px);\n display: grid;\n place-items: center;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 10px;\n font-weight: 700;\n}\n.txt-s:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n.txt-s.sel {\n color: var(--mj-brand-accent, var(--mj-brand-primary));\n outline: 2px solid color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n outline-offset: 1px;\n}\n\n.txt-fams {\n display: flex;\n align-items: center;\n gap: 6px;\n padding-left: 9px;\n border-left: 1px solid var(--mj-border-default);\n}\n.txt-f {\n width: 22px;\n height: 22px;\n border-radius: var(--mj-radius-md, 8px);\n display: grid;\n place-items: center;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 11px;\n font-weight: 600;\n}\n.txt-f:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n.txt-f.sel {\n color: var(--mj-brand-accent, var(--mj-brand-primary));\n outline: 2px solid color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n outline-offset: 1px;\n}\n.txt-b {\n font-size: 10px;\n}\n\n.txt-colors {\n display: flex;\n align-items: center;\n gap: 9px;\n padding-left: 9px;\n border-left: 1px solid var(--mj-border-default);\n}\n"] }]
298
+ }], null, { ActiveTool: [{
299
+ type: Input
300
+ }], PenColor: [{
301
+ type: Input
302
+ }], PenWidth: [{
303
+ type: Input
304
+ }], ShapeKind: [{
305
+ type: Input
306
+ }], TextSize: [{
307
+ type: Input
308
+ }], TextFamily: [{
309
+ type: Input
310
+ }], TextBold: [{
311
+ type: Input
312
+ }], TextColor: [{
313
+ type: Input
314
+ }], CanUndo: [{
315
+ type: Input
316
+ }], CanRedo: [{
317
+ type: Input
318
+ }], AgentName: [{
319
+ type: Input
320
+ }], ToolChange: [{
321
+ type: Output
322
+ }], PenColorChange: [{
323
+ type: Output
324
+ }], PenWidthChange: [{
325
+ type: Output
326
+ }], ShapeKindChange: [{
327
+ type: Output
328
+ }], TextSizeChange: [{
329
+ type: Output
330
+ }], TextFamilyChange: [{
331
+ type: Output
332
+ }], TextBoldChange: [{
333
+ type: Output
334
+ }], TextColorChange: [{
335
+ type: Output
336
+ }], StyleSelection: [{
337
+ type: Output
338
+ }], Undo: [{
339
+ type: Output
340
+ }], Redo: [{
341
+ type: Output
342
+ }] }); })();
343
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RealtimeWhiteboardToolbarComponent, { className: "RealtimeWhiteboardToolbarComponent", filePath: "src/lib/whiteboard-toolbar.component.ts", lineNumber: 55 }); })();
344
+ //# sourceMappingURL=whiteboard-toolbar.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whiteboard-toolbar.component.js","sourceRoot":"","sources":["../../src/lib/whiteboard-toolbar.component.ts","../../src/lib/whiteboard-toolbar.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { WHITEBOARD_FONT_SIZES, WhiteboardFontFamily, WhiteboardShapeKind } from './whiteboard-state';\n\n/** A user-selectable board tool. */\nexport type WhiteboardTool = 'select' | 'pan' | 'pen' | 'shape' | 'sticky' | 'text' | 'markdown' | 'html' | 'image' | 'connector' | 'eraser';\n\n/** One entry in the floating toolbar. */\ninterface ToolbarEntry {\n Tool: WhiteboardTool;\n Icon: string;\n Title: string;\n Kbd: string;\n}\n\n/**\n * USER pen palette — categorical ink colors. Violet is deliberately EXCLUDED:\n * violet is the reserved ownership hue of the agent's marks.\n */\nexport const WHITEBOARD_PEN_COLORS: readonly string[] = ['#cbd5e1', '#fbbf24', '#5cc0ed', '#4ade80', '#f87171'];\n\n/** Available pen stroke widths (px). */\nexport const WHITEBOARD_PEN_WIDTHS: readonly number[] = [2, 4, 7];\n\n/**\n * A partial text-style choice emitted when the user picks a style with an existing\n * text / sticky selection — the board applies it to the selected item via the state engine.\n */\nexport interface WhiteboardTextStyleEvent {\n FontSize?: number;\n FontFamily?: WhiteboardFontFamily;\n Bold?: boolean;\n Color?: string;\n}\n\n/** One font-family choice in the text-style flyout (key + preview stack). */\ninterface FontFamilyEntry {\n Key: WhiteboardFontFamily;\n Title: string;\n Stack: string;\n}\n\n/**\n * The floating left-edge toolbar of the live whiteboard: tool buttons with kbd hints,\n * the pen color/width flyout (with the \"violet = agent's\" reservation note), the shape\n * flyout, and undo/redo. Pure presentational — all state in/out via bindings.\n */\n@Component({\n standalone: true,\n selector: 'mj-realtime-whiteboard-toolbar',\n imports: [CommonModule],\n templateUrl: './whiteboard-toolbar.component.html',\n styleUrl: './whiteboard-toolbar.component.css'\n})\nexport class RealtimeWhiteboardToolbarComponent {\n /** The currently active tool. */\n @Input() ActiveTool: WhiteboardTool = 'select';\n /** Selected pen ink color (from {@link WHITEBOARD_PEN_COLORS}). */\n @Input() PenColor: string = WHITEBOARD_PEN_COLORS[0];\n /** Selected pen stroke width. */\n @Input() PenWidth = 4;\n /** Selected shape kind for drag-create. */\n @Input() ShapeKind: WhiteboardShapeKind = 'rect';\n /** Selected text font size (curated steps; 12 matches the CSS default). */\n @Input() TextSize = 12;\n /** Selected text font family. */\n @Input() TextFamily: WhiteboardFontFamily = 'sans';\n /** Selected text bold state (labels render bold by default). */\n @Input() TextBold = true;\n /** Selected text color (null = the theme default; palette excludes the agent's violet). */\n @Input() TextColor: string | null = null;\n /** Whether undo / redo are available (drives nothing visually but kept for a11y). */\n @Input() CanUndo = false;\n @Input() CanRedo = false;\n /** Display name of the session's agent (the pen flyout note: \"violet = Sage's\"). */\n @Input() AgentName = 'Agent';\n\n @Output() ToolChange = new EventEmitter<WhiteboardTool>();\n @Output() PenColorChange = new EventEmitter<string>();\n @Output() PenWidthChange = new EventEmitter<number>();\n @Output() ShapeKindChange = new EventEmitter<WhiteboardShapeKind>();\n @Output() TextSizeChange = new EventEmitter<number>();\n @Output() TextFamilyChange = new EventEmitter<WhiteboardFontFamily>();\n @Output() TextBoldChange = new EventEmitter<boolean>();\n @Output() TextColorChange = new EventEmitter<string>();\n /** A style choice was made — the board applies it to the selected text/sticky item (if any). */\n @Output() StyleSelection = new EventEmitter<WhiteboardTextStyleEvent>();\n @Output() Undo = new EventEmitter<void>();\n @Output() Redo = new EventEmitter<void>();\n\n public readonly Tools: ToolbarEntry[] = [\n { Tool: 'select', Icon: 'fa-solid fa-arrow-pointer', Title: 'Select / move', Kbd: 'V' },\n { Tool: 'pan', Icon: 'fa-regular fa-hand', Title: 'Pan', Kbd: 'H' },\n { Tool: 'pen', Icon: 'fa-solid fa-pen', Title: 'Pen', Kbd: 'P' },\n { Tool: 'shape', Icon: 'fa-regular fa-square', Title: 'Shapes', Kbd: 'R' },\n { Tool: 'sticky', Icon: 'fa-regular fa-note-sticky', Title: 'Sticky note', Kbd: 'S' },\n { Tool: 'text', Icon: 'fa-solid fa-font', Title: 'Text', Kbd: 'T' },\n { Tool: 'markdown', Icon: 'fa-brands fa-markdown', Title: 'Markdown panel', Kbd: 'M' },\n { Tool: 'html', Icon: 'fa-solid fa-code', Title: 'HTML widget (sandboxed)', Kbd: 'W' },\n { Tool: 'image', Icon: 'fa-regular fa-image', Title: 'Paste / insert image', Kbd: 'I' },\n { Tool: 'connector', Icon: 'fa-solid fa-arrow-trend-up', Title: 'Connector', Kbd: 'C' },\n { Tool: 'eraser', Icon: 'fa-solid fa-eraser', Title: 'Eraser', Kbd: 'E' }\n ];\n\n public readonly PenColors = WHITEBOARD_PEN_COLORS;\n public readonly PenWidths = WHITEBOARD_PEN_WIDTHS;\n public readonly ShapeKinds: { Kind: WhiteboardShapeKind; Icon: string; Title: string }[] = [\n { Kind: 'rect', Icon: 'fa-regular fa-square', Title: 'Rectangle' },\n { Kind: 'ellipse', Icon: 'fa-regular fa-circle', Title: 'Ellipse' },\n { Kind: 'diamond', Icon: 'fa-regular fa-square wb-diamond', Title: 'Diamond' }\n ];\n public readonly TextSizes = WHITEBOARD_FONT_SIZES;\n public readonly TextFamilies: FontFamilyEntry[] = [\n { Key: 'sans', Title: 'Sans-serif', Stack: 'inherit' },\n { Key: 'serif', Title: 'Serif', Stack: 'Georgia, \"Times New Roman\", serif' },\n { Key: 'mono', Title: 'Monospace', Stack: 'var(--mj-font-mono, ui-monospace, \"SF Mono\", Menlo, monospace)' }\n ];\n\n public SelectTool(tool: WhiteboardTool): void {\n this.ToolChange.emit(tool);\n }\n\n // Each pick updates the chosen style for NEW text AND restyles the current\n // text/sticky selection (the board ignores StyleSelection when nothing applies).\n public PickTextSize(size: number): void {\n this.TextSizeChange.emit(size);\n this.StyleSelection.emit({ FontSize: size });\n }\n\n public PickTextFamily(family: WhiteboardFontFamily): void {\n this.TextFamilyChange.emit(family);\n this.StyleSelection.emit({ FontFamily: family });\n }\n\n public ToggleTextBold(): void {\n const next = !this.TextBold;\n this.TextBoldChange.emit(next);\n this.StyleSelection.emit({ Bold: next });\n }\n\n public PickTextColor(color: string): void {\n this.TextColorChange.emit(color);\n this.StyleSelection.emit({ Color: color });\n }\n\n public TrackTool(index: number, entry: ToolbarEntry): WhiteboardTool {\n return entry.Tool;\n }\n}\n","<div class=\"board-toolbar\">\n @for (entry of Tools; track entry.Tool) {\n <button type=\"button\"\n class=\"tool\"\n [class.active]=\"ActiveTool === entry.Tool\"\n [title]=\"entry.Title\"\n (click)=\"SelectTool(entry.Tool)\">\n <i [class]=\"entry.Icon\"></i><span class=\"kbd\">{{ entry.Kbd }}</span>\n\n @if (entry.Tool === 'pen' && ActiveTool === 'pen') {\n <span class=\"pen-flyout\" (click)=\"$event.stopPropagation()\">\n @for (color of PenColors; track color) {\n <span class=\"pen-c\"\n [class.sel]=\"PenColor === color\"\n [style.background]=\"color\"\n (click)=\"PenColorChange.emit(color)\"></span>\n }\n <span class=\"pen-w\">\n @for (width of PenWidths; track width; let i = $index) {\n <span [class]=\"'w' + (i + 1)\"\n [class.sel]=\"PenWidth === width\"\n (click)=\"PenWidthChange.emit(width)\"></span>\n }\n </span>\n <span class=\"pen-note\">violet = {{ AgentName }}'s</span>\n </span>\n }\n\n @if (entry.Tool === 'text' && ActiveTool === 'text') {\n <span class=\"pen-flyout text-flyout\" (click)=\"$event.stopPropagation()\">\n @for (size of TextSizes; track size) {\n <span class=\"txt-s\"\n [class.sel]=\"TextSize === size\"\n [title]=\"size + ' px'\"\n (click)=\"PickTextSize(size)\">{{ size }}</span>\n }\n <span class=\"txt-fams\">\n @for (fam of TextFamilies; track fam.Key) {\n <span class=\"txt-f\"\n [class.sel]=\"TextFamily === fam.Key\"\n [title]=\"fam.Title\"\n [style.fontFamily]=\"fam.Stack\"\n (click)=\"PickTextFamily(fam.Key)\">Ag</span>\n }\n <span class=\"txt-f txt-b\"\n [class.sel]=\"TextBold\"\n title=\"Bold\"\n (click)=\"ToggleTextBold()\"><i class=\"fa-solid fa-bold\"></i></span>\n </span>\n <span class=\"txt-colors\">\n @for (color of PenColors; track color) {\n <span class=\"pen-c\"\n [class.sel]=\"TextColor === color\"\n [style.background]=\"color\"\n (click)=\"PickTextColor(color)\"></span>\n }\n </span>\n <span class=\"pen-note\">violet = {{ AgentName }}'s</span>\n </span>\n }\n\n @if (entry.Tool === 'shape' && ActiveTool === 'shape') {\n <span class=\"pen-flyout shape-flyout\" (click)=\"$event.stopPropagation()\">\n @for (shape of ShapeKinds; track shape.Kind) {\n <span class=\"shape-c\"\n [class.sel]=\"ShapeKind === shape.Kind\"\n [title]=\"shape.Title\"\n (click)=\"ShapeKindChange.emit(shape.Kind)\"><i [class]=\"shape.Icon\"></i></span>\n }\n <span class=\"pen-note\">drag to draw</span>\n </span>\n }\n </button>\n }\n\n <div class=\"tool-sep\"></div>\n <button type=\"button\" class=\"tool\" title=\"Undo\" [disabled]=\"!CanUndo\" (click)=\"Undo.emit()\">\n <i class=\"fa-solid fa-rotate-left\"></i>\n </button>\n <button type=\"button\" class=\"tool\" title=\"Redo\" [disabled]=\"!CanRedo\" (click)=\"Redo.emit()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n </button>\n</div>\n"]}
@@ -0,0 +1,103 @@
1
+ import { WhiteboardState } from './whiteboard-state';
2
+ /**
3
+ * WHITEBOARD — the programmatic (agent-facing) mutation tool surface.
4
+ *
5
+ * Angular-free on purpose: `ApplyWhiteboardAgentTool` is the pure round-trip the host
6
+ * component delegates to (the host adds the UI garnish — violet pop-in, toast, presence
7
+ * cursor). The integration layer registers {@link WHITEBOARD_TOOL_DEFINITIONS} with its
8
+ * agent/automation runtime so a co-author can call `Whiteboard_AddNote` etc.; tool-call
9
+ * frames are routed back through {@link ApplyWhiteboardAgentTool}, which returns the JSON
10
+ * result string fed back to the caller (e.g. as a realtime model's `tool_response`).
11
+ */
12
+ /**
13
+ * Any JSON-serializable value (the building block of {@link WhiteboardToolJSONObject}).
14
+ * Structurally identical to `JSONValue` from `@memberjunction/ai` — re-declared locally
15
+ * so this generic package carries no AI-framework dependency.
16
+ */
17
+ export type WhiteboardToolJSONValue = string | number | boolean | null | WhiteboardToolJSONValue[] | {
18
+ [key: string]: WhiteboardToolJSONValue;
19
+ };
20
+ /** A JSON object (string-keyed map of {@link WhiteboardToolJSONValue}). */
21
+ export type WhiteboardToolJSONObject = {
22
+ [key: string]: WhiteboardToolJSONValue;
23
+ };
24
+ /**
25
+ * One JSON-described programmatic whiteboard tool: a name, a model-facing description,
26
+ * and a JSON-schema parameter object. Structurally identical to (mutually assignable
27
+ * with) `RealtimeToolDefinition` from `@memberjunction/ai`, re-declared locally so the
28
+ * package stays dependency-light — consumers integrating with the MJ realtime stack can
29
+ * pass {@link WHITEBOARD_TOOL_DEFINITIONS} straight into APIs typed against
30
+ * `RealtimeToolDefinition[]`.
31
+ */
32
+ export interface WhiteboardToolDefinition {
33
+ /** The tool's name, used to match tool-call frames back to {@link ApplyWhiteboardAgentTool}. */
34
+ Name: string;
35
+ /** Human/model-readable description of what the tool does (drives when it gets called). */
36
+ Description: string;
37
+ /** A JSON-schema object describing the tool's parameters. */
38
+ ParametersSchema: WhiteboardToolJSONObject;
39
+ }
40
+ /** Result payload (serialized to JSON) returned from every whiteboard tool call. */
41
+ export interface WhiteboardToolResult {
42
+ success: boolean;
43
+ /** ID of the item the tool created / mutated (when applicable). */
44
+ itemId?: string;
45
+ /** ID of the page the tool created / switched to / renamed (page tools only). */
46
+ pageId?: string;
47
+ /** Human summary the model can narrate ("Added a sticky note …"). */
48
+ summary?: string;
49
+ /** Error description when `success` is false. */
50
+ error?: string;
51
+ }
52
+ /**
53
+ * The shared name prefix of every whiteboard tool — the key an integration layer uses to
54
+ * route all `Whiteboard_*` tool calls locally to {@link ApplyWhiteboardAgentTool} (e.g.
55
+ * MJ's realtime sessions register it with `RealtimeSessionService.RegisterClientToolHandler`
56
+ * so calls execute in the browser instead of the server relay).
57
+ */
58
+ export declare const WHITEBOARD_TOOL_PREFIX = "Whiteboard_";
59
+ /** Names of the whiteboard tools, as registered with the agent/automation runtime. */
60
+ export declare const WHITEBOARD_TOOL_NAMES: {
61
+ readonly AddNote: "Whiteboard_AddNote";
62
+ readonly AddShape: "Whiteboard_AddShape";
63
+ readonly AddText: "Whiteboard_AddText";
64
+ readonly AddMarkdown: "Whiteboard_AddMarkdown";
65
+ readonly AddHtml: "Whiteboard_AddHtml";
66
+ readonly UpdateContent: "Whiteboard_UpdateContent";
67
+ readonly DrawConnector: "Whiteboard_DrawConnector";
68
+ readonly Highlight: "Whiteboard_Highlight";
69
+ readonly MoveItem: "Whiteboard_MoveItem";
70
+ readonly RemoveItem: "Whiteboard_RemoveItem";
71
+ readonly StyleItem: "Whiteboard_StyleItem";
72
+ readonly AddPage: "Whiteboard_AddPage";
73
+ readonly SwitchPage: "Whiteboard_SwitchPage";
74
+ readonly RenamePage: "Whiteboard_RenamePage";
75
+ };
76
+ /** Max markdown source length accepted by AddMarkdown / UpdateContent (chars). */
77
+ export declare const WHITEBOARD_MARKDOWN_MAX_CHARS = 32000;
78
+ /** Max HTML source length accepted by AddHtml / UpdateContent (chars). */
79
+ export declare const WHITEBOARD_HTML_MAX_CHARS = 64000;
80
+ /**
81
+ * The shared sentence appended (once, programmatically — see
82
+ * {@link WHITEBOARD_TOOL_DEFINITIONS}) to every ITEM tool's description, so the model
83
+ * always knows item operations are scoped to the page that is currently active.
84
+ */
85
+ export declare const WHITEBOARD_ACTIVE_PAGE_NOTE = " This tool targets the ACTIVE page only \u2014 use Whiteboard_SwitchPage first to work with items on another page.";
86
+ /**
87
+ * The full `Whiteboard_*` tool set, ready for registration with an agent/automation
88
+ * runtime (shape-compatible with `RealtimeToolDefinition` from `@memberjunction/ai`).
89
+ *
90
+ * Every ITEM tool's description carries the shared {@link WHITEBOARD_ACTIVE_PAGE_NOTE}
91
+ * sentence (appended programmatically here — ONE mechanism, not eleven hand edits);
92
+ * the three page tools keep their page-navigation descriptions unmodified.
93
+ */
94
+ export declare const WHITEBOARD_TOOL_DEFINITIONS: WhiteboardToolDefinition[];
95
+ /**
96
+ * Execute one agent whiteboard tool against the state engine (author `'agent'`, one undo
97
+ * batch per call) and return the JSON result string for the tool round-trip.
98
+ *
99
+ * Never throws: malformed args / unknown tools / unknown item IDs return a
100
+ * `{ success: false, error }` payload so the model can self-correct conversationally.
101
+ */
102
+ export declare function ApplyWhiteboardAgentTool(state: WhiteboardState, toolName: string, argsJson: string): string;
103
+ //# sourceMappingURL=whiteboard-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whiteboard-tools.d.ts","sourceRoot":"","sources":["../../src/lib/whiteboard-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAEsD,eAAe,EAC3E,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;GASG;AAEH;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAC/B,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,uBAAuB,EAAE,GACzB;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,CAAC;AAE/C,2EAA2E;AAC3E,MAAM,MAAM,wBAAwB,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAAA;CAAE,CAAC;AAElF;;;;;;;GAOG;AACH,MAAM,WAAW,wBAAwB;IACvC,gGAAgG;IAChG,IAAI,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,gBAAgB,EAAE,wBAAwB,CAAC;CAC5C;AAED,oFAAoF;AACpF,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD,sFAAsF;AACtF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;CAexB,CAAC;AAEX,kFAAkF;AAClF,eAAO,MAAM,6BAA6B,QAAS,CAAC;AACpD,0EAA0E;AAC1E,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAYhD;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,uHACyE,CAAC;AA4MlH;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,EAAE,wBAAwB,EAIkB,CAAC;AA0FrF;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA+B3G"}