@m2c2kit/core 0.3.17 → 0.3.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,87 +1,4 @@
1
- import { Canvas, Typeface, TypefaceFontProvider, Image, CanvasKit, Surface, Font, Paint, ParagraphBuilder, Paragraph, FontMgr, Path, PaintStyle } from 'canvaskit-wasm';
2
-
3
- declare class GlobalVariables {
4
- now: number;
5
- deltaTime: number;
6
- canvasScale: number;
7
- rootScale: number;
8
- canvasCssWidth: number;
9
- canvasCssHeight: number;
10
- }
11
-
12
- declare global {
13
- var Globals: GlobalVariables;
14
- }
15
- //# sourceMappingURL=Globals.d.ts.map
16
-
17
- /**
18
- * Base interface for all m2c2kit events.
19
- *
20
- * @remarks I would have named it Event, but that would collide with
21
- * the existing DOM Event
22
- */
23
- interface M2Event<T> {
24
- /** Type of event. */
25
- type: M2EventType | string;
26
- /** The object on which the event occurred. */
27
- target: T;
28
- /** Has the event been taken care of by the listener and not be dispatched to other targets? */
29
- handled?: boolean;
30
- }
31
- /**
32
- * The different events that are dispatched by m2c2kit core.
33
- */
34
- declare const M2EventType: {
35
- readonly ActivityStart: "ActivityStart";
36
- readonly ActivityEnd: "ActivityEnd";
37
- readonly ActivityCancel: "ActivityCancel";
38
- readonly ActivityData: "ActivityData";
39
- readonly GameWarmupStart: "GameWarmupStart";
40
- readonly GameWarmupEnd: "GameWarmupEnd";
41
- readonly TapDown: "TapDown";
42
- readonly TapUp: "TapUp";
43
- readonly TapUpAny: "TapUpAny";
44
- readonly TapLeave: "TapLeave";
45
- readonly PointerDown: "PointerDown";
46
- readonly PointerUp: "PointerUp";
47
- readonly PointerMove: "PointerMove";
48
- readonly PointerLeave: "PointerLeave";
49
- readonly Drag: "Drag";
50
- readonly DragStart: "DragStart";
51
- readonly DragEnd: "DragEnd";
52
- readonly CompositeCustom: "CompositeCustom";
53
- readonly FrameDidSimulatePhysics: "FrameDidSimulatePhysics";
54
- readonly SceneSetup: "SceneSetup";
55
- readonly SceneAppear: "SceneAppear";
56
- };
57
- type M2EventType = (typeof M2EventType)[keyof typeof M2EventType];
58
-
59
- /**
60
- * Base interface for all m2c2kit event listeners.
61
- */
62
- interface M2EventListener<T> {
63
- /** Type of event to listen for. */
64
- type: M2EventType | string;
65
- /** Callback function to be called when the event is dispatched. */
66
- callback: (event: T) => void;
67
- /** Optional key (string identifier) used to identify the event listener. */
68
- key?: string;
69
- }
70
-
71
- interface M2NodeEventListener<M2NodeEvent> extends M2EventListener<M2NodeEvent> {
72
- /** For composites that raise events, type of the composite custom event. */
73
- compositeType?: string;
74
- /** UUID of the node that the event listener is listening for. */
75
- nodeUuid: string;
76
- }
77
-
78
- /** Base interface for all M2Node events. */
79
- interface M2NodeEvent extends M2Event<M2Node> {
80
- /** The M2Node on which the event occurred. */
81
- target: M2Node;
82
- /** For composites that raise events, type of the composite custom event. */
83
- compositeType?: string;
84
- }
1
+ import { Canvas, Typeface, TypefaceFontProvider, Image, Paint, CanvasKit, Surface, Font, ParagraphBuilder, Paragraph, FontMgr, Path, PaintStyle } from 'canvaskit-wasm';
85
2
 
86
3
  /**
87
4
  * Position in two-dimensional space.
@@ -93,30 +10,32 @@ interface Point {
93
10
  y: number;
94
11
  }
95
12
 
96
- /**
97
- * Describes an interaction between the pointer (mouse, touches) and a node.
98
- *
99
- * @remarks I would have named it PointerEvent, but that would collide with
100
- * the existing DOM PointerEvent.
101
- */
102
- interface M2PointerEvent extends M2NodeEvent {
103
- /** Point that was tapped on node, relative to the node coordinate system */
104
- point: Point;
105
- /** Buttons being pressed when event was fired. Taken from DOM MouseEvent.buttons */
106
- buttons: number;
13
+ interface IDrawable {
14
+ draw(canvas: Canvas): void;
15
+ warmup(canvas: Canvas): void;
16
+ /**
17
+ * Frees up resources allocated by the Drawable M2Node.
18
+ *
19
+ * @internal For m2c2kit library use only
20
+ *
21
+ * @remarks This will be done automatically by the m2c2kit library; the
22
+ * end-user must not call this.
23
+ */
24
+ dispose(): void;
25
+ anchorPoint: Point;
26
+ zPosition: number;
107
27
  }
108
28
 
109
- /**
110
- * Describes an interaction of a pointer (mouse, touches) pressing a node.
111
- *
112
- * @remarks Unlike M2PointerEvent, TapEvent considers how the pointer, while
113
- * in the down state, moves in relation to the bounds of the node.
114
- */
115
- interface TapEvent extends M2NodeEvent {
116
- /** Point that was tapped on node, relative to the node coordinate system */
117
- point: Point;
118
- /** Buttons being pressed when event was fired. Taken from DOM MouseEvent.buttons */
119
- buttons: number;
29
+ declare enum M2NodeType {
30
+ Node = "Node",
31
+ Scene = "Scene",
32
+ Sprite = "Sprite",
33
+ Label = "Label",
34
+ TextLine = "TextLine",
35
+ Shape = "Shape",
36
+ Composite = "Composite",
37
+ SoundPlayer = "SoundPlayer",
38
+ SoundRecorder = "SoundRecorder"
120
39
  }
121
40
 
122
41
  interface DrawableOptions {
@@ -170,32 +89,6 @@ interface Layout {
170
89
  constraints?: Constraints;
171
90
  }
172
91
 
173
- /**
174
- * Color in red (0-255), green (0-255), blue (0-255), alpha (0-1) format. Must be numeric array of length 4.
175
- */
176
- type RgbaColor = [number, number, number, number];
177
-
178
- interface TextOptions {
179
- /** Text to be displayed */
180
- text?: string;
181
- /** Name of font to use for text. Must have been previously loaded */
182
- fontName?: string;
183
- /** Color of text. Default is Constants.DEFAULT_FONT_COLOR (WebColors.Black) */
184
- fontColor?: RgbaColor;
185
- /** Size of text. Default is Constants.DEFAULT_FONT_SIZE (16) */
186
- fontSize?: number;
187
- }
188
-
189
- /**
190
- * Width and height on two-dimensional space
191
- */
192
- interface Size {
193
- /** Horizontal width, x-axis */
194
- width: number;
195
- /** Vertical height, y-axis */
196
- height: number;
197
- }
198
-
199
92
  interface M2NodeOptions {
200
93
  /** Name of the node. Only needed if the node will be referred to by name in a later function */
201
94
  name?: string;
@@ -215,208 +108,46 @@ interface M2NodeOptions {
215
108
  hidden?: boolean;
216
109
  /** FOR INTERNAL USE ONLY */
217
110
  layout?: Layout;
111
+ /** Unique identifier (UUID). Will be generated automatically. @internal For m2c2kit library use only */
112
+ uuid?: string;
113
+ /** Should the node not emit events to the EventStore? Default is false.
114
+ * @remarks This property is for use by authors of `Composite` nodes. It is not intended for general use. */
115
+ suppressEvents?: boolean;
218
116
  }
219
117
 
220
- declare enum M2NodeType {
221
- Node = "Node",
222
- Scene = "Scene",
223
- Sprite = "Sprite",
224
- Label = "Label",
225
- TextLine = "TextLine",
226
- Shape = "Shape",
227
- Composite = "Composite"
228
- }
229
-
230
- type EasingFunction = (
231
- /** elapsed time since start of action */
232
- t: number,
233
- /** start value of value to be eased */
234
- b: number,
235
- /** total change of value to be eased */
236
- c: number,
237
- /** total duration of action */
238
- d: number) => number;
239
- /**
240
- * The Easings class has static methods for creating easings to be used in actions.
241
- */
242
- declare class Easings {
243
- static none: EasingFunction;
244
- static linear: EasingFunction;
245
- static quadraticIn: EasingFunction;
246
- static quadraticOut: EasingFunction;
247
- static quadraticInOut: EasingFunction;
248
- static cubicIn: EasingFunction;
249
- static cubicOut: EasingFunction;
250
- static cubicInOut: EasingFunction;
251
- static quarticIn: EasingFunction;
252
- static quarticOut: EasingFunction;
253
- static quarticInOut: EasingFunction;
254
- static quinticIn: EasingFunction;
255
- static quinticOut: EasingFunction;
256
- static quinticInOut: EasingFunction;
257
- static sinusoidalIn: EasingFunction;
258
- static sinusoidalOut: EasingFunction;
259
- static sinusoidalInOut: EasingFunction;
260
- static exponentialIn: EasingFunction;
261
- static exponentialOut: EasingFunction;
262
- static exponentialInOut: EasingFunction;
263
- static circularIn: EasingFunction;
264
- static circularOut: EasingFunction;
265
- static circularInOut: EasingFunction;
266
- }
267
-
268
- interface IDrawable {
269
- draw(canvas: Canvas): void;
270
- warmup(canvas: Canvas): void;
271
- /**
272
- * Frees up resources allocated by the Drawable M2Node.
273
- *
274
- * @internal For m2c2kit library use only
275
- *
276
- * @remarks This will be done automatically by the m2c2kit library; the
277
- * end-user must not call this.
278
- */
279
- dispose(): void;
280
- anchorPoint: Point;
281
- zPosition: number;
282
- }
283
-
284
- interface SceneOptions extends M2NodeOptions, DrawableOptions {
285
- /** Background color of the scene. Default is Constants.DEFAULT_SCENE_BACKGROUND_COLOR (WebColors.White) */
286
- backgroundColor?: RgbaColor;
287
- }
288
-
289
- interface CallbackOptions {
290
- /** Should the provided callback replace any existing callbacks of the same event type for this target? Default is false */
291
- replaceExisting?: boolean;
292
- /** String identifier used to identify the callback. Only needed if the callback will be removed later */
293
- key?: string;
118
+ interface CompositeOptions extends M2NodeOptions, DrawableOptions {
294
119
  }
295
120
 
296
- declare class Scene extends M2Node implements IDrawable, SceneOptions {
297
- readonly type = M2NodeType.Scene;
121
+ declare abstract class Composite extends M2Node implements IDrawable {
122
+ readonly type = M2NodeType.Composite;
123
+ compositeType: string;
298
124
  isDrawable: boolean;
299
- anchorPoint: {
300
- x: number;
301
- y: number;
302
- };
303
- zPosition: number;
304
- private _backgroundColor;
305
- _active: boolean;
306
- _transitioning: boolean;
307
- private backgroundPaint?;
125
+ private _anchorPoint;
126
+ private _zPosition;
308
127
  /**
309
- * Top-level node that holds all other nodes, such as sprites, rectangles, or labels, that will be displayed on the screen
310
- *
311
- * @remarks The scene is the game screen or stage, and fills the entire available screen. There are usually multiple screens to contain multiple stages of the game, such as various instruction pages or phases of a game.
312
- *
313
- * @param options - {@link SceneOptions}
314
- */
315
- constructor(options?: SceneOptions);
316
- initialize(): void;
317
- dispose(): void;
318
- set game(game: Game);
319
- /**
320
- * The game which this scene is a part of.
321
- *
322
- * @remarks Throws error if scene is not part of the game object.
323
- */
324
- get game(): Game;
325
- get backgroundColor(): RgbaColor;
326
- set backgroundColor(backgroundColor: RgbaColor);
327
- /**
328
- * Duplicates a node using deep copy.
329
- *
330
- * @remarks This is a deep recursive clone (node and children).
331
- * The uuid property of all duplicated nodes will be newly created,
332
- * because uuid must be unique.
333
- *
334
- * @param newName - optional name of the new, duplicated node. If not
335
- * provided, name will be the new uuid
336
- */
337
- duplicate(newName?: string): Scene;
338
- /**
339
- * Code that will be called every time the scene is presented.
340
- *
341
- * @remarks Use this callback to set nodes to their initial state, if
342
- * that state might be changed later. For example, if a scene allows
343
- * players to place dots on a grid, the setup() method should ensure the
344
- * grid is clear of any prior dots from previous times this scene may
345
- * have been displayed. In addition, if nodes should vary in each
346
- * iteration, that should be done here.
347
- *
348
- * @param callback - function to execute
349
- * @param options - {@link CallbackOptions}
350
- */
351
- onSetup(callback: (nodeEvent: M2NodeEvent) => void, options?: CallbackOptions): void;
352
- /**
353
- *
354
- * Code that will be called after the scene has finished any transitions
355
- * and has fully appeared on the screen.
356
- *
357
- * @param callback - function to execute
358
- * @param options - {@link CallbackOptions}
359
- */
360
- onAppear(callback: (nodeEvent: M2NodeEvent) => void, options?: CallbackOptions): void;
361
- update(): void;
362
- draw(canvas: Canvas): void;
363
- warmup(canvas: Canvas): void;
364
- }
365
-
366
- interface SlideTransitionOptions {
367
- /** Direction in which the slide action goes */
368
- direction: TransitionDirection;
369
- /** Duration, in milliseconds, of the transition */
370
- duration: number;
371
- /** Easing function for movement; default is linear */
372
- easing?: EasingFunction;
373
- }
374
- /**
375
- * The Transition class has static methods for creating animations that run as one scene transitions to another.
376
- */
377
- declare abstract class Transition {
378
- abstract type: TransitionType;
379
- abstract easing: EasingFunction;
380
- abstract duration: number;
381
- /**
382
- * Creates a scene transition in which the outgoing scene slides out and the incoming scene slides in, as if the incoming scene pushes it.
383
- *
384
- * @param options - {@link SlideTransitionOptions}
385
- * @returns
386
- */
387
- static slide(options: SlideTransitionOptions): SlideTransition;
388
- /**
389
- * Creates a scene transition with no animation or duration. The next scene is immediately drawn.
390
- */
391
- static none(): NoneTransition;
392
- }
393
- declare class NoneTransition extends Transition {
394
- type: TransitionType;
395
- easing: EasingFunction;
396
- duration: number;
397
- constructor();
398
- }
399
- declare class SlideTransition extends Transition {
400
- type: TransitionType;
401
- easing: EasingFunction;
402
- duration: number;
403
- direction: TransitionDirection;
404
- constructor(direction: TransitionDirection, duration: number, easing: EasingFunction);
405
- }
406
- declare enum TransitionType {
407
- Slide = "Slide",
408
- None = "None"
409
- }
410
- declare enum TransitionDirection {
411
- Up = "Up",
412
- Down = "Down",
413
- Right = "Right",
414
- Left = "Left"
415
- }
416
- declare class SceneTransition {
417
- scene: Scene;
418
- transition: Transition;
419
- constructor(scene: Scene, transition: Transition);
128
+ * Base Drawable object for creating custom nodes ("composites") composed of primitive nodes.
129
+ *
130
+ * @param options
131
+ */
132
+ constructor(options?: CompositeOptions);
133
+ initialize(): void;
134
+ get anchorPoint(): Point;
135
+ set anchorPoint(anchorPoint: Point);
136
+ get zPosition(): number;
137
+ set zPosition(zPosition: number);
138
+ dispose(): void;
139
+ update(): void;
140
+ draw(canvas: Canvas): void;
141
+ abstract warmup(canvas: Canvas): void;
142
+ /**
143
+ * Event handler for custom events a `Composite` may generate.
144
+ *
145
+ * @remarks If the `Composite` generates custom events, this method is
146
+ * necessary for the `Composite` to work in replay mode.
147
+ *
148
+ * @param event - event to handle
149
+ */
150
+ handleCompositeEvent(event: CompositeEvent): void;
420
151
  }
421
152
 
422
153
  /** Base interface for all Activity events. */
@@ -551,19 +282,26 @@ interface IDataStore {
551
282
  /** Sets the value of an item. The key will be saved to the store as provided;
552
283
  * if namespacing or other formatting is desired, it must be done before
553
284
  * calling this method. activityId can be used by the store for indexing. */
554
- setItem(key: string, value: string | number | boolean | object | undefined | null, activityId: string): Promise<string>;
285
+ setItem(key: string, value: string | number | boolean | object | undefined | null, activityPublishUuid: string): Promise<string>;
555
286
  /** Gets the value of an item by its key. */
556
287
  getItem<T extends string | number | boolean | object | undefined | null>(key: string): Promise<T>;
557
288
  /** Deletes an item by its key. */
558
289
  deleteItem(key: string): Promise<void>;
559
290
  /** Deletes all items. */
560
- clearItemsByActivityId(activityId: string): Promise<void>;
291
+ clearItemsByActivityPublishUuid(activityPublishUuid: string): Promise<void>;
561
292
  /** Returns keys of all items. */
562
- itemsKeysByActivityId(activityId: string): Promise<string[]>;
293
+ itemsKeysByActivityPublishUuid(activityPublishUuid: string): Promise<string[]>;
563
294
  /** Determines if the key exists. */
564
295
  itemExists(key: string): Promise<boolean>;
565
296
  }
566
297
 
298
+ interface CallbackOptions {
299
+ /** Should the provided callback replace any existing callbacks of the same event type for this target? Default is false */
300
+ replaceExisting?: boolean;
301
+ /** String identifier used to identify the callback. Only needed if the callback will be removed later */
302
+ key?: string;
303
+ }
304
+
567
305
  interface Activity {
568
306
  /** The type of activity: Game or Survey */
569
307
  type: ActivityType;
@@ -621,14 +359,20 @@ interface Activity {
621
359
  * @param options - options for the callback.
622
360
  */
623
361
  onData(callback: (activityResultsEvent: ActivityResultsEvent) => void, options?: CallbackOptions): void;
624
- /** The activity's parent session unique identifier. */
362
+ /** The activity's parent session unique identifier. This is newly generated each session. */
625
363
  sessionUuid: string;
626
- /** The activity's unique identifier. NOTE: This is newly generated each session. The uuid for an activity will vary across sessions. */
364
+ /** The activity's unique identifier. This is newly generated each session. The UUID for an activity will vary across sessions. */
627
365
  uuid: string;
628
366
  /** Human-friendly name of this activity */
629
367
  name: string;
630
368
  /** Short identifier of this activity */
631
369
  id: string;
370
+ /** Persistent unique identifier (UUID) of the activity. Required for games. Optional or empty string if a survey. */
371
+ publishUuid: string;
372
+ /** The ID of the study (protocol, experiment, or other aggregate) that contains the repeated administrations of this activity. The ID should be short, url-friendly, human-readable text (no spaces, special characters, or slashes), e.g., `nyc-aging-cohort`. */
373
+ studyId?: string;
374
+ /** Unique identifier (UUID) of the study (protocol, experiment, or other aggregate) that contains the administration of this activity. */
375
+ studyUuid?: string;
632
376
  /** The value of performance.now() immediately before the activity begins */
633
377
  beginTimestamp: number;
634
378
  /** The value of new Date().toISOString() immediately before the activity begins */
@@ -641,6 +385,207 @@ interface Activity {
641
385
  dataStores?: IDataStore[];
642
386
  }
643
387
 
388
+ /** Base interface for all M2Node events. */
389
+ interface M2NodeEvent extends M2Event<M2Node> {
390
+ /** The M2Node on which the event occurred. If the event has gone through serialization, the string will be the node's UUID. */
391
+ target: M2Node | string;
392
+ }
393
+
394
+ /**
395
+ * Color in red (0-255), green (0-255), blue (0-255), alpha (0-1) format. Must be numeric array of length 4.
396
+ */
397
+ type RgbaColor = [number, number, number, number];
398
+
399
+ interface SceneOptions extends M2NodeOptions, DrawableOptions {
400
+ /** Background color of the scene. Default is Constants.DEFAULT_SCENE_BACKGROUND_COLOR (WebColors.White) */
401
+ backgroundColor?: RgbaColor;
402
+ }
403
+
404
+ declare class Scene extends M2Node implements IDrawable, SceneOptions {
405
+ readonly type = M2NodeType.Scene;
406
+ isDrawable: boolean;
407
+ private _anchorPoint;
408
+ private _zPosition;
409
+ private _backgroundColor;
410
+ _active: boolean;
411
+ _transitioning: boolean;
412
+ private backgroundPaint?;
413
+ /**
414
+ * Top-level node that holds all other nodes, such as sprites, rectangles, or labels, that will be displayed on the screen
415
+ *
416
+ * @remarks The scene is the game screen or stage, and fills the entire available screen. There are usually multiple screens to contain multiple stages of the game, such as various instruction pages or phases of a game.
417
+ *
418
+ * @param options - {@link SceneOptions}
419
+ */
420
+ constructor(options?: SceneOptions);
421
+ get completeNodeOptions(): {
422
+ backgroundColor: RgbaColor;
423
+ anchorPoint?: Point;
424
+ zPosition?: number;
425
+ name?: string;
426
+ position?: Point;
427
+ scale?: number;
428
+ alpha?: number;
429
+ zRotation?: number;
430
+ isUserInteractionEnabled?: boolean;
431
+ draggable?: boolean;
432
+ hidden?: boolean;
433
+ layout?: Layout;
434
+ uuid?: string;
435
+ suppressEvents?: boolean;
436
+ };
437
+ initialize(): void;
438
+ dispose(): void;
439
+ set game(game: Game);
440
+ /**
441
+ * The game which this scene is a part of.
442
+ *
443
+ * @remarks Throws error if scene is not part of the game object.
444
+ */
445
+ get game(): Game;
446
+ get backgroundColor(): RgbaColor;
447
+ set backgroundColor(backgroundColor: RgbaColor);
448
+ get anchorPoint(): Point;
449
+ set anchorPoint(anchorPoint: Point);
450
+ get zPosition(): number;
451
+ set zPosition(zPosition: number);
452
+ /**
453
+ * Duplicates a node using deep copy.
454
+ *
455
+ * @remarks This is a deep recursive clone (node and children).
456
+ * The uuid property of all duplicated nodes will be newly created,
457
+ * because uuid must be unique.
458
+ *
459
+ * @param newName - optional name of the new, duplicated node. If not
460
+ * provided, name will be the new uuid
461
+ */
462
+ duplicate(newName?: string): Scene;
463
+ /**
464
+ * Code that will be called every time the scene is presented.
465
+ *
466
+ * @remarks Use this callback to set nodes to their initial state, if
467
+ * that state might be changed later. For example, if a scene allows
468
+ * players to place dots on a grid, the setup() method should ensure the
469
+ * grid is clear of any prior dots from previous times this scene may
470
+ * have been displayed. In addition, if nodes should vary in each
471
+ * iteration, that should be done here.
472
+ *
473
+ * @param callback - function to execute
474
+ * @param options - {@link CallbackOptions}
475
+ */
476
+ onSetup(callback: (nodeEvent: M2NodeEvent) => void, options?: CallbackOptions): void;
477
+ /**
478
+ *
479
+ * Code that will be called after the scene has finished any transitions
480
+ * and has fully appeared on the screen.
481
+ *
482
+ * @param callback - function to execute
483
+ * @param options - {@link CallbackOptions}
484
+ */
485
+ onAppear(callback: (nodeEvent: M2NodeEvent) => void, options?: CallbackOptions): void;
486
+ update(): void;
487
+ draw(canvas: Canvas): void;
488
+ warmup(canvas: Canvas): void;
489
+ }
490
+
491
+ type EasingFunction = (
492
+ /** elapsed time since start of action */
493
+ t: number,
494
+ /** start value of value to be eased */
495
+ b: number,
496
+ /** total change of value to be eased */
497
+ c: number,
498
+ /** total duration of action */
499
+ d: number) => number;
500
+ /**
501
+ * The Easings class has static methods for creating easings to be used in actions.
502
+ */
503
+ declare class Easings {
504
+ static none: EasingFunction;
505
+ static linear: EasingFunction;
506
+ static quadraticIn: EasingFunction;
507
+ static quadraticOut: EasingFunction;
508
+ static quadraticInOut: EasingFunction;
509
+ static cubicIn: EasingFunction;
510
+ static cubicOut: EasingFunction;
511
+ static cubicInOut: EasingFunction;
512
+ static quarticIn: EasingFunction;
513
+ static quarticOut: EasingFunction;
514
+ static quarticInOut: EasingFunction;
515
+ static quinticIn: EasingFunction;
516
+ static quinticOut: EasingFunction;
517
+ static quinticInOut: EasingFunction;
518
+ static sinusoidalIn: EasingFunction;
519
+ static sinusoidalOut: EasingFunction;
520
+ static sinusoidalInOut: EasingFunction;
521
+ static exponentialIn: EasingFunction;
522
+ static exponentialOut: EasingFunction;
523
+ static exponentialInOut: EasingFunction;
524
+ static circularIn: EasingFunction;
525
+ static circularOut: EasingFunction;
526
+ static circularInOut: EasingFunction;
527
+ static toTypeAsString(easingFunction: EasingFunction): string;
528
+ static fromTypeAsString(easingType: string): EasingFunction;
529
+ }
530
+
531
+ interface SlideTransitionOptions {
532
+ /** Direction in which the slide action goes */
533
+ direction: TransitionDirection;
534
+ /** Duration, in milliseconds, of the transition */
535
+ duration: number;
536
+ /** Easing function for movement or a string identifier of the easing function, e.g., `SinusoidalInOut`. Default is a linear easing function. */
537
+ easing?: EasingFunction | string;
538
+ }
539
+ /**
540
+ * The Transition class has static methods for creating animations that run as one scene transitions to another.
541
+ */
542
+ declare abstract class Transition {
543
+ abstract type: TransitionType;
544
+ abstract easing: EasingFunction;
545
+ abstract duration: number;
546
+ /**
547
+ * Creates a scene transition in which the outgoing scene slides out and the incoming scene slides in, as if the incoming scene pushes it.
548
+ *
549
+ * @param options - {@link SlideTransitionOptions}
550
+ * @returns
551
+ */
552
+ static slide(options: SlideTransitionOptions): SlideTransition;
553
+ /**
554
+ * Creates a scene transition with no animation or duration. The next scene is immediately drawn.
555
+ */
556
+ static none(): NoneTransition;
557
+ }
558
+ declare class NoneTransition extends Transition {
559
+ type: "None";
560
+ easing: EasingFunction;
561
+ duration: number;
562
+ constructor();
563
+ }
564
+ declare class SlideTransition extends Transition {
565
+ type: "Slide";
566
+ easing: EasingFunction;
567
+ duration: number;
568
+ direction: TransitionDirection;
569
+ constructor(direction: TransitionDirection, duration: number, easing: EasingFunction);
570
+ }
571
+ declare const TransitionType: {
572
+ readonly Slide: "Slide";
573
+ readonly None: "None";
574
+ };
575
+ type TransitionType = (typeof TransitionType)[keyof typeof TransitionType];
576
+ declare const TransitionDirection: {
577
+ readonly Up: "Up";
578
+ readonly Down: "Down";
579
+ readonly Right: "Right";
580
+ readonly Left: "Left";
581
+ };
582
+ type TransitionDirection = (typeof TransitionDirection)[keyof typeof TransitionDirection];
583
+ declare class SceneTransition {
584
+ scene: Scene;
585
+ transition: Transition;
586
+ constructor(scene: Scene, transition: Transition);
587
+ }
588
+
644
589
  /**
645
590
  * Image that can be rendered by a browser from a URL or from a
646
591
  * HTML svg tag in string form. Provide either url or svgString, not both.
@@ -658,10 +603,16 @@ interface BrowserImage {
658
603
  svgString?: string;
659
604
  /** URL of image asset (svg, png, jpg) to render and load */
660
605
  url?: string;
606
+ /** Image asset as a Data URL. @internal For m2c2kit library use only */
607
+ dataUrl?: string;
661
608
  /** If true, the image will not be fully loaded until it is needed. Default
662
- * is false. Lazy loading is useful for localized images or large "banks"
663
- * of images. These should be lazy loaded because they may not be needed. */
609
+ * is false. Lazy loading is useful for large "banks" of images. These should
610
+ * be lazy loaded because they may not be needed. */
664
611
  lazy?: boolean;
612
+ /** If true, try to use a localized version of the image. Localized images
613
+ * are loaded on demand and are not preloaded. Only an image whose asset
614
+ * is provided as a URL can be localized. Default is false. */
615
+ localize?: boolean;
665
616
  }
666
617
 
667
618
  /**
@@ -690,78 +641,250 @@ interface DefaultParameter extends JsonSchema {
690
641
  }
691
642
 
692
643
  /**
693
- * Translations is a map of a locale to a map of keys to translations.
644
+ * Font url and raw data that has been shared with other games in the session.
645
+ *
646
+ * @remarks Font sharing will happen only if the font filename is the same AND
647
+ * a game's `shareAssets` property is not false.
648
+ */
649
+ interface SharedFont {
650
+ /** url that the shared font was loaded from */
651
+ url: string;
652
+ /** raw data of the shared font */
653
+ data: ArrayBuffer;
654
+ }
655
+
656
+ /**
657
+ * Font asset to use in the game.
658
+ */
659
+ interface FontAsset {
660
+ /** Name of the font to use when referring to it within m2c2kit */
661
+ fontName: string;
662
+ /** URL of font (TrueType font) to load */
663
+ url: string;
664
+ /** If true, the font will not be fully loaded until it is needed. Default
665
+ * is false. Lazy loading is useful for fonts involved in localization.
666
+ * These should be lazy loaded because they may not be needed.
667
+ */
668
+ lazy?: boolean;
669
+ /** Font url and raw data that has been shared with other games in the session. Undefined if this font was not shared. @internal For m2c2kit library use only */
670
+ sharedFont?: SharedFont;
671
+ }
672
+
673
+ /**
674
+ * Game's module name, version, and dependencies.
675
+ */
676
+ interface ModuleMetadata {
677
+ /** name property from package.json */
678
+ name: string;
679
+ /** version property from package.json */
680
+ version: string;
681
+ /** dependency property from package.json */
682
+ dependencies: {
683
+ [key: string]: string;
684
+ };
685
+ }
686
+
687
+ interface SoundAsset {
688
+ /** Name of the sound to use when referring to it within m2c2kit, such as
689
+ * when creating a `SoundPlayer` node. */
690
+ soundName: string;
691
+ /** URL of sound to load */
692
+ url: string;
693
+ /** If true, the sound will not be fully loaded until it is needed. Default
694
+ * is false. Lazy loading is useful for sounds involved in localization.
695
+ * These should be lazy loaded because they may not be needed.
696
+ */
697
+ lazy?: boolean;
698
+ }
699
+
700
+ /**
701
+ * A map of a locale to a map of keys to translated text and font information.
702
+ *
703
+ * @remarks When it comes to fonts, the `Translation` object only specifies
704
+ * which fonts to use for text. The actual fonts must be provided as part of
705
+ * the `GameOptions` object with names that match the names specified in the
706
+ * `Translation` object.
707
+ *
708
+ * The below example defines a translation object for use in three locales:
709
+ * en-US, es-MX, and hi-IN.
710
+ *
711
+ * In the `configuration` object, the `baseLocale` property is en-US. This
712
+ * means that the en-US locale is the locale from which the "native"
713
+ * resources originate.
714
+ *
715
+ * The property `localeName` is human-readable text of the locale that can
716
+ * be displayed to the user. For example, `en-US` might have the locale name
717
+ * `English`. The property `localeSvg` is an image of the locale, as an SVG
718
+ * string and its height and width. This is so the locale can be displayed to
719
+ * the user if the locale uses a script that is not supported in the default
720
+ * font, and a locale-specific font is not yet loaded.
721
+ *
722
+ * For en-US and es-MX, the game's default font will be used for all text
723
+ * because the `fontName` property is not specified for these locales. For
724
+ * hi-IN, the `devanagari` font will be used for all text.
725
+ *
726
+ * `EMOJI_WELCOME` uses an emoji, and it will not display properly unless an
727
+ * `emoji` font is added. The `additionalFontName` property is used to
728
+ * specify an additional font or fonts to use as well as the locale's font.
729
+ * For en-US and es-MX, the `emoji` font plus the game's default font will be
730
+ * used for the `EMOJI_WELCOME` text. For hi-IN, the `emoji` font plus the
731
+ * `devanagari` font will be used for the `EMOJI_WELCOME` text.
732
+ *
733
+ * `OK_BUTTON` uses the game's default font for all locales. Because hi-IN
734
+ * specified a font name, the `overrideFontName` property with a value of
735
+ * `default` is used to specify that the game's default font should be used
736
+ * instead of the locale's font, devanagari.
737
+ *
738
+ * `BYE` uses interpolation. `{{name}}` is a placeholder that will be replaced,
739
+ * at runtime, with the value of the `name` key in the `options` object passed
740
+ * to the `t` or `tf` methods of the `I18n` object. If the placeholder is not
741
+ * found in `options`, an error will be thrown.
694
742
  *
695
743
  * @example
744
+ *
696
745
  * ```
697
- * const translations: Translations = {
746
+ * const translation: Translation = {
747
+ * "configuration": {
748
+ * "baseLocale": "en-US"
749
+ * },
698
750
  * "en-US": {
751
+ * localeName: "English",
699
752
  * "NEXT_BUTTON": "Next"
753
+ * "EMOJI_WELCOME": {
754
+ * text: "👋 Hello",
755
+ * additionalFontName: ["emoji"]
756
+ * },
757
+ * "OK_BUTTON": "OK",
758
+ * "BYE": "Goodbye, {{name}}."
700
759
  * },
701
760
  * "es-MX": {
761
+ * localeName: "Español",
702
762
  * "NEXT_BUTTON": "Siguiente"
763
+ * "EMOJI_WELCOME": {
764
+ * text: "👋 Hola",
765
+ * additionalFontName: ["emoji"]
766
+ * },
767
+ * "OK_BUTTON": "OK",
768
+ * "BYE": "Adiós, {{name}}."
769
+ * },
770
+ * "hi-IN": {
771
+ * localeName: "Hindi",
772
+ * localeSvg: {
773
+ * // from https://commons.wikimedia.org/wiki/File:Hindi.svg, not copyrighted
774
+ * // note: To save space, the next line is not the full, working SVG string from the above URL.
775
+ * svgString: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 304 168" xml:space="preserve"><path d="m45.223..."/></svg>`,
776
+ * height: 44,
777
+ * width: 80,
778
+ * },
779
+ * fontName: "devanagari",
780
+ * "NEXT_BUTTON": "अगला"
781
+ * "EMOJI_WELCOME": {
782
+ * text: "👋 नमस्कार",
783
+ * additionalFontName: ["emoji"]
784
+ * },
785
+ * "OK_BUTTON": {
786
+ * text: "OK",
787
+ * overrideFontName: "default"
788
+ * },
789
+ * "BYE": "अलविदा {{name}}."
703
790
  * }
704
791
  * }
792
+ *
793
+ * ...
794
+ *
795
+ * const nextButton = new Button({
796
+ * text: "NEXT_BUTTON"
797
+ * ...
798
+ * })
799
+ *
800
+ * const byeLabel = new Label({
801
+ * text: "BYE",
802
+ * interpolation: {
803
+ * name: "Alice"
804
+ * }
805
+ * ...
806
+ * }
705
807
  * ```
706
808
  */
707
- interface Translations {
809
+ type Translation = LocaleTranslationMap & {
810
+ configuration?: TranslationConfiguration;
811
+ };
812
+ interface TranslationConfiguration {
813
+ /** The locale from which translations and adaptations are made to adjust to different regions and languages. This is the locale from which the base or unlocalized resources originate. */
814
+ baseLocale: string;
815
+ }
816
+ interface LocaleSvg {
817
+ /** The HTML SVG tag, in string form, that will be rendered and loaded.
818
+ * Must begin with &#60;svg> and end with &#60;/svg> */
819
+ svgString: string;
820
+ /** Height to scale image to */
821
+ height: number;
822
+ /** Width to scale image to */
823
+ width: number;
824
+ }
825
+ type LocaleTranslationMap = {
708
826
  [locale: string]: {
709
- [key: string]: string;
827
+ /** The font name or names to use for all text in the locale. If omitted,
828
+ * the game's default font will be used. */
829
+ fontName?: string | string[];
830
+ /** Human-readable text of the locale that can be displayed to the user. For example, `en-US` might have the locale name `English` */
831
+ localeName?: string;
832
+ /** Image of the locale, as an SVG string, that can be displayed to the user. Some locales, in their native script, might not be supported in the default font. For example, Hindi script cannot be displayed in Roboto font. It would be inefficient to load all the possible extra fonts simply to display the locale to the user. Thus, in lieu of a string, the locale can be displayed to the user as an SVG. Only if that locale is selected, the font supporting that locale will be loaded. */
833
+ localeSvg?: LocaleSvg;
834
+ } & {
835
+ /** The translated text or the translated text with custom font information. Note: `LocaleSvg` is included in the union only to satisfy TypeScript compiler. */
836
+ [key: string]: string | TextWithFontCustomization | LocaleSvg;
710
837
  };
711
- }
712
-
838
+ };
713
839
  /**
714
- * Font url and raw data that has been shared with other games in the session.
715
- *
716
- * @remarks Font sharing will happen only if the font filename is the same AND
717
- * a game's `shareAssets` property is not false.
840
+ * A translated string with custom font information to be applied only to this
841
+ * string.
718
842
  */
719
- interface SharedFont {
720
- /** url that the shared font was loaded from */
721
- url: string;
722
- /** raw data of the shared font */
723
- data: ArrayBuffer;
843
+ interface TextWithFontCustomization {
844
+ /** The translated string. */
845
+ text: string;
846
+ /** Font name(s) to _add to_ the locale's font name(s) when displaying text. */
847
+ additionalFontName?: string | Array<string>;
848
+ /** Font name(s) to use _in place of_ the locale's font name(s) when
849
+ * displaying text. Use `default` to indicate that the game's default font
850
+ * should be used instead of the locale's font names(s) */
851
+ overrideFontName?: string | Array<string>;
724
852
  }
725
-
726
- /**
727
- * Font asset to use in the game.
728
- */
729
- interface FontAsset {
730
- /** Name of the font to use when referring to it within m2c2kit */
731
- fontName: string;
732
- /** URL of font (TrueType font) to load */
733
- url: string;
734
- /** If true, the font will not be fully loaded until it is needed. Default
735
- * is false. Lazy loading is useful for fonts involved in localization.
736
- * These should be lazy loaded because they may not be needed.
737
- */
738
- lazy?: boolean;
739
- /** Font url and raw data that has been shared with other games in the session. Undefined if this font was not shared. @internal For m2c2kit library use only */
740
- sharedFont?: SharedFont;
853
+ interface TextAndFont {
854
+ /** The translated string. */
855
+ text?: string;
856
+ /** Font name to use when displaying the text. */
857
+ fontName?: string;
858
+ /** Font names to use when displaying the text. */
859
+ fontNames?: Array<string>;
741
860
  }
742
861
 
743
862
  /**
744
- * Game's module name, version, and dependencies.
863
+ * Localization information that is passed to the I18n constructor.
745
864
  */
746
- interface ModuleMetadata {
747
- /** name property from package.json */
748
- name: string;
749
- /** version property from package.json */
750
- version: string;
751
- /** dependency property from package.json */
752
- dependencies: {
753
- [key: string]: string;
754
- };
865
+ interface LocalizationOptions {
866
+ /** Locale to use for localization when running the game, or "auto" to request from the environment. */
867
+ locale?: string;
868
+ /** Locale to use if requested locale translation is not available, or if "auto" locale was requested and environment cannot provide a locale. Default is `en-US`.*/
869
+ fallbackLocale?: string;
870
+ /** Font color for strings or outline color for images when a requested locale's translation or image is missing. This is useful in development to call attention to missing localization assets. */
871
+ missingLocalizationColor?: RgbaColor;
872
+ /** Translation for localization. */
873
+ translation?: Translation;
874
+ /** Additional translation for localization. This will typically be provided through `setParameters()` at runtime. This translation be merged into the existing translation and will overwrite any existing translation with the same key-value pairs. Thus, this can be used to modify an existing translation, either in whole or in part. */
875
+ additionalTranslation?: Translation;
755
876
  }
756
877
 
757
878
  /**
758
879
  * Options to specify HTML canvas, set game canvas size, and load game assets.
759
880
  */
760
- interface GameOptions {
881
+ interface GameOptions extends LocalizationOptions {
761
882
  /** Human-friendly name of this game */
762
883
  name: string;
763
- /** Short identifier of this game; unique among published games and url-friendly (no spaces, special characters, or slashes)*/
884
+ /** Short identifier of this game; unique among published games and url-friendly (no spaces, special characters, or slashes). */
764
885
  id: string;
886
+ /** Persistent unique identifier (UUID) of this game; unique among published games. The m2c2kit CLI will generate this property automatically, and you should not change it. If not using the CLI, use a website like https://www.uuidgenerator.net/version4 to generate this value. */
887
+ publishUuid: string;
765
888
  /** Version of this game */
766
889
  version: string;
767
890
  /** Uri (repository, webpage, or other location where full information about the game can be found) */
@@ -786,6 +909,8 @@ interface GameOptions {
786
909
  fonts?: Array<FontAsset>;
787
910
  /** Array of BrowserImage objects to render and load */
788
911
  images?: Array<BrowserImage>;
912
+ /** Array of SoundAsset objects to fetch and decode */
913
+ sounds?: Array<SoundAsset>;
789
914
  /** Show FPS in upper left corner? Default is false */
790
915
  showFps?: boolean;
791
916
  /** Color of the html body, if the game does not fill the screen. Useful for showing scene boundaries. Default is the scene background color */
@@ -796,8 +921,10 @@ interface GameOptions {
796
921
  fpsMetricReportThreshold?: number;
797
922
  /** Advance through time step-by-step, for development and debugging */
798
923
  timeStepping?: boolean;
799
- /** Translations for localization. */
800
- translations?: Translations;
924
+ /** Show controls for replaying and viewing the event store? Default is false */
925
+ showEventStoreControls?: boolean;
926
+ /** Should the game events be saved to the event store? Default is false */
927
+ recordEvents?: boolean;
801
928
  /** Show logs for WebGl activity? */
802
929
  logWebGl?: boolean;
803
930
  /** Should games within a session share wasm and font assets that have identical filenames, in order to reduce bandwidth? Default is true. */
@@ -810,37 +937,6 @@ interface GameData extends ActivityKeyValueData {
810
937
  trials: Array<TrialData>;
811
938
  }
812
939
 
813
- /**
814
- * Localization information that is passed to the I18n constructor.
815
- */
816
- interface LocalizationOptions {
817
- /** Locale to use for localization, or "auto" to request from the environment. */
818
- locale: string;
819
- /** Locale to use if requested locale translation is not available, or if "auto" locale was requested and environment cannot provide a locale. */
820
- fallbackLocale?: string;
821
- /** Font color for strings that are missing translation and use the fallback locale or untranslated string. */
822
- missingTranslationFontColor?: RgbaColor;
823
- /** Translations for localization. */
824
- translations?: Translations;
825
- /** Additional translations for localization provided through game parameters. These will be merged into existing translations. */
826
- additionalTranslations?: Translations;
827
- }
828
-
829
- declare class I18n {
830
- private _translations;
831
- locale: string;
832
- fallbackLocale: string;
833
- private environmentLocale;
834
- options: LocalizationOptions;
835
- static makeLocalizationParameters(): GameParameters;
836
- constructor(options: LocalizationOptions);
837
- t(key: string, useFallback?: boolean): string | undefined;
838
- get translations(): Translations;
839
- set translations(value: Translations);
840
- private getEnvironmentLocale;
841
- private mergeAdditionalTranslations;
842
- }
843
-
844
940
  /**
845
941
  * A Plugin is code that can be registered to run at certain points in the game loop.
846
942
  */
@@ -995,13 +1091,26 @@ declare class FontManager {
995
1091
  * additional properties.
996
1092
  */
997
1093
  interface M2Image {
1094
+ /** Name of the image, as it will be referred to when creating a sprite. */
998
1095
  imageName: string;
1096
+ /** The image in CanvasKit format. */
999
1097
  canvaskitImage: Image | undefined;
1000
1098
  width: number;
1001
1099
  height: number;
1100
+ /** Status of the image: Deferred, Loading, Ready, or Error. */
1002
1101
  status: M2ImageStatus;
1102
+ /** For an image that will be fetched, this is the URL that will be attempted. This may have localization applied. */
1003
1103
  url?: string;
1104
+ /** Is this image a fallback localized image? */
1105
+ isFallback: boolean;
1106
+ /** For an image that will be fetched, the original URL before any localization. */
1107
+ originalUrl?: string;
1108
+ /** For a localized image that will be fetched, additional URLs to try if the URL in `url` fails. */
1109
+ fallbackLocalizationUrls?: Array<string>;
1110
+ /** An image defined by an SVG string. */
1004
1111
  svgString?: string;
1112
+ /** Try to localize the image by fetching a locale-specific image? Default is false. */
1113
+ localize: boolean;
1005
1114
  }
1006
1115
  declare const M2ImageStatus: {
1007
1116
  /** Image was set for lazy loading, and loading has not yet been requested. */
@@ -1026,6 +1135,7 @@ declare class ImageManager {
1026
1135
  private scale?;
1027
1136
  private game;
1028
1137
  private baseUrls;
1138
+ missingLocalizationImagePaint?: Paint;
1029
1139
  constructor(game: Game, baseUrls: GameBaseUrls);
1030
1140
  /**
1031
1141
  * Loads image assets and makes them ready to use during the game initialization.
@@ -1051,6 +1161,25 @@ declare class ImageManager {
1051
1161
  * @returns A promise that completes when all images have loaded
1052
1162
  */
1053
1163
  loadImages(browserImages: Array<BrowserImage>): Promise<void>;
1164
+ private configureImageLocalization;
1165
+ /**
1166
+ * Localizes the image URL by appending the locale to the image URL,
1167
+ * immediately before the file extension.
1168
+ *
1169
+ * @remarks For example, `https://url.com/file.png` in en-US locale
1170
+ * becomes `https://url.com/file.en-US.png`. A URL without an extension
1171
+ * will throw an error.
1172
+ *
1173
+ * @param url - url of the image
1174
+ * @param locale - locale in format of xx-YY, where xx is the language code
1175
+ * and YY is the country code
1176
+ * @returns localized url
1177
+ */
1178
+ private localizeImageUrl;
1179
+ /**
1180
+ * Sets an image to be re-rendered within the current locale.
1181
+ */
1182
+ reinitializeLocalizedImages(): void;
1054
1183
  private checkImageNamesForDuplicates;
1055
1184
  /**
1056
1185
  * Makes ready to the game a m2c2kit image ({@link M2Image}) that was
@@ -1113,6 +1242,142 @@ declare class ImageManager {
1113
1242
  private removeScratchCanvas;
1114
1243
  }
1115
1244
 
1245
+ interface M2Sound {
1246
+ soundName: string;
1247
+ data: ArrayBuffer | undefined;
1248
+ audioBuffer: AudioBuffer | undefined;
1249
+ url: string;
1250
+ status: M2SoundStatus;
1251
+ }
1252
+ declare const M2SoundStatus: {
1253
+ /** Sound was set for lazy loading, and loading has not yet been requested. */
1254
+ readonly Deferred: "Deferred";
1255
+ /** Sound is indicated for fetching, but fetching has not begun. */
1256
+ readonly WillFetch: "WillFetch";
1257
+ /** Sound is being fetched. */
1258
+ readonly Fetching: "Fetching";
1259
+ /** Sound has been fetched. */
1260
+ readonly Fetched: "Fetched";
1261
+ /** Sound is being decoded. */
1262
+ readonly Decoding: "Decoding";
1263
+ /** Sound has fully finished loading and is ready to use. */
1264
+ readonly Ready: "Ready";
1265
+ /** Error occurred in loading. */
1266
+ readonly Error: "Error";
1267
+ };
1268
+ type M2SoundStatus = (typeof M2SoundStatus)[keyof typeof M2SoundStatus];
1269
+
1270
+ /**
1271
+ * Fetches, loads, and provides sounds to the game.
1272
+ *
1273
+ * @internal For m2c2kit library use only
1274
+ */
1275
+ declare class SoundManager {
1276
+ private sounds;
1277
+ private game;
1278
+ private baseUrls;
1279
+ private _audioContext?;
1280
+ constructor(game: Game, baseUrls: GameBaseUrls);
1281
+ get audioContext(): AudioContext;
1282
+ /**
1283
+ * Loads sound assets during the game initialization.
1284
+ *
1285
+ * @internal For m2c2kit library use only
1286
+ *
1287
+ * @remarks Typically, a user won't call this because the m2c2kit
1288
+ * framework will call this automatically. At initialization, sounds can
1289
+ * only be fetched, not decoded because the AudioContext can not yet
1290
+ * be created (it requires a user interaction).
1291
+ *
1292
+ * @param soundAssets - array of SoundAsset objects
1293
+ */
1294
+ initializeSounds(soundAssets: Array<SoundAsset> | undefined): Promise<void>;
1295
+ /**
1296
+ * Loads an array of sound assets and makes them ready for the game.
1297
+ *
1298
+ * @remarks Loading a sound consists of 1) fetching the sound file and 2)
1299
+ * decoding the sound data. The sound is then ready to be played. Step 1
1300
+ * can be done at any time, but step 2 requires an `AudioContext`, which
1301
+ * can only be created after a user interaction. If a play `Action` is
1302
+ * attempted before the sound is ready (either it has not been fetched or
1303
+ * decoded), the play `Action` will log a warning to the console and the
1304
+ * loading process will continue in the background, and the sound will play
1305
+ * when ready. This `loadSounds()` method **does not** have to be awaited.
1306
+ *
1307
+ * @param soundAssets - an array of {@link SoundAsset}
1308
+ * @returns A promise that completes when all sounds have loaded
1309
+ */
1310
+ loadSounds(soundAssets: Array<SoundAsset>): Promise<void>;
1311
+ private fetchSounds;
1312
+ /**
1313
+ * Fetches a m2c2kit sound ({@link M2Sound}) that was previously
1314
+ * initialized with lazy loading.
1315
+ *
1316
+ * @internal For m2c2kit library use only
1317
+ *
1318
+ * @param m2Sound - M2Sound to fetch
1319
+ * @returns A promise that completes when sounds have been fetched
1320
+ */
1321
+ fetchDeferredSound(m2Sound: M2Sound): Promise<void>;
1322
+ /**
1323
+ * Checks if the SoundManager has sounds needing decoding.
1324
+ *
1325
+ * @internal For m2c2kit library use only
1326
+ *
1327
+ * @returns true if there are sounds that have been fetched and are waiting
1328
+ * to be decoded (status is `M2SoundStatus.Fetched`)
1329
+ */
1330
+ hasSoundsToDecode(): boolean;
1331
+ /**
1332
+ * Decodes all fetched sounds from bytes to an `AudioBuffer`.
1333
+ *
1334
+ * @internal For m2c2kit library use only
1335
+ *
1336
+ * @remarks This method will be called after the `AudioContext` has been
1337
+ * created and if there are fetched sounds waiting to be decoded.
1338
+ *
1339
+ * @returns A promise that completes when all fetched sounds have been decoded
1340
+ */
1341
+ decodeFetchedSounds(): Promise<void[]>;
1342
+ /**
1343
+ * Decodes a sound from bytes to an `AudioBuffer`.
1344
+ *
1345
+ * @param sound - sound to decode
1346
+ */
1347
+ private decodeSound;
1348
+ /**
1349
+ * Returns a m2c2kit sound ({@link M2Sound}) that has been entered into the
1350
+ * SoundManager.
1351
+ *
1352
+ * @internal For m2c2kit library use only
1353
+ *
1354
+ * @remarks Typically, a user won't need to call this because sound
1355
+ * initialization and processing is handled by the framework.
1356
+ *
1357
+ * @param soundName - sound's name as defined in the game's sound assets
1358
+ * @returns a m2c2kit sound
1359
+ */
1360
+ getSound(soundName: string): M2Sound;
1361
+ /**
1362
+ * Frees up resources allocated by the SoundManager.
1363
+ *
1364
+ * @internal For m2c2kit library use only
1365
+ *
1366
+ * @remarks This will be done automatically by the m2c2kit library; the
1367
+ * end-user must not call this.
1368
+ */
1369
+ dispose(): void;
1370
+ /**
1371
+ * Gets names of sounds entered in the `SoundManager`.
1372
+ *
1373
+ * @remarks These are sounds that the `SoundManager` is aware of. The sounds
1374
+ * may not be ready to play (may not have been fetched or decoded yet).
1375
+ *
1376
+ * @returns array of sound names
1377
+ */
1378
+ getSoundNames(): Array<string>;
1379
+ }
1380
+
1116
1381
  /** Key value pairs of file URLs and hashed file URLs */
1117
1382
  type Manifest = {
1118
1383
  [originalUrl: string]: string;
@@ -1123,6 +1388,99 @@ interface GameEvent extends M2Event<Activity> {
1123
1388
  target: Game;
1124
1389
  }
1125
1390
 
1391
+ type M2EventTarget = M2Node | Element | ImageManager | I18n;
1392
+
1393
+ /**
1394
+ * Event store mode.
1395
+ */
1396
+ declare const EventStoreMode: {
1397
+ readonly Disabled: "Disabled";
1398
+ readonly Record: "Record";
1399
+ readonly Replay: "Replay";
1400
+ };
1401
+ type EventStoreMode = (typeof EventStoreMode)[keyof typeof EventStoreMode];
1402
+ declare class EventStore {
1403
+ private events;
1404
+ private replayBeginTimestamp;
1405
+ private firstTimestamp;
1406
+ replayThoughSequence: number;
1407
+ serializedEventsBeforeReplay: string;
1408
+ mode: EventStoreMode;
1409
+ private serializeEvent;
1410
+ addEvent(event: M2Event<M2EventTarget>): void;
1411
+ addEvents(events: Array<M2Event<M2EventTarget>>): void;
1412
+ clearEvents(): void;
1413
+ record(): void;
1414
+ replay(events?: M2Event<M2EventTarget>[]): void;
1415
+ getEvents(): M2Event<M2EventTarget>[];
1416
+ dequeueEvents(timestamp: number): M2Event<M2EventTarget>[];
1417
+ get eventQueueLength(): number;
1418
+ /**
1419
+ * Sorts the events in the event store.
1420
+ *
1421
+ * @remarks The events are sorted by sequence number in ascending order.
1422
+ */
1423
+ private sortEventStore;
1424
+ }
1425
+
1426
+ declare class M2NodeFactory {
1427
+ /**
1428
+ * The `M2NodeFactory` creates nodes of the specified type with the specified
1429
+ * options for event replay.
1430
+ */
1431
+ constructor();
1432
+ /**
1433
+ * Creates a new node of the specified type with the specified options.
1434
+ *
1435
+ * @param type - The type of node to create
1436
+ * @param compositeType - The composite type of the node to create
1437
+ * @param options - The options to use when creating the node
1438
+ * @returns created node
1439
+ */
1440
+ createNode(type: string, compositeType: string | undefined, options: M2NodeOptions): M2Node;
1441
+ private hasClassRegistration;
1442
+ }
1443
+
1444
+ interface EventMaterializerOptions {
1445
+ game: Game;
1446
+ nodeFactory: M2NodeFactory;
1447
+ freeNodesScene: Scene;
1448
+ configureI18n(localizationOptions: LocalizationOptions): Promise<void>;
1449
+ }
1450
+ declare class EventMaterializer {
1451
+ private game;
1452
+ private nodeFactory;
1453
+ private freeNodesScene;
1454
+ private eventMaterializers;
1455
+ private configureI18n;
1456
+ /**
1457
+ * The `EventMaterializer` class is responsible for taking serialized events
1458
+ * from an event store and replaying them in the game.
1459
+ */
1460
+ constructor(options: EventMaterializerOptions);
1461
+ /**
1462
+ * Deserialize the events by materializing them into the game.
1463
+ *
1464
+ * @remarks This method is called when the game is replaying events from the
1465
+ * event store. Materializing an event means to take the event and apply its
1466
+ * changes to the game. For example, a `NodeNew` event will create a new node
1467
+ * in the game. A `NodePropertyChange` event will change a property of a node
1468
+ * in the game.
1469
+ *
1470
+ * @param events - The events to materialize
1471
+ */
1472
+ materialize(events: ReadonlyArray<M2Event<M2EventTarget>>): void;
1473
+ private materializeCompositeEvent;
1474
+ private materializeNodeNewEvent;
1475
+ private materializeNodePropertyChangeEvent;
1476
+ private materializeNodeAddChildEvent;
1477
+ private materializeNodeRemoveChildEvent;
1478
+ private materializeDomPointerDownEvent;
1479
+ private materializeBrowserImageDataReadyEvent;
1480
+ private materializeI18nDataReadyEvent;
1481
+ private materializeScenePresentEvent;
1482
+ }
1483
+
1126
1484
  interface TrialData {
1127
1485
  [key: string]: string | number | boolean | object | undefined | null;
1128
1486
  }
@@ -1133,6 +1491,9 @@ declare class Game implements Activity {
1133
1491
  uuid: string;
1134
1492
  name: string;
1135
1493
  id: string;
1494
+ publishUuid: string;
1495
+ studyId?: string;
1496
+ studyUuid?: string;
1136
1497
  moduleMetadata: ModuleMetadata;
1137
1498
  readonly canvasKitWasmVersion = "__CANVASKITWASM_VERSION__";
1138
1499
  options: GameOptions;
@@ -1155,13 +1516,20 @@ declare class Game implements Activity {
1155
1516
  };
1156
1517
  private _fontManager?;
1157
1518
  private _imageManager?;
1519
+ private _soundManager?;
1158
1520
  manifest?: Manifest;
1521
+ eventStore: EventStore;
1522
+ private nodeFactory;
1523
+ private _eventMaterializer?;
1524
+ /** Nodes created during event replay */
1525
+ materializedNodes: M2Node[];
1159
1526
  /**
1160
1527
  * The base class for all games. New games should extend this class.
1161
1528
  *
1162
1529
  * @param options - {@link GameOptions}
1163
1530
  */
1164
1531
  constructor(options: GameOptions);
1532
+ private createFreeNodesScene;
1165
1533
  private getImportedModuleBaseUrl;
1166
1534
  private addLocalizationParametersToGameParameters;
1167
1535
  init(): Promise<void>;
@@ -1187,6 +1555,7 @@ declare class Game implements Activity {
1187
1555
  * @returns base URLs for game assets and CanvasKit wasm binary
1188
1556
  */
1189
1557
  resolveGameBaseUrls(game: Game): Promise<GameBaseUrls>;
1558
+ private configureI18n;
1190
1559
  initialize(): Promise<void>;
1191
1560
  /**
1192
1561
  * Returns the manifest, if manifest.json was created during the build.
@@ -1205,6 +1574,24 @@ declare class Game implements Activity {
1205
1574
  set fontManager(fontManager: FontManager);
1206
1575
  get imageManager(): ImageManager;
1207
1576
  set imageManager(imageManager: ImageManager);
1577
+ get soundManager(): SoundManager;
1578
+ set soundManager(soundManager: SoundManager);
1579
+ get eventMaterializer(): EventMaterializer;
1580
+ set eventMaterializer(eventMaterializer: EventMaterializer);
1581
+ /**
1582
+ * Adds prefixes to a key to ensure that keys are unique across activities
1583
+ * and studies.
1584
+ *
1585
+ * @remarks When a value is saved to the key-value data store, the key must
1586
+ * be prefixed with additional information to ensure that keys are unique.
1587
+ * The prefixes will include the activity id and publish UUID, and possibly
1588
+ * the study id and study UUID, if they are set (this is so that keys are
1589
+ * unique across different studies that might use the same activity).
1590
+ *
1591
+ * @param key - item key to add prefixes to
1592
+ * @returns the item key with prefixes added
1593
+ */
1594
+ private addPrefixesToKey;
1208
1595
  /**
1209
1596
  * Saves an item to the activity's key-value store.
1210
1597
  *
@@ -1308,6 +1695,7 @@ declare class Game implements Activity {
1308
1695
  storeItemExists(key: string, globalStore?: boolean): Promise<boolean>;
1309
1696
  get dataStores(): IDataStore[];
1310
1697
  set dataStores(dataStores: IDataStore[]);
1698
+ hasDataStores(): boolean;
1311
1699
  private getLocalizationOptionsFromGameParameters;
1312
1700
  private isLocalizationRequested;
1313
1701
  setParameters(additionalParameters: unknown): void;
@@ -1322,7 +1710,7 @@ declare class Game implements Activity {
1322
1710
  surface?: Surface;
1323
1711
  private showFps?;
1324
1712
  private bodyBackgroundColor?;
1325
- private currentScene?;
1713
+ currentScene?: Scene;
1326
1714
  private priorUpdateTime?;
1327
1715
  private fpsTextFont?;
1328
1716
  private fpsTextPaint?;
@@ -1337,7 +1725,7 @@ declare class Game implements Activity {
1337
1725
  canvasCssWidth: number;
1338
1726
  canvasCssHeight: number;
1339
1727
  scenes: Scene[];
1340
- private freeNodesScene;
1728
+ freeNodesScene: Scene;
1341
1729
  private incomingSceneTransitions;
1342
1730
  private currentSceneSnapshot?;
1343
1731
  private pendingScreenshot?;
@@ -1399,6 +1787,19 @@ declare class Game implements Activity {
1399
1787
  * @param scene
1400
1788
  */
1401
1789
  addScene(scene: Scene): void;
1790
+ /**
1791
+ * Adds events from a node and its children to the game's event store.
1792
+ *
1793
+ * @remarks This method is first called when a scene is added to the game.
1794
+ * If the scene or any of its descendants was constructed or had its
1795
+ * properties changed before it was added to the game, these events were
1796
+ * stored within the node (because the game event store was not yet
1797
+ * available). This method retrieves these events from the node and adds
1798
+ * them to the game's event store.
1799
+ *
1800
+ * @param node - node that contains events to add
1801
+ */
1802
+ private addNodeEvents;
1402
1803
  /**
1403
1804
  * Adds multiple scenes to the game.
1404
1805
  *
@@ -1414,10 +1815,10 @@ declare class Game implements Activity {
1414
1815
  /**
1415
1816
  * Specifies the scene that will be presented upon the next frame draw.
1416
1817
  *
1417
- * @param scene
1818
+ * @param scene - the scene, its string name, or UUID
1418
1819
  * @param transition
1419
1820
  */
1420
- presentScene(scene: string | Scene, transition?: NoneTransition): void;
1821
+ presentScene(scene: string | Scene, transition?: Transition): void;
1421
1822
  /**
1422
1823
  * Gets the value of the game parameter. If parameterName
1423
1824
  * is not found, then throw exception.
@@ -1456,6 +1857,11 @@ declare class Game implements Activity {
1456
1857
  * @param entryScene - The scene (Scene object or its string name) to display when the game starts
1457
1858
  */
1458
1859
  start(entryScene?: Scene | string): Promise<void>;
1860
+ playEventsHandler(mouseEvent: MouseEvent): void;
1861
+ private replayEventsButtonEnabled;
1862
+ private setReplayEventsButtonEnabled;
1863
+ private setStopReplayButtonEnabled;
1864
+ private addEventControlsToDom;
1459
1865
  private addTimeSteppingControlsToDom;
1460
1866
  private updateTimeSteppingOutput;
1461
1867
  private advanceStepsHandler;
@@ -1627,7 +2033,23 @@ declare class Game implements Activity {
1627
2033
  * @param plugin - Plugin to register
1628
2034
  */
1629
2035
  registerPlugin(plugin: Plugin): Promise<void>;
2036
+ /**
2037
+ * Updates active scenes and executes plugins.
2038
+ *
2039
+ */
1630
2040
  private update;
2041
+ /**
2042
+ * Updates all active scenes and their children.
2043
+ */
2044
+ private updateScenes;
2045
+ /**
2046
+ * Executes all active plugins before scenes are updated.
2047
+ */
2048
+ private executeBeforeUpdatePlugins;
2049
+ /**
2050
+ * Executes all active plugins after scenes have been updated.
2051
+ */
2052
+ private executeAfterUpdatePlugins;
1631
2053
  private draw;
1632
2054
  private calculateFps;
1633
2055
  private takeCurrentSceneSnapshot;
@@ -1765,6 +2187,326 @@ declare class Game implements Activity {
1765
2187
  private IsCanvasPointWithinNodeBounds;
1766
2188
  }
1767
2189
 
2190
+ /**
2191
+ * Map of placeholders to values for use in string interpolation.
2192
+ */
2193
+ interface StringInterpolationMap {
2194
+ [placeholder: string]: string;
2195
+ }
2196
+
2197
+ interface TranslationOptions {
2198
+ [key: string]: unknown;
2199
+ }
2200
+ interface TextLocalizationResult {
2201
+ text: string;
2202
+ fontName?: string;
2203
+ fontNames?: string[];
2204
+ isFallbackOrMissingTranslation: boolean;
2205
+ }
2206
+ declare class I18n {
2207
+ private _translation;
2208
+ locale: string;
2209
+ fallbackLocale: string;
2210
+ baseLocale: string;
2211
+ missingLocalizationColor: RgbaColor | undefined;
2212
+ game: Game;
2213
+ /**
2214
+ * The I18n class localizes text and images.
2215
+ *
2216
+ * @param game - game instance
2217
+ * @param options - {@link LocalizationOptions}
2218
+ */
2219
+ constructor(game: Game, options: LocalizationOptions);
2220
+ /**
2221
+ * Initializes the I18n instance and sets the initial locale.
2222
+ *
2223
+ * @remarks If the game instance has been configured to use a data store,
2224
+ * the previously used locale and fallback locale will be retrieved from the
2225
+ * data store if they have been previously set.
2226
+ */
2227
+ initialize(): Promise<void>;
2228
+ private configureInitialLocale;
2229
+ private localeTranslationAvailable;
2230
+ switchToLocale(locale: string): void;
2231
+ /**
2232
+ *
2233
+ * @param key - Translation key
2234
+ * @param interpolation - Interpolation keys and values to replace
2235
+ * placeholders in the translated text
2236
+ * @returns a `TextLocalizationResult` object with the localized text, font
2237
+ * information, and whether the translation is a fallback.
2238
+ */
2239
+ getTextLocalization(key: string, interpolation?: StringInterpolationMap): TextLocalizationResult;
2240
+ /**
2241
+ * Returns the translation text for the given key in the current locale.
2242
+ *
2243
+ * @remarks Optional interpolation keys and values can be provided to replace
2244
+ * placeholders in the translated text. Placeholders are denoted by double
2245
+ * curly braces.
2246
+ *
2247
+ * @param key - key to look up in the translation
2248
+ * @param options - `TranslationOptions`, such as interpolation keys/values
2249
+ * and whether to translate using the fallback locale
2250
+ * @returns the translation text for the key in the current locale, or
2251
+ * undefined if the key is not found
2252
+ *
2253
+ * @example
2254
+ *
2255
+ * ```
2256
+ * const translation: Translation = {
2257
+ * "en-US": {
2258
+ * "GREETING": "Hello, {{name}}."
2259
+ * }
2260
+ * }
2261
+ * ...
2262
+ * i18n.t("GREETING", { name: "World" }); // returns "Hello, World."
2263
+ *
2264
+ * ```
2265
+ */
2266
+ t(key: string, options?: TranslationOptions): string | undefined;
2267
+ /**
2268
+ * Returns the translation text and font information for the given key in the
2269
+ * current locale.
2270
+ *
2271
+ * @remarks Optional interpolation keys and values can be provided to replace
2272
+ * placeholders in the translated text. Placeholders are denoted by double
2273
+ * curly braces. See method {@link I18n.t()} for interpolation example.
2274
+ *
2275
+ * @param key - key to look up in the translation
2276
+ * @param options - `TranslationOptions`, such as interpolation keys/values
2277
+ * and whether to translate using the fallback locale
2278
+ * @returns the translation text and font information for the key in the
2279
+ * current locale, or undefined if the key is not found
2280
+ */
2281
+ tf(key: string, options?: TranslationOptions): TextAndFont | undefined;
2282
+ private getKeyText;
2283
+ private getKeyTextAndFont;
2284
+ private insertInterpolations;
2285
+ get translation(): Translation;
2286
+ set translation(value: Translation);
2287
+ private getEnvironmentLocale;
2288
+ private mergeAdditionalTranslation;
2289
+ static makeLocalizationParameters(): GameParameters;
2290
+ private isTextWithFontCustomization;
2291
+ private isStringOrTextWithFontCustomization;
2292
+ private isStringArray;
2293
+ private isString;
2294
+ }
2295
+
2296
+ /**
2297
+ * Base interface for all m2c2kit events.
2298
+ *
2299
+ * @remarks I would have named it Event, but that would collide with
2300
+ * the existing DOM Event
2301
+ */
2302
+ interface M2Event<T> {
2303
+ /** Type of event. */
2304
+ type: M2EventType | string;
2305
+ /** The object on which the event occurred. If the event has gone through serialization, the string will be the object's UUID (if an `M2Node`) or class name. */
2306
+ target: T | string;
2307
+ /** Has the event been taken care of by the listener and not be dispatched to other targets? */
2308
+ handled?: boolean;
2309
+ /** Timestamp of the event, `from performance.now()` */
2310
+ timestamp: number;
2311
+ /** Timestamp of th event, from `new Date().toISOString()` */
2312
+ iso8601Timestamp: string;
2313
+ /** Sequence number of event.
2314
+ * @remarks Sequence number is guaranteed to reflect order of events, but
2315
+ * not necessarily contiguous, e.g., could be 1, 2, 5, 10, 11, 24.
2316
+ * */
2317
+ sequence?: number;
2318
+ }
2319
+ interface DomPointerDownEvent extends M2Event<Element> {
2320
+ type: "DomPointerDown";
2321
+ target: Element;
2322
+ x: number;
2323
+ y: number;
2324
+ }
2325
+ interface CompositeEvent extends M2NodeEvent {
2326
+ /** The Composite on which the event occurred. If the event has gone through serialization, the string will be the composite's UUID. */
2327
+ target: Composite | string;
2328
+ type: "Composite";
2329
+ /** The type of the composite node. */
2330
+ compositeType: string;
2331
+ /** The type of the composite event. */
2332
+ compositeEventType: string;
2333
+ /** The composite event properties */
2334
+ [key: string]: number | string | boolean | object | null | undefined;
2335
+ }
2336
+ interface M2NodeNewEvent extends M2Event<M2Node> {
2337
+ type: "NodeNew";
2338
+ target: M2Node;
2339
+ /** The type of the new node. */
2340
+ nodeType: M2NodeType | string;
2341
+ /** If a composite node, the type of the composite. */
2342
+ compositeType?: string;
2343
+ /** The options of the at the time of instantiation. This includes options for any base types and interfaces. */
2344
+ nodeOptions: M2NodeOptions;
2345
+ }
2346
+ interface M2NodeAddChildEvent extends M2Event<M2Node> {
2347
+ type: "NodeAddChild";
2348
+ target: M2Node;
2349
+ /** The node's unique identifier (UUID). */
2350
+ uuid: string;
2351
+ /** The child node's unique identifier (UUID). */
2352
+ childUuid: string;
2353
+ }
2354
+ interface M2NodeRemoveChildEvent extends M2Event<M2Node> {
2355
+ type: "NodeRemoveChild";
2356
+ target: M2Node;
2357
+ /** The node's unique identifier (UUID). */
2358
+ uuid: string;
2359
+ /** The child node's unique identifier (UUID). */
2360
+ childUuid: string;
2361
+ }
2362
+ interface ScenePresentEvent extends M2Event<M2Node> {
2363
+ type: "ScenePresent";
2364
+ target: Scene;
2365
+ /** The node's unique identifier (UUID). */
2366
+ uuid: string;
2367
+ /** Transition type of the presented scene. */
2368
+ transitionType: TransitionType;
2369
+ direction?: TransitionDirection;
2370
+ duration?: number;
2371
+ easingType?: string;
2372
+ }
2373
+ interface M2NodePropertyChangeEvent extends M2Event<M2Node> {
2374
+ type: "NodePropertyChange";
2375
+ target: M2Node;
2376
+ /** The node's unique identifier (UUID). */
2377
+ uuid: string;
2378
+ /** The property that changed. */
2379
+ property: string;
2380
+ /** The new value of the property. */
2381
+ value: string | number | boolean | object | null | undefined;
2382
+ }
2383
+ interface BrowserImageDataReadyEvent extends M2Event<ImageManager> {
2384
+ type: "BrowserImageDataReady";
2385
+ target: ImageManager;
2386
+ /** The image name. */
2387
+ imageName: string;
2388
+ /** Width to scale image to */
2389
+ width: number;
2390
+ /** Height to scale image to */
2391
+ height: number;
2392
+ /** The image data URL. */
2393
+ dataUrl?: string;
2394
+ /** SVG string */
2395
+ svgString?: string;
2396
+ }
2397
+ interface I18nDataReadyEvent extends M2Event<I18n> {
2398
+ type: "I18nDataReadyEvent";
2399
+ target: I18n;
2400
+ localizationOptions: LocalizationOptions;
2401
+ }
2402
+ /**
2403
+ * The different events that are dispatched by m2c2kit core.
2404
+ */
2405
+ declare const M2EventType: {
2406
+ readonly ActivityStart: "ActivityStart";
2407
+ readonly ActivityEnd: "ActivityEnd";
2408
+ readonly ActivityCancel: "ActivityCancel";
2409
+ readonly ActivityData: "ActivityData";
2410
+ readonly GameWarmupStart: "GameWarmupStart";
2411
+ readonly GameWarmupEnd: "GameWarmupEnd";
2412
+ readonly TapDown: "TapDown";
2413
+ readonly TapUp: "TapUp";
2414
+ readonly TapUpAny: "TapUpAny";
2415
+ readonly TapLeave: "TapLeave";
2416
+ readonly PointerDown: "PointerDown";
2417
+ readonly PointerUp: "PointerUp";
2418
+ readonly PointerMove: "PointerMove";
2419
+ readonly PointerLeave: "PointerLeave";
2420
+ readonly Drag: "Drag";
2421
+ readonly DragStart: "DragStart";
2422
+ readonly DragEnd: "DragEnd";
2423
+ readonly Composite: "Composite";
2424
+ readonly FrameDidSimulatePhysics: "FrameDidSimulatePhysics";
2425
+ readonly SceneSetup: "SceneSetup";
2426
+ readonly SceneAppear: "SceneAppear";
2427
+ readonly ScenePresent: "ScenePresent";
2428
+ readonly NodeNew: "NodeNew";
2429
+ readonly NodeAddChild: "NodeAddChild";
2430
+ readonly NodeRemoveChild: "NodeRemoveChild";
2431
+ readonly NodePropertyChange: "NodePropertyChange";
2432
+ readonly DomPointerDown: "DomPointerDown";
2433
+ readonly BrowserImageDataReady: "BrowserImageDataReady";
2434
+ readonly I18nDataReadyEvent: "I18nDataReadyEvent";
2435
+ };
2436
+ type M2EventType = (typeof M2EventType)[keyof typeof M2EventType];
2437
+
2438
+ /**
2439
+ * Base interface for all m2c2kit event listeners.
2440
+ */
2441
+ interface M2EventListener<T> {
2442
+ /** Type of event to listen for. */
2443
+ type: M2EventType | string;
2444
+ /** Callback function to be called when the event is dispatched. */
2445
+ callback: (event: T) => void;
2446
+ /** Optional key (string identifier) used to identify the event listener. */
2447
+ key?: string;
2448
+ }
2449
+
2450
+ interface M2NodeEventListener<M2NodeEvent> extends M2EventListener<M2NodeEvent> {
2451
+ /** For composites that raise events, type of the composite node. */
2452
+ compositeType?: string;
2453
+ /** For composites that raise events, type of the composite event. */
2454
+ compositeEventType?: string;
2455
+ /** UUID of the node that the event listener is listening for. */
2456
+ nodeUuid: string;
2457
+ }
2458
+
2459
+ /**
2460
+ * Describes an interaction between the pointer (mouse, touches) and a node.
2461
+ *
2462
+ * @remarks I would have named it PointerEvent, but that would collide with
2463
+ * the existing DOM PointerEvent.
2464
+ */
2465
+ interface M2PointerEvent extends M2NodeEvent {
2466
+ /** Point that was tapped on node, relative to the node coordinate system */
2467
+ point: Point;
2468
+ /** Buttons being pressed when event was fired. Taken from DOM MouseEvent.buttons */
2469
+ buttons: number;
2470
+ }
2471
+
2472
+ /**
2473
+ * Describes an interaction of a pointer (mouse, touches) pressing a node.
2474
+ *
2475
+ * @remarks Unlike M2PointerEvent, TapEvent considers how the pointer, while
2476
+ * in the down state, moves in relation to the bounds of the node.
2477
+ */
2478
+ interface TapEvent extends M2NodeEvent {
2479
+ /** Point that was tapped on node, relative to the node coordinate system */
2480
+ point: Point;
2481
+ /** Buttons being pressed when event was fired. Taken from DOM MouseEvent.buttons */
2482
+ buttons: number;
2483
+ }
2484
+
2485
+ interface TextOptions {
2486
+ /** Text to be displayed */
2487
+ text?: string;
2488
+ /** Name of font to use for text. Must have been previously loaded */
2489
+ fontName?: string;
2490
+ /** Color of text. Default is Constants.DEFAULT_FONT_COLOR (WebColors.Black) */
2491
+ fontColor?: RgbaColor;
2492
+ /** Size of text. Default is Constants.DEFAULT_FONT_SIZE (16) */
2493
+ fontSize?: number;
2494
+ /** Map of placeholders to values for use in string interpolation during localization. */
2495
+ interpolation?: StringInterpolationMap;
2496
+ /** If true, try to use a localized version of the text. Default is true. */
2497
+ localize?: boolean;
2498
+ }
2499
+
2500
+ /**
2501
+ * Width and height on two-dimensional space
2502
+ */
2503
+ interface Size {
2504
+ /** Horizontal width, x-axis */
2505
+ width: number;
2506
+ /** Vertical height, y-axis */
2507
+ height: number;
2508
+ }
2509
+
1768
2510
  /**
1769
2511
  * Describes a drag and drop operation.
1770
2512
  *
@@ -1784,31 +2526,36 @@ declare abstract class M2Node implements M2NodeOptions {
1784
2526
  isDrawable: boolean;
1785
2527
  isShape: boolean;
1786
2528
  isText: boolean;
2529
+ private _suppressEvents;
2530
+ options: M2NodeOptions;
2531
+ constructionTimeStamp: number;
2532
+ constructionIso8601TimeStamp: string;
2533
+ constructionSequence: number;
1787
2534
  name: string;
1788
2535
  _position: Point;
1789
2536
  _scale: number;
1790
- alpha: number;
2537
+ _alpha: number;
1791
2538
  _zRotation: number;
1792
- isUserInteractionEnabled: boolean;
1793
- draggable: boolean;
1794
- hidden: boolean;
2539
+ protected _isUserInteractionEnabled: boolean;
2540
+ protected _draggable: boolean;
2541
+ protected _hidden: boolean;
1795
2542
  layout: Layout;
1796
2543
  _game?: Game;
1797
2544
  parent?: M2Node;
1798
2545
  children: M2Node[];
1799
2546
  absolutePosition: Point;
1800
- size: Size;
2547
+ protected _size: Size;
1801
2548
  absoluteScale: number;
1802
2549
  absoluteAlpha: number;
1803
2550
  absoluteAlphaChange: number;
1804
2551
  actions: Action[];
1805
2552
  queuedAction?: Action;
1806
- originalActions: Action[];
1807
2553
  eventListeners: M2NodeEventListener<M2NodeEvent>[];
1808
2554
  readonly uuid: string;
1809
2555
  needsInitialization: boolean;
1810
2556
  userData: any;
1811
2557
  loopMessages: Set<string>;
2558
+ nodeEvents: M2Event<M2Node>[];
1812
2559
  /** Is the node in a pressed state? E.g., did the user put the pointer
1813
2560
  * down on the node and not yet release it? */
1814
2561
  pressed: boolean;
@@ -1829,6 +2576,28 @@ declare abstract class M2Node implements M2NodeOptions {
1829
2576
  dragging: boolean;
1830
2577
  constructor(options?: M2NodeOptions);
1831
2578
  initialize(): void;
2579
+ protected get completeNodeOptions(): M2NodeOptions;
2580
+ /**
2581
+ * Save the node's construction event in the event store.
2582
+ */
2583
+ protected saveNodeNewEvent(): void;
2584
+ /**
2585
+ * Saves the node's property change event in the event store.
2586
+ *
2587
+ * @param property - property name
2588
+ * @param value - property value
2589
+ */
2590
+ protected savePropertyChangeEvent(property: string, value: string | number | boolean | object | null | undefined): void;
2591
+ /**
2592
+ * Saves the node's event.
2593
+ *
2594
+ * @remarks If the game event store is not available, the event is saved
2595
+ * within the node's `nodeEvents` event array. It will be added to the game
2596
+ * event store when the node is added to the game.
2597
+ *
2598
+ * @param event - event to save
2599
+ */
2600
+ protected saveEvent(event: M2Event<M2Node>): void;
1832
2601
  /**
1833
2602
  * The game which this node is a part of.
1834
2603
  *
@@ -1855,6 +2624,15 @@ declare abstract class M2Node implements M2NodeOptions {
1855
2624
  * @param child - The child node to add
1856
2625
  */
1857
2626
  addChild(child: M2Node): void;
2627
+ /**
2628
+ * Saves the child's events to the parent node.
2629
+ *
2630
+ * @remarks When a child is added to a parent, the parent receives all the
2631
+ * child's events and saves them.
2632
+ *
2633
+ * @param child - child node to save events to parent node
2634
+ */
2635
+ private saveChildEvents;
1858
2636
  /**
1859
2637
  * Removes all children from the node.
1860
2638
  */
@@ -2086,12 +2864,24 @@ declare abstract class M2Node implements M2NodeOptions {
2086
2864
  */
2087
2865
  get canvasKit(): CanvasKit;
2088
2866
  get parentSceneAsNode(): M2Node;
2867
+ get size(): Size;
2868
+ set size(size: Size);
2089
2869
  get position(): Point;
2090
2870
  set position(position: Point);
2091
2871
  get zRotation(): number;
2092
2872
  set zRotation(zRotation: number);
2093
2873
  get scale(): number;
2094
2874
  set scale(scale: number);
2875
+ get alpha(): number;
2876
+ set alpha(alpha: number);
2877
+ get isUserInteractionEnabled(): boolean;
2878
+ set isUserInteractionEnabled(isUserInteractionEnabled: boolean);
2879
+ get hidden(): boolean;
2880
+ set hidden(hidden: boolean);
2881
+ get draggable(): boolean;
2882
+ set draggable(draggable: boolean);
2883
+ get suppressEvents(): boolean;
2884
+ set suppressEvents(value: boolean);
2095
2885
  /**
2096
2886
  * For a given directed acyclic graph, topological ordering of the vertices will be identified using BFS
2097
2887
  * @param adjList Adjacency List that represent a graph with vertices and edges
@@ -2155,8 +2945,27 @@ interface RotateActionOptions {
2155
2945
  runDuringTransition?: boolean;
2156
2946
  }
2157
2947
 
2158
- interface IActionContainer {
2159
- children?: Array<Action>;
2948
+ interface PlayActionOptions {
2949
+ /** Should the action run during screen transitions? Default is no */
2950
+ runDuringTransition?: boolean;
2951
+ }
2952
+
2953
+ /**
2954
+ * An ActionContainer is an Action that can contain other actions.
2955
+ *
2956
+ * @remarks An ActionContainer is a parent action that can have other
2957
+ * actions as children. The `Sequence`, `Group`, `Repeat,` and
2958
+ * `RepeatForever` actions implement `ActionContainer`.
2959
+ */
2960
+ interface ActionContainer extends Action {
2961
+ /**
2962
+ * Immediate children of a parent action.
2963
+ */
2964
+ children: Array<Action>;
2965
+ /**
2966
+ * All children of a parent action and those children's children, recursively.
2967
+ */
2968
+ descendants: Array<Action>;
2160
2969
  }
2161
2970
 
2162
2971
  /** The type of action */
@@ -2168,7 +2977,140 @@ declare enum ActionType {
2168
2977
  Move = "Move",
2169
2978
  Scale = "Scale",
2170
2979
  FadeAlpha = "FadeAlpha",
2171
- Rotate = "Rotate"
2980
+ Rotate = "Rotate",
2981
+ Play = "Play",
2982
+ Repeat = "Repeat",
2983
+ RepeatForever = "RepeatForever"
2984
+ }
2985
+
2986
+ /**
2987
+ * A class for for working with numeric values that may be currently unknown,
2988
+ * but may be known in the future.
2989
+ *
2990
+ * @remarks Most m2c2kit actions have a known duration, such as waiting for a
2991
+ * given duration or moving a node to a specific position across a specific
2992
+ * duration: the duration is explicitly provided when the `Action` is created.
2993
+ * However, some actions have a duration that is not known when the `Action` is
2994
+ * created, but it will be known in the future. So far, the only action that
2995
+ * requires this is the `play` action. In the browser, a sound file cannot be
2996
+ * decoded by the `AudioContext` interface (which will calculate the duration)
2997
+ * until the user has interacted with the page, which could be after the
2998
+ * `Action` has been created. This is a problem because a `sequence` action
2999
+ * needs to know the duration of all its children in order to calculate its own
3000
+ * duration and when each of the child actions will start. To solve this
3001
+ * problem, the `Futurable` class is a simple implementation of the Composite
3002
+ * pattern that allows for the creation of a numeric value that may be known in
3003
+ * the future. If a value is not known at creation time, it is represented by
3004
+ * `Infinity`. The `Futurable` class supports addition and subtraction of
3005
+ * another `Futurable` and numbers. When the numeric value of a `Futurable` is
3006
+ * requested, it evaluates the expression and returns the numeric value. If any
3007
+ * of the terms in the expression is a `Futurable`, it will recursively
3008
+ * evaluate them. If any of the terms are unknown (represented by `Infinity`),
3009
+ * it will return `Infinity`. If a previous unknown value becomes known, any
3010
+ * other `Futurable` that depends on it will also become known.
3011
+ */
3012
+ declare class Futurable {
3013
+ /** The numbers, operators, and other Futurables that represent a value. */
3014
+ private expression;
3015
+ /** Log a warning to console if a expression is this length. */
3016
+ private readonly WARNING_EXPRESSION_LENGTH;
3017
+ constructor(value?: Futurable | number);
3018
+ /**
3019
+ * Appends a number or another Futurable to this Futurable's expression.
3020
+ *
3021
+ * @remarks This method does a simple array push, but checks the length of
3022
+ * the expression array and warns if it gets "too long." This may indicate
3023
+ * a logic error, unintended recursion, etc. because our use cases will
3024
+ * likely not have expressions that are longer than
3025
+ * `Futural.WARNING_EXPRESSION_LENGTH` elements.
3026
+ *
3027
+ * @param value - value to add to the expression.
3028
+ */
3029
+ private pushToExpression;
3030
+ /**
3031
+ * Assigns a value, either known or Futurable, to this Futurable.
3032
+ *
3033
+ * @remarks This method clears the current expression.
3034
+ *
3035
+ * @param value - value to assign to this Futurable.
3036
+ */
3037
+ assign(value: number | Futurable): void;
3038
+ /**
3039
+ * Performs addition on this Futurable.
3040
+ *
3041
+ * @remarks This method modifies the Futurable by adding the term(s) to the
3042
+ * Futurable's expression.
3043
+ *
3044
+ * @param terms - terms to add to this Futurable.
3045
+ * @returns the modified Futurable.
3046
+ */
3047
+ add(...terms: Array<Futurable | number>): this;
3048
+ /**
3049
+ * Performs subtraction on this Futurable.
3050
+ *
3051
+ * @remarks This method modifies the Futurable by subtracting the term(s)
3052
+ * from the Futurable's expression.
3053
+ *
3054
+ * @param terms - terms to subtract from this Futurable.
3055
+ * @returns the modified Futurable.
3056
+ */
3057
+ subtract(...terms: Array<Futurable | number>): this;
3058
+ /**
3059
+ * Adds an operation (an operator and term(s)) to the Futurable's
3060
+ * expression.
3061
+ *
3062
+ * @param operator - Add or Subtract.
3063
+ * @param terms - terms to add to the expression.
3064
+ */
3065
+ private appendOperation;
3066
+ /**
3067
+ * Gets the numeric value of this Futurable.
3068
+ *
3069
+ * @remarks This method evaluates the expression of the Futurable and
3070
+ * returns the numeric value. If any of the terms in the expression are
3071
+ * Futurables, it will recursively evaluate them. If any of the terms are
3072
+ * unknown (represented by Infinity), it will return Infinity.
3073
+ *
3074
+ * @returns the numeric value of this Futurable.
3075
+ */
3076
+ get value(): number;
3077
+ }
3078
+
3079
+ /**
3080
+ * An extension of `ActionContainer` that can repeat another action.
3081
+ *
3082
+ * @remarks A `RepeatingActionContainer` is a parent action that repeats
3083
+ * another action for a specified number of repetitions, as provided in the
3084
+ * `count` property. The `Repeat` and `RepeatForever` actions implement
3085
+ * `RepeatingActionContainer`.
3086
+ */
3087
+ interface RepeatingActionContainer extends ActionContainer {
3088
+ /** Number of times the action will repeat. */
3089
+ count: number;
3090
+ /** Number of completions done. */
3091
+ completedRepetitions: number;
3092
+ /** How long, in milliseconds, the repeating action has run. This is updated
3093
+ * only at the end of a repetition. */
3094
+ cumulativeDuration: number;
3095
+ /** Returns true when the action is running and the action's children have
3096
+ * just completed a repetition */
3097
+ repetitionHasCompleted: boolean;
3098
+ }
3099
+
3100
+ interface RepeatActionOptions {
3101
+ /** Action to repeat */
3102
+ action: Action;
3103
+ /** Number of times to repeat the action */
3104
+ count: number;
3105
+ /** Should the action run during screen transitions? Default is no */
3106
+ runDuringTransition?: boolean;
3107
+ }
3108
+
3109
+ interface RepeatForeverActionOptions {
3110
+ /** Action to repeat */
3111
+ action: Action;
3112
+ /** Should the action run during screen transitions? Default is no */
3113
+ runDuringTransition?: boolean;
2172
3114
  }
2173
3115
 
2174
3116
  /**
@@ -2177,151 +3119,362 @@ declare enum ActionType {
2177
3119
  */
2178
3120
  declare abstract class Action {
2179
3121
  abstract type: ActionType;
2180
- startOffset: number;
2181
- endOffset: number;
3122
+ startOffset: Futurable;
2182
3123
  started: boolean;
2183
3124
  running: boolean;
2184
- completed: boolean;
3125
+ private _completed;
3126
+ /**
3127
+ * Start time of a running action is always known; it is not a `Futurable`.
3128
+ * -1 indicates that the root action has not yet started running.
3129
+ */
2185
3130
  runStartTime: number;
2186
- duration: number;
3131
+ duration: Futurable;
2187
3132
  runDuringTransition: boolean;
2188
- parent?: Action;
2189
- isParent: boolean;
2190
- isChild: boolean;
3133
+ parent?: ActionContainer;
2191
3134
  key?: string;
2192
3135
  constructor(runDuringTransition?: boolean);
3136
+ /**
3137
+ * Prepares the Action for evaluation.
3138
+ *
3139
+ * @remarks Calculates start times for all actions in the hierarchy
3140
+ * and returns a copy of the action that is prepared for evaluation during
3141
+ * the update loop.
3142
+ *
3143
+ * @param key - optional string to identify an action
3144
+ * @returns action prepared for evaluation
3145
+ */
3146
+ initialize(key?: string): Action;
3147
+ /**
3148
+ * Clones the action, and any actions it contains, recursively.
3149
+ *
3150
+ * @remarks We need to clone an action before running it because actions
3151
+ * have state that is updated over time such as whether they are running or
3152
+ * not, etc. If we didn't clone actions, two nodes reusing the same action
3153
+ * would share state. On `Action`, this method is abstract and is
3154
+ * implemented in each subclass.
3155
+ *
3156
+ * @returns a clone of the action
3157
+ */
3158
+ abstract clone(): Action;
3159
+ /**
3160
+ * Parses the action hierarchy and assigns each action its parent and
3161
+ * root action.
3162
+ *
3163
+ * @remarks Uses recursion to handle arbitrary level of nesting parent
3164
+ * actions within parent actions. When this method is called from the
3165
+ * `initialize()` method, the root action is both the `action` and the
3166
+ * `rootAction`. This is because the action is the top-level action in the
3167
+ * hierarchy. When the method calls itself recursively, the `rootAction`
3168
+ * remains the same, but the `action` is a child action or the action of a
3169
+ * repeating action.
3170
+ *
3171
+ * @param action - the action to assign parents to
3172
+ * @param rootAction - top-level action passed to the run method
3173
+ * @param key - optional string to identify an action. The key is assigned
3174
+ * to every action in the hierarchy.
3175
+ */
3176
+ private assignParents;
3177
+ /**
3178
+ * Sets the runDuringTransition property based on descendants.
3179
+ *
3180
+ * @remarks This ensures that a parent action has its `runDuringTransition`
3181
+ * property set to true if any of its descendants have their
3182
+ * `runDuringTransition` property set to true. Parent actions do not have a
3183
+ * way for the user to set this property directly; it is inferred (propagated
3184
+ * up) from the descendants.
3185
+ *
3186
+ * @param action to propagate runDuringTransition property to
3187
+ */
3188
+ private propagateRunDuringTransition;
3189
+ /**
3190
+ * Assigns durations to all actions in the hierarchy.
3191
+ *
3192
+ * @remarks Uses recursion to handle arbitrary level of nesting parent
3193
+ * actions within parent actions.
3194
+ *
3195
+ * @param action - the action to assign durations to
3196
+ */
3197
+ private assignDurations;
3198
+ /**
3199
+ * Calculates the duration of an action, including any children actions
3200
+ * the action may contain.
3201
+ *
3202
+ * @remarks Uses recursion to handle arbitrary level of nesting parent
3203
+ * actions within parent actions
3204
+ *
3205
+ * @param action
3206
+ * @returns the calculated duration
3207
+ */
3208
+ private calculateDuration;
3209
+ /**
3210
+ * Assigns start offsets to all actions in the hierarchy.
3211
+ *
3212
+ * @remarks Uses recursion to handle arbitrary level of nesting parent
3213
+ * actions within parent actions.
3214
+ *
3215
+ * @param action - the action to assign start offsets to
3216
+ */
3217
+ private assignStartOffsets;
3218
+ /**
3219
+ * Calculates the start offset. This is when an action should start,
3220
+ * relative to the start time of its parent (if it has a parent).
3221
+ *
3222
+ * @param action - the action to calculate the start offset for
3223
+ * @returns the start offset as a Futurable
3224
+ */
3225
+ private calculateStartOffset;
3226
+ /**
3227
+ * Evaluates an action, updating the node's properties as needed.
3228
+ *
3229
+ * @remarks This method is called every frame by the M2Node's `update()`
3230
+ * method.
3231
+ *
3232
+ * @param action - the Action to be evaluated and possibly run
3233
+ * @param node - the `M2Node` that the action will be run on
3234
+ * @param now - the current elapsed time, from `performance.now()`
3235
+ * @param dt - the time since the last frame (delta time)
3236
+ */
3237
+ static evaluateAction(action: Action, node: M2Node, now: number, dt: number): void;
3238
+ private static evaluateRepeatingActions;
3239
+ private static evaluateRotateAction;
3240
+ private static evaluateFadeAlphaAction;
3241
+ private static evaluateScaleAction;
3242
+ private static evaluateMoveAction;
3243
+ private static evaluateWaitAction;
3244
+ private static evaluatePlayAction;
3245
+ private static evaluateCustomAction;
3246
+ /**
3247
+ * Assigns RunStartTime to all actions in the hierarchy.
3248
+ *
3249
+ * @remarks Uses recursion to handle arbitrary level of nesting parent
3250
+ * actions within parent actions.
3251
+ *
3252
+ * @param action - the action to assign RunStartTime to
3253
+ */
3254
+ assignRunStartTimes(action: Action, runStartTime: number): void;
3255
+ /**
3256
+ * Configures action to be run again.
3257
+ *
3258
+ * @remarks This method is called on a repeating action's children when they
3259
+ * need to be run again.
3260
+ *
3261
+ * @param action - action to restart
3262
+ * @param now - current time
3263
+ */
3264
+ restartAction(action: Action, now: number): void;
3265
+ /**
3266
+ * Determines if the action should be running.
3267
+ *
3268
+ * @remarks An action should be running if current time is in the interval
3269
+ * [ start time + start offset, start time + start offset + duration ]
3270
+ *
3271
+ * @param now - current time
3272
+ * @returns true if the action should be running
3273
+ */
3274
+ shouldBeRunning(now: number): boolean;
2193
3275
  /**
2194
3276
  * Creates an action that will move a node to a point on the screen.
2195
3277
  *
2196
3278
  * @param options - {@link MoveActionOptions}
2197
3279
  * @returns The move action
2198
3280
  */
2199
- static move(options: MoveActionOptions): Action;
3281
+ static move(options: MoveActionOptions): MoveAction;
2200
3282
  /**
2201
- * Creates an action that will wait a given duration before it is considered complete.
3283
+ * Creates an action that will wait a given duration before it is considered
3284
+ * complete.
2202
3285
  *
2203
3286
  * @param options - {@link WaitActionOptions}
2204
3287
  * @returns The wait action
2205
3288
  */
2206
- static wait(options: WaitActionOptions): Action;
3289
+ static wait(options: WaitActionOptions): WaitAction;
2207
3290
  /**
2208
3291
  * Creates an action that will execute a callback function.
2209
3292
  *
2210
3293
  * @param options - {@link CustomActionOptions}
2211
3294
  * @returns The custom action
2212
3295
  */
2213
- static custom(options: CustomActionOptions): Action;
3296
+ static custom(options: CustomActionOptions): CustomAction;
3297
+ /**
3298
+ * Creates an action that will play a sound.
3299
+ *
3300
+ * @remarks This action can only be used with a SoundPlayer node.
3301
+ * It will throw an error if used with any other node type.
3302
+ *
3303
+ * @param options - {@link PlayActionOptions}
3304
+ * @returns The play action
3305
+ */
3306
+ static play(options?: PlayActionOptions): PlayAction;
2214
3307
  /**
2215
3308
  * Creates an action that will scale the node's size.
2216
3309
  *
2217
- * @remarks Scaling is relative to any inherited scaling, which is multiplicative. For example, if the node's parent is scaled to 2.0 and this node's action scales to 3.0, then the node will appear 6 times as large as original.
3310
+ * @remarks Scaling is relative to any inherited scaling, which is
3311
+ * multiplicative. For example, if the node's parent is scaled to 2.0 and
3312
+ * this node's action scales to 3.0, then the node will appear 6 times as
3313
+ * large as original.
2218
3314
  *
2219
3315
  * @param options - {@link ScaleActionOptions}
2220
3316
  * @returns The scale action
2221
3317
  */
2222
- static scale(options: ScaleActionOptions): Action;
3318
+ static scale(options: ScaleActionOptions): ScaleAction;
2223
3319
  /**
2224
3320
  * Creates an action that will change the node's alpha (opacity).
2225
3321
  *
2226
- * @remarks Alpha has multiplicative inheritance. For example, if the node's parent is alpha .5 and this node's action fades alpha to .4, then the node will appear with alpha .2.
3322
+ * @remarks Alpha has multiplicative inheritance. For example, if the node's
3323
+ * parent is alpha .5 and this node's action fades alpha to .4, then the
3324
+ * node will appear with alpha .2.
2227
3325
  *
2228
3326
  * @param options - {@link FadeAlphaActionOptions}
2229
3327
  * @returns The fadeAlpha action
2230
3328
  */
2231
- static fadeAlpha(options: FadeAlphaActionOptions): Action;
3329
+ static fadeAlpha(options: FadeAlphaActionOptions): FadeAlphaAction;
2232
3330
  /**
2233
3331
  * Creates an action that will rotate the node.
2234
3332
  *
2235
- * @remarks Rotate actions are applied to their children. In addition to this node's rotate action, all ancestors' rotate actions will also be applied.
3333
+ * @remarks Rotate actions are applied to their children. In addition to this
3334
+ * node's rotate action, all ancestors' rotate actions will also be applied.
2236
3335
  *
2237
3336
  * @param options - {@link RotateActionOptions}
2238
3337
  * @returns The rotate action
2239
3338
  */
2240
- static rotate(options: RotateActionOptions): Action;
3339
+ static rotate(options: RotateActionOptions): RotateAction;
2241
3340
  /**
2242
3341
  * Creates an array of actions that will be run in order.
2243
3342
  *
2244
- * @remarks The next action will not begin until the current one has finished. The sequence will be considered completed when the last action has completed.
3343
+ * @remarks The next action will not begin until the current one has
3344
+ * finished. The sequence will be considered completed when the last action
3345
+ * has completed.
2245
3346
  *
2246
3347
  * @param actions - One or more actions that form the sequence
2247
3348
  * @returns
2248
3349
  */
2249
- static sequence(actions: Array<Action>): Action;
3350
+ static sequence(actions: Array<Action>): SequenceAction;
2250
3351
  /**
2251
3352
  * Create an array of actions that will be run simultaneously.
2252
3353
  *
2253
- * @remarks All actions within the group will begin to run at the same time. The group will be considered completed when the longest-running action has completed.
3354
+ * @remarks All actions within the group will begin to run at the same time.
3355
+ * The group will be considered completed when the longest-running action
3356
+ * has completed.
2254
3357
  *
2255
3358
  * @param actions - One or more actions that form the group
2256
3359
  * @returns
2257
3360
  */
2258
- static group(actions: Array<Action>): Action;
2259
- initialize(node: M2Node, key?: string): Array<Action>;
2260
- static cloneAction(action: Action, key?: string): Action;
2261
- static evaluateAction(action: Action, node: M2Node, now: number, dt: number): void;
3361
+ static group(actions: Array<Action>): GroupAction;
2262
3362
  /**
2263
- * Calculates the duration of an action, including any children actions
2264
- * the action may contain.
2265
- *
2266
- * @remarks Uses recursion to handle arbitrary level of nesting parent
2267
- * actions within parent actions
3363
+ * Creates an action that will repeat another action a given number of times.
2268
3364
  *
2269
- * @param action
2270
- * @returns the calculated duration
3365
+ * @param options - {@link RepeatActionOptions}
3366
+ * @returns The repeat action
2271
3367
  */
2272
- private calculateDuration;
3368
+ static repeat(options: RepeatActionOptions): RepeatAction;
2273
3369
  /**
2274
- * Update each action's start and end offsets.
3370
+ * Creates an action that will repeat another action forever.
2275
3371
  *
2276
- * @remarks Uses recursion to handle arbitrary level of nesting parent
2277
- * actions within parent actions.
3372
+ * @remarks A repeat forever action is a special case of a repeat action
3373
+ * where the count is set to infinity.
2278
3374
  *
2279
- * @param action that needs assigning start and end offsets
3375
+ * @param options - {@link RepeatForeverActionOptions}
3376
+ * @returns The repeat forever action
2280
3377
  */
2281
- private calculateStartEndOffsets;
3378
+ static repeatForever(options: RepeatForeverActionOptions): RepeatForeverAction;
2282
3379
  /**
2283
- * Takes an action hierarchy and flattens to an array of non-nested actions
3380
+ * Type guard that returns true if the action is a parent action.
2284
3381
  *
2285
- * @remarks Uses recursion to handle arbitrary level of nesting parent
2286
- * actions within parent actions
3382
+ * @remarks Parent actions are Group, Sequence, Repeat, and RepeatForever
3383
+ * actions.
2287
3384
  *
2288
- * @param action - the action to flatten
2289
- * @param actions - the accumulator array of flattened actions. This will be
2290
- * undefined on the first call, and an array on recursive calls
2291
- * @returns flattened array of actions
3385
+ * @param action - action to check
3386
+ * @returns true if the action is a parent action
2292
3387
  */
2293
- private flattenActions;
3388
+ isParent(action: Action): action is ActionContainer;
2294
3389
  /**
2295
- * Parses the action hierarchy and assigns each action its parent and
2296
- * root action.
3390
+ * Type guard that returns true if the action can repeat.
2297
3391
  *
2298
- * @remarks Uses recursion to handle arbitrary level of nesting parent
2299
- * actions within parent actions
3392
+ * @remarks Repeating actions are Repeat and RepeatForever actions.
2300
3393
  *
2301
- * @param action
2302
- * @param rootAction - top-level action passed to the run method
2303
- * @param key - optional string to identify an action
3394
+ * @param action - action to check
3395
+ * @returns true if the action is a RepeatAction or RepeatForeverAction
2304
3396
  */
2305
- private assignParents;
3397
+ private isRepeating;
3398
+ /**
3399
+ * Indicates whether the action has completed.
3400
+ */
3401
+ get completed(): boolean;
3402
+ set completed(value: boolean);
2306
3403
  }
2307
- declare class SequenceAction extends Action implements IActionContainer {
3404
+ declare class SequenceAction extends Action implements ActionContainer {
2308
3405
  type: ActionType;
2309
3406
  children: Array<Action>;
2310
3407
  constructor(actions: Array<Action>);
3408
+ clone(): SequenceAction;
3409
+ /**
3410
+ * Indicates whether the action has completed, taking into account all its
3411
+ * child actions.
3412
+ *
3413
+ * @remarks Is read-only for parent actions.
3414
+ */
3415
+ get completed(): boolean;
3416
+ get descendants(): Action[];
3417
+ }
3418
+ declare class GroupAction extends Action implements ActionContainer {
3419
+ type: ActionType;
3420
+ children: Action[];
3421
+ constructor(actions: Array<Action>);
3422
+ clone(): GroupAction;
3423
+ /**
3424
+ * Indicates whether the action has completed, taking into account all its
3425
+ * child actions.
3426
+ *
3427
+ * @remarks Is read-only for parent actions.
3428
+ */
3429
+ get completed(): boolean;
3430
+ get descendants(): Action[];
3431
+ }
3432
+ declare class RepeatAction extends Action implements RepeatingActionContainer {
3433
+ type: ActionType;
3434
+ count: number;
3435
+ children: Array<Action>;
3436
+ completedRepetitions: number;
3437
+ cumulativeDuration: number;
3438
+ constructor(action: Action, count: number, runDuringTransition?: boolean);
3439
+ clone(): RepeatAction;
3440
+ /**
3441
+ * Indicates whether the action has completed, taking into account all its
3442
+ * child actions and the number of repetitions.
3443
+ *
3444
+ * @remarks Is read-only for parent actions.
3445
+ */
3446
+ get completed(): boolean;
3447
+ get descendantsAreCompleted(): boolean;
3448
+ /**
3449
+ * Indicates whether a single repetition of a repeating action has just
3450
+ * completed.
3451
+ *
3452
+ * @returns returns true if a repetition has completed
3453
+ */
3454
+ get repetitionHasCompleted(): boolean;
3455
+ get descendants(): Action[];
2311
3456
  }
2312
- declare class GroupAction extends Action implements IActionContainer {
3457
+ declare class RepeatForeverAction extends RepeatAction {
2313
3458
  type: ActionType;
2314
- children: Action[];
2315
- constructor(actions: Array<Action>);
3459
+ count: number;
3460
+ constructor(action: Action, runDuringTransition?: boolean);
3461
+ clone(): RepeatForeverAction;
2316
3462
  }
2317
3463
  declare class CustomAction extends Action {
2318
3464
  type: ActionType;
2319
3465
  callback: () => void;
2320
3466
  constructor(callback: () => void, runDuringTransition?: boolean);
3467
+ clone(): CustomAction;
3468
+ }
3469
+ declare class PlayAction extends Action {
3470
+ type: ActionType;
3471
+ constructor(runDuringTransition?: boolean);
3472
+ clone(): PlayAction;
2321
3473
  }
2322
3474
  declare class WaitAction extends Action {
2323
3475
  type: ActionType;
2324
- constructor(duration: number, runDuringTransition: boolean);
3476
+ constructor(duration: Futurable, runDuringTransition: boolean);
3477
+ clone(): WaitAction;
2325
3478
  }
2326
3479
  declare class MoveAction extends Action {
2327
3480
  type: ActionType;
@@ -2330,19 +3483,22 @@ declare class MoveAction extends Action {
2330
3483
  dx: number;
2331
3484
  dy: number;
2332
3485
  easing: EasingFunction;
2333
- constructor(point: Point, duration: number, easing: EasingFunction, runDuringTransition: boolean);
3486
+ constructor(point: Point, duration: Futurable, easing: EasingFunction, runDuringTransition: boolean);
3487
+ clone(): MoveAction;
2334
3488
  }
2335
3489
  declare class ScaleAction extends Action {
2336
3490
  type: ActionType;
2337
3491
  scale: number;
2338
3492
  delta: number;
2339
- constructor(scale: number, duration: number, runDuringTransition?: boolean);
3493
+ constructor(scale: number, duration: Futurable, runDuringTransition?: boolean);
3494
+ clone(): ScaleAction;
2340
3495
  }
2341
3496
  declare class FadeAlphaAction extends Action {
2342
3497
  type: ActionType;
2343
3498
  alpha: number;
2344
3499
  delta: number;
2345
- constructor(alpha: number, duration: number, runDuringTransition?: boolean);
3500
+ constructor(alpha: number, duration: Futurable, runDuringTransition?: boolean);
3501
+ clone(): FadeAlphaAction;
2346
3502
  }
2347
3503
  declare class RotateAction extends Action {
2348
3504
  type: ActionType;
@@ -2351,7 +3507,8 @@ declare class RotateAction extends Action {
2351
3507
  shortestUnitArc?: boolean;
2352
3508
  delta: number;
2353
3509
  finalValue: number;
2354
- constructor(byAngle: number | undefined, toAngle: number | undefined, shortestUnitArc: boolean | undefined, duration: number, runDuringTransition?: boolean);
3510
+ constructor(byAngle: number | undefined, toAngle: number | undefined, shortestUnitArc: boolean | undefined, duration: Futurable, runDuringTransition?: boolean);
3511
+ clone(): RotateAction;
2355
3512
  }
2356
3513
 
2357
3514
  interface ActivityCallbacks {
@@ -2473,28 +3630,6 @@ declare class ColorfulMutablePath extends MutablePath {
2473
3630
  duplicate(): ColorfulMutablePath;
2474
3631
  }
2475
3632
 
2476
- interface CompositeOptions extends M2NodeOptions, DrawableOptions {
2477
- }
2478
-
2479
- declare abstract class Composite extends M2Node implements IDrawable {
2480
- readonly type = M2NodeType.Composite;
2481
- compositeType: string;
2482
- isDrawable: boolean;
2483
- anchorPoint: Point;
2484
- zPosition: number;
2485
- /**
2486
- * Base Drawable object for creating custom nodes ("composites") composed of primitive nodes.
2487
- *
2488
- * @param options
2489
- */
2490
- constructor(options?: CompositeOptions);
2491
- initialize(): void;
2492
- dispose(): void;
2493
- update(): void;
2494
- draw(canvas: Canvas): void;
2495
- abstract warmup(canvas: Canvas): void;
2496
- }
2497
-
2498
3633
  /**
2499
3634
  * Reasonable defaults to use if values are not specified.
2500
3635
  */
@@ -2553,10 +3688,79 @@ declare enum Dimensions {
2553
3688
  MatchConstraint = 0
2554
3689
  }
2555
3690
 
3691
+ type M2NodeConstructor = new (options?: M2NodeOptions) => M2Node;
3692
+
2556
3693
  /**
2557
3694
  * Utility class for comparing equality of m2c2kit objects.
3695
+ *
3696
+ * @deprecated Use the class `Equal` instead.
2558
3697
  */
2559
3698
  declare class Equals {
3699
+ /**
3700
+ * Compares two RgbaColor objects and returns true if they are equal.
3701
+ *
3702
+ * @remarks If either of the colors is undefined, the comparison will
3703
+ * return false. RgbaColor is an array of 4 numbers, and thus is a
3704
+ * reference type. We need this method to compare two RgbaColor objects
3705
+ * for value equality.
3706
+ *
3707
+ * @deprecated Use the methods in `Equal` instead.
3708
+ *
3709
+ * @param color1
3710
+ * @param color2
3711
+ * @returns
3712
+ */
3713
+ static rgbaColor(color1?: RgbaColor, color2?: RgbaColor): boolean;
3714
+ }
3715
+
3716
+ interface RectOptions {
3717
+ /** Position of rectangle */
3718
+ origin?: Point;
3719
+ /** Size of rectangle */
3720
+ size?: Size;
3721
+ /** X coordinate of rectangle position; this can be used instead of setting the origin property */
3722
+ x?: number;
3723
+ /** Y coordinate of rectangle position; this can be used instead of setting the origin property */
3724
+ y?: number;
3725
+ /** Width of rectangle; this can be used instead of setting the size property */
3726
+ width?: number;
3727
+ /** Height of rectangle; this can be used instead of setting the size property */
3728
+ height?: number;
3729
+ }
3730
+
3731
+ /**
3732
+ * A collection of multi-color lines to draw.
3733
+ *
3734
+ * @remarks Unlike `M2Path`, this interface allows for lines of different
3735
+ * colors and widths to be drawn in the same path.
3736
+ */
3737
+ interface M2ColorfulPath extends M2Path {
3738
+ /** Colors and widths of lines in the path. */
3739
+ linePresentations: Array<LinePresentation>;
3740
+ }
3741
+
3742
+ /**
3743
+ * A path created from an SVG string path.
3744
+ */
3745
+ interface SvgStringPath {
3746
+ /** SVG string from which to create the path */
3747
+ pathString?: string;
3748
+ /** SVG string from which to create the path @deprecated Use `pathString` */
3749
+ svgPathString?: string;
3750
+ /** If provided, scale the SVG path to this height, and scale the width to keep the original SVG proportions */
3751
+ height?: number;
3752
+ /** If provided, scale the SVG path to this width, and scale the height to keep the original SVG proportions */
3753
+ width?: number;
3754
+ }
3755
+
3756
+ type ValueType = string | number | boolean | null | undefined | Array<ValueType> | {
3757
+ [key: string]: ValueType;
3758
+ } | Point | RectOptions | M2Path | M2ColorfulPath | SvgStringPath | Size;
3759
+ /**
3760
+ * Utility class for comparing equality of m2c2kit objects.
3761
+ *
3762
+ */
3763
+ declare class Equal {
2560
3764
  /**
2561
3765
  * Compares two RgbaColor objects and returns true if they are equal.
2562
3766
  *
@@ -2570,6 +3774,28 @@ declare class Equals {
2570
3774
  * @returns
2571
3775
  */
2572
3776
  static rgbaColor(color1?: RgbaColor, color2?: RgbaColor): boolean;
3777
+ /**
3778
+ * Compares two values for deep equality.
3779
+ *
3780
+ * @remarks Supported values are string, number, boolean, null, undefined,
3781
+ * and object (note that arrays are objects in JavaScript).
3782
+ *
3783
+ * @param value1 - value to compare
3784
+ * @param value2 - value to compare
3785
+ * @returns true if values have deep equality
3786
+ */
3787
+ static value(value1: ValueType, value2: ValueType): boolean;
3788
+ /**
3789
+ * Compares two objects for deep equality.
3790
+ *
3791
+ * @remarks In JavaScript, arrays are objects, so this method will also
3792
+ * compare arrays for deep equality.
3793
+ *
3794
+ * @param obj1 - object to compare
3795
+ * @param obj2 - object to compare
3796
+ * @returns true if objects have deep equality
3797
+ */
3798
+ private static objectsDeepEqual;
2573
3799
  }
2574
3800
 
2575
3801
  /**
@@ -2614,6 +3840,57 @@ declare class M2c2KitHelpers {
2614
3840
  * "https://", "file://", etc.)
2615
3841
  */
2616
3842
  static urlHasScheme(url: string): boolean;
3843
+ /**
3844
+ * Registers a `M2Node` class with the global class registry.
3845
+ *
3846
+ * @remarks This is used to register a class so that it can be
3847
+ * instantiated by the `M2NodeFactory`.
3848
+ *
3849
+ * @param nodeClass - class or classes to register.
3850
+ */
3851
+ static registerM2NodeClass(...nodeClass: Array<M2NodeConstructor>): void;
3852
+ /**
3853
+ * Creates timestamps based on when the current frame's update began.
3854
+ *
3855
+ * @remarks When recording events related to node creation, node
3856
+ * parent-child relationships, and node properties, the timestamps should be
3857
+ * based on when current frame's update began -- not the current time. While
3858
+ * current time is most accurate for recording user interactions (use
3859
+ * `M2c2KitHelpers.createTimestamps()` for user interactions), the frame's
3860
+ * update is the best way to ensure that node events that occurred in the same
3861
+ * frame are recorded with the same timestamp and thus are replayed in the
3862
+ * correct order. For example, a node may be created, added to a scene, and
3863
+ * have its hidden property set to true, all in the same frame. If the
3864
+ * current timestamps were used for all these events, it could happen that
3865
+ * the hidden property is set slightly after the node is added to the scene.
3866
+ * When replayed, this could cause the node to be visible for a single frame
3867
+ * if the queue of replay events pulls only the creation and addition events.
3868
+ * By using the frame's update time, we ensure that all events related to a
3869
+ * node are recorded with the same timestamp and are replayed in the same
3870
+ * frame.
3871
+ * If game has not yet begun to run (i.e., frame updates have not yet started),
3872
+ * the timestamps will be based on the current time.
3873
+ *
3874
+ * @returns object with timestamps
3875
+ */
3876
+ static createFrameUpdateTimestamps(): {
3877
+ timestamp: number;
3878
+ iso8601Timestamp: string;
3879
+ };
3880
+ /**
3881
+ * Creates timestamps based on the current time.
3882
+ *
3883
+ * @remarks Use `M2c2KitHelpers.createFrameUpdateTimestamps()` when requesting
3884
+ * timestamps for events related to node creation, parent-child
3885
+ * relationships, and properties.
3886
+ * See {@link createFrameUpdateTimestamps()} for explanation.
3887
+ *
3888
+ * @returns object with `timestamp` and `iso8601Timestamp` properties
3889
+ */
3890
+ static createTimestamps(): {
3891
+ timestamp: number;
3892
+ iso8601Timestamp: string;
3893
+ };
2617
3894
  /**
2618
3895
  * Calculates the four points of the bounding box of the node, taking
2619
3896
  * into account the node's rotation (as well as the rotation of its
@@ -2755,11 +4032,44 @@ interface FontData {
2755
4032
  isDefault: boolean;
2756
4033
  }
2757
4034
 
4035
+ declare global {
4036
+ var m2c2Globals: GlobalVariables;
4037
+ }
4038
+ interface GlobalVariables {
4039
+ now: number;
4040
+ iso8601Now: string;
4041
+ deltaTime: number;
4042
+ canvasScale: number;
4043
+ /**
4044
+ * rootScale is the scaling factor to be applied to scenes to scale up or
4045
+ * down to fit the device's window while preserving the aspect ratio the
4046
+ * game was designed for
4047
+ */
4048
+ rootScale: number;
4049
+ canvasCssWidth: number;
4050
+ canvasCssHeight: number;
4051
+ /**
4052
+ * A dictionary of all `M2Node` classes that have been registered.
4053
+ * This is used to instantiate `M2Node` objects from their class name.
4054
+ *
4055
+ * @remarks The type should be `{ [key: string]: M2NodeConstructor }` or
4056
+ * `M2NodeClassRegistry`. But, this creates problems in Jest: I could not
4057
+ * get ts-jest to compile when the type of a global variable is not a
4058
+ * simple type. Instead, the type of `m2NodeClassRegistry` is `object`,
4059
+ * and I will assert it to `M2NodeClassRegistry` when needed.
4060
+ */
4061
+ m2NodeClassRegistry: object;
4062
+ get eventSequence(): number;
4063
+ __sequence: number;
4064
+ }
4065
+
2758
4066
  interface IText {
2759
4067
  text?: string;
2760
4068
  fontName?: string;
2761
4069
  fontColor?: RgbaColor;
2762
4070
  fontSize?: number;
4071
+ interpolation?: StringInterpolationMap;
4072
+ localize?: boolean;
2763
4073
  }
2764
4074
 
2765
4075
  declare enum LabelHorizontalAlignmentMode {
@@ -2783,25 +4093,25 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
2783
4093
  readonly type = M2NodeType.Label;
2784
4094
  isDrawable: boolean;
2785
4095
  isText: boolean;
2786
- anchorPoint: {
2787
- x: number;
2788
- y: number;
2789
- };
2790
- zPosition: number;
4096
+ private _anchorPoint;
4097
+ private _zPosition;
2791
4098
  private _text;
2792
4099
  private _fontName;
2793
4100
  private _fontNames;
2794
4101
  private _fontColor;
2795
4102
  private _fontSize;
4103
+ private _interpolation;
2796
4104
  private _horizontalAlignmentMode;
2797
4105
  private _preferredMaxLayoutWidth;
2798
4106
  private _backgroundColor?;
4107
+ private _localize;
2799
4108
  private paragraph?;
2800
4109
  private paraStyle?;
2801
4110
  private builder?;
2802
4111
  private _fontPaint?;
2803
4112
  private _backgroundPaint?;
2804
- private _translatedText;
4113
+ private localizedFontName;
4114
+ private localizedFontNames;
2805
4115
  /**
2806
4116
  * Single or multi-line text formatted and rendered on the screen.
2807
4117
  *
@@ -2810,6 +4120,31 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
2810
4120
  * @param options - {@link LabelOptions}
2811
4121
  */
2812
4122
  constructor(options?: LabelOptions);
4123
+ get completeNodeOptions(): {
4124
+ horizontalAlignmentMode: LabelHorizontalAlignmentMode;
4125
+ preferredMaxLayoutWidth: number | undefined;
4126
+ backgroundColor: RgbaColor | undefined;
4127
+ fontNames: string[] | undefined;
4128
+ text?: string;
4129
+ fontName?: string;
4130
+ fontColor?: RgbaColor;
4131
+ fontSize?: number;
4132
+ interpolation?: StringInterpolationMap;
4133
+ localize?: boolean;
4134
+ anchorPoint?: Point;
4135
+ zPosition?: number;
4136
+ name?: string;
4137
+ position?: Point;
4138
+ scale?: number;
4139
+ alpha?: number;
4140
+ zRotation?: number;
4141
+ isUserInteractionEnabled?: boolean;
4142
+ draggable?: boolean;
4143
+ hidden?: boolean;
4144
+ layout?: Layout;
4145
+ uuid?: string;
4146
+ suppressEvents?: boolean;
4147
+ };
2813
4148
  initialize(): void;
2814
4149
  /**
2815
4150
  * Determines the M2Font objects that need to be ready in order to draw
@@ -2825,7 +4160,8 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
2825
4160
  dispose(): void;
2826
4161
  get text(): string;
2827
4162
  set text(text: string);
2828
- get translatedText(): string;
4163
+ get interpolation(): StringInterpolationMap;
4164
+ set interpolation(interpolation: StringInterpolationMap);
2829
4165
  get fontName(): string | undefined;
2830
4166
  set fontName(fontName: string | undefined);
2831
4167
  get fontNames(): Array<string> | undefined;
@@ -2840,6 +4176,12 @@ declare class Label extends M2Node implements IDrawable, IText, LabelOptions {
2840
4176
  set preferredMaxLayoutWidth(preferredMaxLayoutWidth: number | undefined);
2841
4177
  get backgroundColor(): RgbaColor | undefined;
2842
4178
  set backgroundColor(backgroundColor: RgbaColor | undefined);
4179
+ get localize(): boolean;
4180
+ set localize(localize: boolean);
4181
+ get anchorPoint(): Point;
4182
+ set anchorPoint(anchorPoint: Point);
4183
+ get zPosition(): number;
4184
+ set zPosition(zPosition: number);
2843
4185
  private get backgroundPaint();
2844
4186
  private set backgroundPaint(value);
2845
4187
  private get fontPaint();
@@ -3003,17 +4345,6 @@ declare class LegacyTimer {
3003
4345
  static exists(name: string): boolean;
3004
4346
  }
3005
4347
 
3006
- /**
3007
- * A collection of multi-color lines to draw.
3008
- *
3009
- * @remarks Unlike `M2Path`, this interface allows for lines of different
3010
- * colors and widths to be drawn in the same path.
3011
- */
3012
- interface M2ColorfulPath extends M2Path {
3013
- /** Colors and widths of lines in the path. */
3014
- linePresentations: Array<LinePresentation>;
3015
- }
3016
-
3017
4348
  /** Base interface for all Plugin events. */
3018
4349
  interface PluginEvent extends M2Event<Plugin> {
3019
4350
  target: Plugin;
@@ -3061,21 +4392,6 @@ declare class RandomDraws {
3061
4392
  }>;
3062
4393
  }
3063
4394
 
3064
- interface RectOptions {
3065
- /** Position of rectangle */
3066
- origin?: Point;
3067
- /** Size of rectangle */
3068
- size?: Size;
3069
- /** X coordinate of rectangle position; this can be used instead of setting the origin property */
3070
- x?: number;
3071
- /** Y coordinate of rectangle position; this can be used instead of setting the origin property */
3072
- y?: number;
3073
- /** Width of rectangle; this can be used instead of setting the size property */
3074
- width?: number;
3075
- /** Height of rectangle; this can be used instead of setting the size property */
3076
- height?: number;
3077
- }
3078
-
3079
4395
  declare enum ShapeType {
3080
4396
  Undefined = "Undefined",
3081
4397
  Rectangle = "Rectangle",
@@ -3083,20 +4399,6 @@ declare enum ShapeType {
3083
4399
  Path = "Path"
3084
4400
  }
3085
4401
 
3086
- /**
3087
- * A path created from an SVG string path.
3088
- */
3089
- interface SvgStringPath {
3090
- /** SVG string from which to create the path */
3091
- pathString?: string;
3092
- /** SVG string from which to create the path @deprecated Use `pathString` */
3093
- svgPathString?: string;
3094
- /** If provided, scale the SVG path to this height, and scale the width to keep the original SVG proportions */
3095
- height?: number;
3096
- /** If provided, scale the SVG path to this width, and scale the height to keep the original SVG proportions */
3097
- width?: number;
3098
- }
3099
-
3100
4402
  interface ShapeOptions extends M2NodeOptions, DrawableOptions {
3101
4403
  shapeType?: ShapeType;
3102
4404
  /** If provided, shape will be a circle with given radius */
@@ -3123,22 +4425,19 @@ declare class Shape extends M2Node implements IDrawable, ShapeOptions {
3123
4425
  readonly type = M2NodeType.Shape;
3124
4426
  isDrawable: boolean;
3125
4427
  isShape: boolean;
3126
- anchorPoint: {
3127
- x: number;
3128
- y: number;
3129
- };
3130
- zPosition: number;
4428
+ private _anchorPoint;
4429
+ private _zPosition;
3131
4430
  shapeType: ShapeType;
3132
- circleOfRadius?: number;
3133
- rect?: RectOptions;
3134
- path?: M2Path | M2ColorfulPath | SvgStringPath;
4431
+ private _circleOfRadius?;
4432
+ private _rect?;
4433
+ private _path?;
3135
4434
  ckPath: Path | null;
3136
4435
  ckPathWidth?: number;
3137
4436
  ckPathHeight?: number;
3138
- cornerRadius: number;
4437
+ private _cornerRadius;
3139
4438
  private _fillColor;
3140
4439
  private _strokeColor?;
3141
- lineWidth?: number;
4440
+ private _lineWidth?;
3142
4441
  private _isAntialiased;
3143
4442
  private _fillColorPaintAntialiased?;
3144
4443
  private _strokeColorPaintAntialiased?;
@@ -3159,7 +4458,35 @@ declare class Shape extends M2Node implements IDrawable, ShapeOptions {
3159
4458
  * @param options - {@link ShapeOptions}
3160
4459
  */
3161
4460
  constructor(options?: ShapeOptions);
4461
+ get completeNodeOptions(): {
4462
+ circleOfRadius: number | undefined;
4463
+ rect: RectOptions | undefined;
4464
+ cornerRadius: number;
4465
+ fillColor: RgbaColor;
4466
+ strokeColor: RgbaColor | undefined;
4467
+ lineWidth: number | undefined;
4468
+ path: M2Path | M2ColorfulPath | SvgStringPath | undefined;
4469
+ size: Size | undefined;
4470
+ isAntialiased: boolean;
4471
+ anchorPoint?: Point;
4472
+ zPosition?: number;
4473
+ name?: string;
4474
+ position?: Point;
4475
+ scale?: number;
4476
+ alpha?: number;
4477
+ zRotation?: number;
4478
+ isUserInteractionEnabled?: boolean;
4479
+ draggable?: boolean;
4480
+ hidden?: boolean;
4481
+ layout?: Layout;
4482
+ uuid?: string;
4483
+ suppressEvents?: boolean;
4484
+ };
3162
4485
  initialize(): void;
4486
+ get anchorPoint(): Point;
4487
+ set anchorPoint(anchorPoint: Point);
4488
+ get zPosition(): number;
4489
+ set zPosition(zPosition: number);
3163
4490
  dispose(): void;
3164
4491
  /**
3165
4492
  * Duplicates a node using deep copy.
@@ -3197,6 +4524,16 @@ declare class Shape extends M2Node implements IDrawable, ShapeOptions {
3197
4524
  private warmupStrokedCircle;
3198
4525
  private warmupFilledRectangle;
3199
4526
  private warmupStrokedRectangle;
4527
+ get circleOfRadius(): number | undefined;
4528
+ set circleOfRadius(circleOfRadius: number | undefined);
4529
+ get rect(): RectOptions | undefined;
4530
+ set rect(rect: RectOptions | undefined);
4531
+ get cornerRadius(): number;
4532
+ set cornerRadius(cornerRadius: number | undefined);
4533
+ get lineWidth(): number | undefined;
4534
+ set lineWidth(lineWidth: number | undefined);
4535
+ get path(): M2Path | M2ColorfulPath | SvgStringPath | undefined;
4536
+ set path(path: M2Path | M2ColorfulPath | SvgStringPath | undefined);
3200
4537
  get fillColor(): RgbaColor;
3201
4538
  set fillColor(fillColor: RgbaColor);
3202
4539
  get strokeColor(): RgbaColor | undefined;
@@ -3213,6 +4550,131 @@ declare class Shape extends M2Node implements IDrawable, ShapeOptions {
3213
4550
  set strokeColorPaintNotAntialiased(value: Paint);
3214
4551
  }
3215
4552
 
4553
+ interface SoundPlayerOptions extends M2NodeOptions {
4554
+ /** Name of sound to play. Must have been previously loaded */
4555
+ soundName: string;
4556
+ }
4557
+
4558
+ declare class SoundPlayer extends M2Node implements SoundPlayerOptions {
4559
+ readonly type = M2NodeType.SoundPlayer;
4560
+ isDrawable: boolean;
4561
+ soundName: string;
4562
+ /**
4563
+ * Node for playing sounds.
4564
+ *
4565
+ * @param options - {@link SoundPlayerOptions}
4566
+ */
4567
+ constructor(options: SoundPlayerOptions);
4568
+ initialize(): void;
4569
+ dispose(): void;
4570
+ /**
4571
+ * Duplicates a node using deep copy.
4572
+ *
4573
+ * @remarks This is a deep recursive clone (node and children).
4574
+ * The uuid property of all duplicated nodes will be newly created,
4575
+ * because uuid must be unique.
4576
+ *
4577
+ * @param newName - optional name of the new, duplicated node. If not
4578
+ * provided, name will be the new uuid
4579
+ */
4580
+ duplicate(newName?: string): SoundPlayer;
4581
+ }
4582
+
4583
+ interface SoundRecorderOptions extends M2NodeOptions {
4584
+ /** Preferred MIME type to use for recording audio. `audio/webm` or `audio/mp4` is recommended. If omitted, it will use any MIME type supported by the device. */
4585
+ mimeType?: string;
4586
+ /** Additional MIME types to use for recording audio, in order of preference, if preferred type is not supported. `["audio/webm", "audio/mp4"]` is recommended. */
4587
+ backupMimeTypes?: Array<string>;
4588
+ /** Maximum duration, in milliseconds, to allow recording. If recording lasts longer than this duration, it will automatically be paused. This can be used to prevent excessively long recording and memory usage. */
4589
+ maximumDuration?: number;
4590
+ /** Additional audio constraints to be applied when requesting the audio device.
4591
+ * see https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
4592
+ * @remarks Use with caution. All kinds of constraints may not be supported
4593
+ * on all browsers, and specifying too restrictive constraints will result in
4594
+ * no available user audio device and an exception. Unusual constraints may
4595
+ * also result in an unexpected device being selected.
4596
+ * @example
4597
+ * audioTrackConstraints: {
4598
+ * channelCount: 1,
4599
+ * noiseSuppression: { ideal: true },
4600
+ * }
4601
+ * */
4602
+ audioTrackConstraints?: MediaTrackConstraints;
4603
+ }
4604
+
4605
+ interface SoundRecorderResults {
4606
+ /** The MIME type of the recorded audio, possibly including the codec. */
4607
+ mimeType: string;
4608
+ /** The ISO 8601 device timestamp when the recording began. */
4609
+ beginIso8601Timestamp: string;
4610
+ /** The ISO 8601 device timestamp when the recording ended. */
4611
+ endIso8601Timestamp: string;
4612
+ /** The duration of the recording in milliseconds. @remarks The duration may be different from the timestamp end minus begin times if the recording was paused. */
4613
+ duration: number;
4614
+ /** The settings of the audio tracks when the recording began. */
4615
+ audioTrackSettings?: Array<MediaTrackSettings>;
4616
+ /** The recorded audio as a base 64 string. */
4617
+ audioBase64: string;
4618
+ /** The recorded audio as a Blob. */
4619
+ audioBlob: Blob;
4620
+ }
4621
+
4622
+ declare class SoundRecorder extends M2Node implements Omit<SoundRecorderOptions, "backupMimeTypes"> {
4623
+ readonly type = M2NodeType.SoundRecorder;
4624
+ isDrawable: boolean;
4625
+ mimeType?: string;
4626
+ audioTrackConstraints?: MediaTrackConstraints;
4627
+ maximumDuration?: number;
4628
+ private _isRecording;
4629
+ private _isPaused;
4630
+ private mediaRecorder?;
4631
+ private audioChunks;
4632
+ private mediaTrackSettings?;
4633
+ private beginIso8601Timestamp?;
4634
+ private endIso8601Timestamp?;
4635
+ private timerUuid;
4636
+ /**
4637
+ * Node for recording sounds.
4638
+ *
4639
+ * @param options - {@link SoundRecorderOptions}
4640
+ */
4641
+ constructor(options?: SoundRecorderOptions);
4642
+ initialize(): void;
4643
+ start(): Promise<void>;
4644
+ stop(): Promise<SoundRecorderResults>;
4645
+ pause(): void;
4646
+ resume(): void;
4647
+ /** Is the `SoundRecorder` currently recording? */
4648
+ get isRecording(): boolean;
4649
+ /** Is the `SoundRecorder` currently paused? */
4650
+ get isPaused(): boolean;
4651
+ update(): void;
4652
+ /**
4653
+ * Returns an array of supported audio MIME types for MediaRecorder.
4654
+ *
4655
+ * @remarks Adapted from https://stackoverflow.com/a/68236494
4656
+ * License: https://creativecommons.org/licenses/by-sa/4.0/
4657
+ *
4658
+ * @returns
4659
+ */
4660
+ private getMediaRecorderSupportedAudioMimeTypes;
4661
+ private blobToBase64;
4662
+ private getMimeTypeWithoutCodecs;
4663
+ private getSupportedBackupMimeType;
4664
+ dispose(): void;
4665
+ /**
4666
+ * Duplicates a node using deep copy.
4667
+ *
4668
+ * @remarks This is a deep recursive clone (node and children).
4669
+ * The uuid property of all duplicated nodes will be newly created,
4670
+ * because uuid must be unique.
4671
+ *
4672
+ * @param newName - optional name of the new, duplicated node. If not
4673
+ * provided, name will be the new uuid
4674
+ */
4675
+ duplicate(newName?: string): SoundRecorder;
4676
+ }
4677
+
3216
4678
  interface SpriteOptions extends M2NodeOptions, DrawableOptions {
3217
4679
  /** Name of image to use for sprite. Must have been previously loaded */
3218
4680
  imageName?: string;
@@ -3221,11 +4683,8 @@ interface SpriteOptions extends M2NodeOptions, DrawableOptions {
3221
4683
  declare class Sprite extends M2Node implements IDrawable, SpriteOptions {
3222
4684
  readonly type = M2NodeType.Sprite;
3223
4685
  isDrawable: boolean;
3224
- anchorPoint: {
3225
- x: number;
3226
- y: number;
3227
- };
3228
- zPosition: number;
4686
+ private _anchorPoint;
4687
+ private _zPosition;
3229
4688
  private _imageName;
3230
4689
  private m2Image?;
3231
4690
  private _paint?;
@@ -3237,10 +4696,30 @@ declare class Sprite extends M2Node implements IDrawable, SpriteOptions {
3237
4696
  * @param options - {@link SpriteOptions}
3238
4697
  */
3239
4698
  constructor(options?: SpriteOptions);
4699
+ get completeNodeOptions(): {
4700
+ imageName: string;
4701
+ anchorPoint?: Point;
4702
+ zPosition?: number;
4703
+ name?: string;
4704
+ position?: Point;
4705
+ scale?: number;
4706
+ alpha?: number;
4707
+ zRotation?: number;
4708
+ isUserInteractionEnabled?: boolean;
4709
+ draggable?: boolean;
4710
+ hidden?: boolean;
4711
+ layout?: Layout;
4712
+ uuid?: string;
4713
+ suppressEvents?: boolean;
4714
+ };
3240
4715
  initialize(): void;
3241
4716
  dispose(): void;
3242
- set imageName(imageName: string);
3243
4717
  get imageName(): string;
4718
+ set imageName(imageName: string);
4719
+ get anchorPoint(): Point;
4720
+ set anchorPoint(anchorPoint: Point);
4721
+ get zPosition(): number;
4722
+ set zPosition(zPosition: number);
3244
4723
  private set paint(value);
3245
4724
  private get paint();
3246
4725
  /**
@@ -3257,6 +4736,18 @@ declare class Sprite extends M2Node implements IDrawable, SpriteOptions {
3257
4736
  update(): void;
3258
4737
  draw(canvas: Canvas): void;
3259
4738
  warmup(canvas: Canvas): void;
4739
+ /**
4740
+ * Draws a rectangle border around the image to indicate that a fallback
4741
+ * image is being used.
4742
+ *
4743
+ * @remarks The size of the rectangle is the same as the image, but because
4744
+ * the stroke width of the paint is wider than 1 pixel (see method
4745
+ * `configureImageLocalization()` in `ImageManager.ts`), the rectangle will
4746
+ * be larger than the image and thus be visible.
4747
+ *
4748
+ * @param canvas - CanvasKit canvas to draw on
4749
+ */
4750
+ private drawFallbackImageBorder;
3260
4751
  }
3261
4752
 
3262
4753
  interface StoryOptions {
@@ -3275,20 +4766,22 @@ declare class TextLine extends M2Node implements IDrawable, IText, TextLineOptio
3275
4766
  readonly type = M2NodeType.TextLine;
3276
4767
  isDrawable: boolean;
3277
4768
  isText: boolean;
3278
- zPosition: number;
3279
- anchorPoint: {
3280
- x: number;
3281
- y: number;
3282
- };
4769
+ private _zPosition;
4770
+ private _anchorPoint;
3283
4771
  private _text;
3284
4772
  private _fontName;
3285
4773
  private _fontColor;
3286
4774
  private _fontSize;
4775
+ private _interpolation;
4776
+ private _localize;
3287
4777
  private paint?;
3288
4778
  private font?;
3289
4779
  private typeface;
3290
- private _translatedText;
3291
- private missingTranslationPaint?;
4780
+ private tryMissingTranslationPaint;
4781
+ private textForDraw;
4782
+ private fontForDraw?;
4783
+ private localizedFontName;
4784
+ private localizedFontNames;
3292
4785
  /**
3293
4786
  * Single-line text rendered on the screen.
3294
4787
  *
@@ -3297,16 +4790,28 @@ declare class TextLine extends M2Node implements IDrawable, IText, TextLineOptio
3297
4790
  * @param options - {@link TextLineOptions}
3298
4791
  */
3299
4792
  constructor(options?: TextLineOptions);
3300
- get text(): string;
3301
- set text(text: string);
3302
- get translatedText(): string;
3303
- get fontName(): string | undefined;
3304
- set fontName(fontName: string | undefined);
3305
- get fontColor(): RgbaColor;
3306
- set fontColor(fontColor: RgbaColor);
3307
- get fontSize(): number;
3308
- set fontSize(fontSize: number);
3309
- update(): void;
4793
+ get completeNodeOptions(): {
4794
+ width: number;
4795
+ text?: string;
4796
+ fontName?: string;
4797
+ fontColor?: RgbaColor;
4798
+ fontSize?: number;
4799
+ interpolation?: StringInterpolationMap;
4800
+ localize?: boolean;
4801
+ anchorPoint?: Point;
4802
+ zPosition?: number;
4803
+ name?: string;
4804
+ position?: Point;
4805
+ scale?: number;
4806
+ alpha?: number;
4807
+ zRotation?: number;
4808
+ isUserInteractionEnabled?: boolean;
4809
+ draggable?: boolean;
4810
+ hidden?: boolean;
4811
+ layout?: Layout;
4812
+ uuid?: string;
4813
+ suppressEvents?: boolean;
4814
+ };
3310
4815
  initialize(): void;
3311
4816
  /**
3312
4817
  * Determines the M2Font object that needs to be ready in order to draw
@@ -3319,6 +4824,24 @@ declare class TextLine extends M2Node implements IDrawable, IText, TextLineOptio
3319
4824
  * @returns a M2Font object that is required for the TextLine
3320
4825
  */
3321
4826
  private getRequiredTextLineFont;
4827
+ private createFontPaint;
4828
+ private createFont;
4829
+ get text(): string;
4830
+ set text(text: string);
4831
+ get fontName(): string | undefined;
4832
+ set fontName(fontName: string | undefined);
4833
+ get fontColor(): RgbaColor;
4834
+ set fontColor(fontColor: RgbaColor);
4835
+ get fontSize(): number;
4836
+ set fontSize(fontSize: number);
4837
+ get interpolation(): StringInterpolationMap;
4838
+ set interpolation(interpolation: StringInterpolationMap);
4839
+ get localize(): boolean;
4840
+ set localize(localize: boolean);
4841
+ get anchorPoint(): Point;
4842
+ set anchorPoint(anchorPoint: Point);
4843
+ get zPosition(): number;
4844
+ set zPosition(zPosition: number);
3322
4845
  dispose(): void;
3323
4846
  /**
3324
4847
  * Duplicates a node using deep copy.
@@ -3331,6 +4854,7 @@ declare class TextLine extends M2Node implements IDrawable, IText, TextLineOptio
3331
4854
  * provided, name will be the new uuid
3332
4855
  */
3333
4856
  duplicate(newName?: string): TextLine;
4857
+ update(): void;
3334
4858
  draw(canvas: Canvas): void;
3335
4859
  warmup(canvas: Canvas): void;
3336
4860
  }
@@ -3447,6 +4971,15 @@ declare class Timer {
3447
4971
 
3448
4972
  declare class Uuid {
3449
4973
  static generate(): string;
4974
+ /**
4975
+ * Tests if a string is a valid UUID.
4976
+ *
4977
+ * @remarks Will match UUID versions 1 through 8, plus the nil UUID.
4978
+ *
4979
+ * @param uuid - the string to test
4980
+ * @returns true if the string is a valid UUID
4981
+ */
4982
+ static isValid(uuid: string | undefined | null): boolean;
3450
4983
  }
3451
4984
 
3452
4985
  declare class WebColors {
@@ -3611,4 +5144,4 @@ declare class WebGlInfo {
3611
5144
  static dispose(): void;
3612
5145
  }
3613
5146
 
3614
- export { Action, type Activity, type ActivityCallbacks, type ActivityEvent, type ActivityEventListener, type ActivityKeyValueData, type ActivityLifecycleEvent, type ActivityResultsEvent, ActivityType, type BrowserImage, type CallbackOptions, CanvasKitHelpers, ColorfulMutablePath, Composite, type CompositeOptions, Constants, ConstraintType, type Constraints, CustomAction, type CustomActionOptions, type DefaultParameter, Dimensions, type DrawableOptions, type EasingFunction, Easings, Equals, FadeAlphaAction, type FadeAlphaActionOptions, type FontAsset, type FontData, FontManager, Game, type GameData, type GameEvent, type GameOptions, type GameParameters, GlobalVariables, GroupAction, I18n, type IDataStore, type IDrawable, type IText, ImageManager, Label, LabelHorizontalAlignmentMode, type LabelOptions, type Layout, LayoutConstraint, LegacyTimer, type M2ColorfulPath, type M2DragEvent, type M2Event, type M2EventListener, M2EventType, type M2Image, M2ImageStatus, M2Node, type M2NodeEvent, type M2NodeEventListener, type M2NodeOptions, M2NodeType, type M2Path, type M2PointerEvent, M2c2KitHelpers, MoveAction, type MoveActionOptions, MutablePath, NoneTransition, type Plugin, type PluginEvent, type Point, RandomDraws, type RectOptions, type RgbaColor, RotateAction, ScaleAction, type ScaleActionOptions, Scene, type SceneOptions, SceneTransition, SequenceAction, Shape, type ShapeOptions, ShapeType, type Size, SlideTransition, type SlideTransitionOptions, Sprite, type SpriteOptions, Story, type StoryOptions, type TapEvent, TextLine, type TextLineOptions, type TextOptions, Timer, Transition, TransitionDirection, TransitionType, type Translations, type TrialData, type TrialSchema, Uuid, WaitAction, type WaitActionOptions, WebColors, WebGlInfo, handleInterfaceOptions };
5147
+ export { Action, type Activity, type ActivityCallbacks, type ActivityEvent, type ActivityEventListener, type ActivityKeyValueData, type ActivityLifecycleEvent, type ActivityResultsEvent, ActivityType, type BrowserImage, type BrowserImageDataReadyEvent, type CallbackOptions, CanvasKitHelpers, ColorfulMutablePath, Composite, type CompositeEvent, type CompositeOptions, Constants, ConstraintType, type Constraints, CustomAction, type CustomActionOptions, type DefaultParameter, Dimensions, type DomPointerDownEvent, type DrawableOptions, type EasingFunction, Easings, Equal, Equals, EventStore, EventStoreMode, FadeAlphaAction, type FadeAlphaActionOptions, type FontAsset, type FontData, FontManager, Game, type GameData, type GameEvent, type GameOptions, type GameParameters, type GlobalVariables, GroupAction, I18n, type I18nDataReadyEvent, type IDataStore, type IDrawable, type IText, ImageManager, Label, LabelHorizontalAlignmentMode, type LabelOptions, type Layout, LayoutConstraint, LegacyTimer, type LocaleSvg, type M2ColorfulPath, type M2DragEvent, type M2Event, type M2EventListener, M2EventType, type M2Image, M2ImageStatus, M2Node, type M2NodeAddChildEvent, type M2NodeConstructor, type M2NodeEvent, type M2NodeEventListener, M2NodeFactory, type M2NodeNewEvent, type M2NodeOptions, type M2NodePropertyChangeEvent, type M2NodeRemoveChildEvent, M2NodeType, type M2Path, type M2PointerEvent, type M2Sound, M2SoundStatus, M2c2KitHelpers, MoveAction, type MoveActionOptions, MutablePath, NoneTransition, PlayAction, type PlayActionOptions, type Plugin, type PluginEvent, type Point, RandomDraws, type RectOptions, RepeatAction, RepeatForeverAction, type RgbaColor, RotateAction, ScaleAction, type ScaleActionOptions, Scene, type SceneOptions, type ScenePresentEvent, SceneTransition, SequenceAction, Shape, type ShapeOptions, ShapeType, type Size, SlideTransition, type SlideTransitionOptions, type SoundAsset, SoundManager, SoundPlayer, type SoundPlayerOptions, SoundRecorder, type SoundRecorderOptions, type SoundRecorderResults, Sprite, type SpriteOptions, Story, type StoryOptions, type StringInterpolationMap, type TapEvent, type TextAndFont, TextLine, type TextLineOptions, type TextLocalizationResult, type TextOptions, type TextWithFontCustomization, Timer, Transition, TransitionDirection, TransitionType, type Translation, type TranslationConfiguration, type TranslationOptions, type TrialData, type TrialSchema, Uuid, WaitAction, type WaitActionOptions, WebColors, WebGlInfo, handleInterfaceOptions };