@m2c2kit/addons 0.3.14 → 0.3.15

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.js CHANGED
@@ -260,6 +260,8 @@ class Button extends Composite {
260
260
  this.fontSize = 20;
261
261
  this._text = "";
262
262
  this._fontColor = WebColors.White;
263
+ this._interpolation = {};
264
+ this._localize = true;
263
265
  if (options.text) {
264
266
  this.text = options.text;
265
267
  }
@@ -269,6 +271,12 @@ class Button extends Composite {
269
271
  if (options.cornerRadius !== void 0) {
270
272
  this.cornerRadius = options.cornerRadius;
271
273
  }
274
+ if (options.fontName) {
275
+ this.fontName = options.fontName;
276
+ }
277
+ if (options.fontNames) {
278
+ this.fontNames = options.fontNames;
279
+ }
272
280
  if (options.fontSize !== void 0) {
273
281
  this.fontSize = options.fontSize;
274
282
  }
@@ -278,6 +286,12 @@ class Button extends Composite {
278
286
  if (options.backgroundColor) {
279
287
  this.backgroundColor = options.backgroundColor;
280
288
  }
289
+ if (options.interpolation) {
290
+ this.interpolation = options.interpolation;
291
+ }
292
+ if (options.localize !== void 0) {
293
+ this.localize = options.localize;
294
+ }
281
295
  }
282
296
  initialize() {
283
297
  this.removeAllChildren();
@@ -299,6 +313,10 @@ class Button extends Composite {
299
313
  this.addChild(buttonRectangle);
300
314
  const buttonLabel = new Label({
301
315
  text: this.text,
316
+ localize: this.localize,
317
+ interpolation: this.interpolation,
318
+ fontName: this.fontName,
319
+ fontNames: this.fontNames,
302
320
  fontSize: this.fontSize,
303
321
  fontColor: this.fontColor
304
322
  });
@@ -329,6 +347,35 @@ class Button extends Composite {
329
347
  this._fontColor = fontColor;
330
348
  this.needsInitialization = true;
331
349
  }
350
+ get fontName() {
351
+ return this._fontName;
352
+ }
353
+ set fontName(fontName) {
354
+ this._fontName = fontName;
355
+ this.needsInitialization = true;
356
+ }
357
+ get fontNames() {
358
+ return this._fontNames;
359
+ }
360
+ set fontNames(fontNames) {
361
+ this._fontNames = fontNames;
362
+ this.needsInitialization = true;
363
+ }
364
+ get interpolation() {
365
+ return this._interpolation;
366
+ }
367
+ set interpolation(interpolation) {
368
+ this._interpolation = interpolation;
369
+ Object.freeze(this._interpolation);
370
+ this.needsInitialization = true;
371
+ }
372
+ get localize() {
373
+ return this._localize;
374
+ }
375
+ set localize(localize) {
376
+ this._localize = localize;
377
+ this.needsInitialization = true;
378
+ }
332
379
  /**
333
380
  * Duplicates a node using deep copy.
334
381
  *
@@ -348,7 +395,11 @@ class Button extends Composite {
348
395
  cornerRadius: this.cornerRadius,
349
396
  backgroundColor: this.backgroundColor,
350
397
  fontColor: this.fontColor,
351
- name: newName
398
+ name: newName,
399
+ localize: this.localize,
400
+ interpolation: JSON.parse(JSON.stringify(this.interpolation)),
401
+ fontName: this.fontName,
402
+ fontNames: JSON.parse(JSON.stringify(this.fontNames))
352
403
  });
353
404
  if (this.children.length > 0) {
354
405
  dest.children = this.children.map((child) => {
@@ -1198,8 +1249,12 @@ class VirtualKeyboard extends Composite {
1198
1249
  */
1199
1250
  constructor(options) {
1200
1251
  super(options);
1252
+ this.compositeType = "VirtualKeyboard";
1201
1253
  this.rowsConfiguration = new Array();
1202
1254
  this.shiftActivated = false;
1255
+ this.keyShapes = new Array();
1256
+ // VirtualKeyboard defaults to being user interactive.
1257
+ this._isUserInteractionEnabled = true;
1203
1258
  this.size = options.size;
1204
1259
  this.position = options.position ?? { x: 0, y: 0 };
1205
1260
  this.keyboardHorizontalPaddingPercent = options.keyboardHorizontalPaddingPercent ?? 0.02;
@@ -1381,6 +1436,7 @@ class VirtualKeyboard extends Composite {
1381
1436
  const keyboardHorizontalPadding = (this.keyboardHorizontalPaddingPercent ?? 0.02) * this.size.width;
1382
1437
  const keyBoxHeight = (this.size.height - 2 * keyboardVerticalPadding) / rows.length;
1383
1438
  const keyBoxWidth = (this.size.width - 2 * keyboardHorizontalPadding) / this.keysPerRow;
1439
+ this.keyShapes = [];
1384
1440
  for (let r = 0; r < rows.length; r++) {
1385
1441
  const row = rows[r];
1386
1442
  const rowSumKeyWidths = row.reduce(
@@ -1419,9 +1475,10 @@ class VirtualKeyboard extends Composite {
1419
1475
  cornerRadius: 4,
1420
1476
  fillColor: this.keyColor,
1421
1477
  lineWidth: 0,
1422
- isUserInteractionEnabled: true
1478
+ isUserInteractionEnabled: this.isUserInteractionEnabled
1423
1479
  });
1424
1480
  keyBox.addChild(keyShape);
1481
+ this.keyShapes.push(keyShape);
1425
1482
  keyShape.onTapUp((tapEvent) => {
1426
1483
  let keyAsString = "";
1427
1484
  if (!key.isShift) {
@@ -1616,6 +1673,21 @@ class VirtualKeyboard extends Composite {
1616
1673
  }
1617
1674
  this.eventListeners.push(eventListener);
1618
1675
  }
1676
+ /**
1677
+ * Does the `VirtualKeyboard` respond to user events? Default is true.
1678
+ */
1679
+ get isUserInteractionEnabled() {
1680
+ return this._isUserInteractionEnabled;
1681
+ }
1682
+ /**
1683
+ * Does the `VirtualKeyboard` respond to user events? Default is true.
1684
+ */
1685
+ set isUserInteractionEnabled(isUserInteractionEnabled) {
1686
+ this._isUserInteractionEnabled = isUserInteractionEnabled;
1687
+ this.keyShapes.forEach((keyShape) => {
1688
+ keyShape.isUserInteractionEnabled = isUserInteractionEnabled;
1689
+ });
1690
+ }
1619
1691
  update() {
1620
1692
  super.update();
1621
1693
  }
@@ -1629,7 +1701,7 @@ class VirtualKeyboard extends Composite {
1629
1701
  });
1630
1702
  }
1631
1703
  duplicate(newName) {
1632
- throw new Error("Method not implemented.");
1704
+ throw new Error(`Method not implemented. ${newName}`);
1633
1705
  }
1634
1706
  }
1635
1707
 
@@ -1981,7 +2053,462 @@ class CountdownScene extends Scene {
1981
2053
  }
1982
2054
  }
1983
2055
 
1984
- console.log("\u26AA @m2c2kit/addons version 0.3.14 (ebbdc605)");
2056
+ class LocalePicker extends Composite {
2057
+ /**
2058
+ * An icon and dialog box for selecting a locale from a list of options.
2059
+ *
2060
+ * @remarks This composite node is composed of a dialog box that appears
2061
+ * when the user taps a globe icon. Typically, the `LocalePicker` will be
2062
+ * added as a free node to the game so that it exists independently of
2063
+ * the game's scenes. The dialog box contains a list of locales that the
2064
+ * user can choose from. By default, this list is populated with the locales
2065
+ * in the game's `Translation` object. When the user selects a locale, the
2066
+ * dialog box disappears and the locale is set as the game's current locale.
2067
+ * The dialog box is automatically sized to fit the number of locale
2068
+ * options.
2069
+ *
2070
+ * @example
2071
+ * let localePicker: LocalePicker;
2072
+ * if (game.getParameter<boolean>("show_locale_picker")) {
2073
+ * localePicker = new LocalePicker();
2074
+ * game.addFreeNode(localePicker);
2075
+ * }
2076
+ *
2077
+ * @param options - {@link LocalePickerOptions}
2078
+ */
2079
+ constructor(options) {
2080
+ super(options);
2081
+ this.compositeType = "LocalePicker";
2082
+ this.zPosition = Number.MAX_VALUE;
2083
+ this.DEFAULT_FONT_SIZE = 24;
2084
+ this.automaticallyChangeLocale = true;
2085
+ this._localeOptions = new Array();
2086
+ this._backgroundColor = WebColors.White;
2087
+ this._fontSize = this.DEFAULT_FONT_SIZE;
2088
+ this._fontColor = WebColors.Black;
2089
+ this._cornerRadius = 8;
2090
+ this._overlayAlpha = 0.5;
2091
+ this._icon = {
2092
+ // public domain SVG from https://commons.wikimedia.org/wiki/File:Globe_icon.svg
2093
+ svgString: `<svg xmlns="http://www.w3.org/2000/svg" width="420" height="420" stroke="#000" fill="none"><path stroke-width="26" d="M209 15a195 195 0 1 0 2 0z"/><path stroke-width="18" d="M210 15v390m195-195H15M59 90a260 260 0 0 0 302 0m0 240a260 260 0 0 0-302 0M195 20a250 250 0 0 0 0 382m30 0a250 250 0 0 0 0-382"/></svg>`,
2094
+ height: 32,
2095
+ width: 32
2096
+ };
2097
+ this._iconPosition = { x: 32, y: 32 };
2098
+ /**
2099
+ * Wrap displayed locale in double angle quotes if it is the current locale.
2100
+ * Note: Although the code editor will allow us to enter almost any
2101
+ * unicode character, it will not render correctly if the font does
2102
+ * not support the character. Thus, be careful to use characters that
2103
+ * are supported by the font. For example, check a page like
2104
+ * https://www.fontspace.com/roboto-font-f13281 to see which characters
2105
+ * are supported by Roboto Regular, which is often the default font in
2106
+ * m2c2kit. Emoji or checkmarks like ✓ are not in Roboto Regular!
2107
+ */
2108
+ this.LEFT_SELECTION_INDICATOR = "\xAB";
2109
+ this.RIGHT_SELECTION_INDICATOR = "\xBB";
2110
+ if (!options) {
2111
+ return;
2112
+ }
2113
+ if (options.localeOptions) {
2114
+ this.localeOptions = options.localeOptions;
2115
+ }
2116
+ if (options.backgroundColor) {
2117
+ this.backgroundColor = options.backgroundColor;
2118
+ }
2119
+ if (options.overlayAlpha !== void 0) {
2120
+ this.overlayAlpha = options.overlayAlpha;
2121
+ }
2122
+ if (options.fontSize !== void 0) {
2123
+ this.fontSize = options.fontSize;
2124
+ }
2125
+ if (options.fontColor) {
2126
+ this.fontColor = options.fontColor;
2127
+ }
2128
+ if (options.cornerRadius) {
2129
+ this.cornerRadius = options.cornerRadius;
2130
+ }
2131
+ if (options.currentLocale !== void 0) {
2132
+ this.currentLocale = options.currentLocale;
2133
+ }
2134
+ if (options.icon) {
2135
+ this.icon = options.icon;
2136
+ }
2137
+ if (options.automaticallyChangeLocale !== void 0) {
2138
+ this.automaticallyChangeLocale = options.automaticallyChangeLocale;
2139
+ }
2140
+ }
2141
+ /**
2142
+ * Executes a callback when the user selects a locale.
2143
+ *
2144
+ * @param callback - function to execute
2145
+ * @param options - {@link CallbackOptions}
2146
+ */
2147
+ onResult(callback, options) {
2148
+ const eventListener = {
2149
+ type: M2EventType.CompositeCustom,
2150
+ compositeType: "LocalePickerResult",
2151
+ nodeUuid: this.uuid,
2152
+ callback
2153
+ };
2154
+ if (options?.replaceExisting) {
2155
+ this.eventListeners = this.eventListeners.filter(
2156
+ (listener) => !(listener.nodeUuid === eventListener.nodeUuid && listener.type === "LocalePickerResult")
2157
+ );
2158
+ }
2159
+ this.eventListeners.push(eventListener);
2160
+ }
2161
+ initialize() {
2162
+ if (this.currentLocale === void 0) {
2163
+ this.currentLocale = this.game.i18n?.locale;
2164
+ }
2165
+ if (this.localeOptions.length === 0) {
2166
+ const locales = Object.keys(this.game.i18n?.translation || {});
2167
+ locales.filter((locale) => locale !== "configuration").forEach((locale) => {
2168
+ this.localeOptions.push({
2169
+ text: this.game.i18n?.translation[locale].localeName || locale,
2170
+ locale,
2171
+ svg: this.game.i18n?.translation[locale].localeSvg
2172
+ });
2173
+ });
2174
+ }
2175
+ if (this.localeOptions.length === 0) {
2176
+ throw new Error("No locales available for LocalePicker");
2177
+ }
2178
+ this.children.filter((child) => child.name !== "localePickerIcon").forEach((child) => this.removeChild(child));
2179
+ this.game.imageManager.loadImages([
2180
+ {
2181
+ imageName: "__localePickerIcon",
2182
+ svgString: this.icon.svgString,
2183
+ height: this.icon.height,
2184
+ width: this.icon.width
2185
+ }
2186
+ ]);
2187
+ if (!this.iconSprite) {
2188
+ this.iconSprite = new Sprite({
2189
+ // name is how we refer to this sprite, as a node.
2190
+ name: "localePickerIcon",
2191
+ // imageName is the loaded image that we can assign to the sprite
2192
+ imageName: "__localePickerIcon",
2193
+ position: this.iconPosition,
2194
+ isUserInteractionEnabled: true
2195
+ });
2196
+ this.addChild(this.iconSprite);
2197
+ this.iconSprite.onTapDown(() => {
2198
+ this.setDialogVisibility(true);
2199
+ });
2200
+ }
2201
+ const overlay = new Shape({
2202
+ rect: {
2203
+ width: Globals.canvasCssWidth,
2204
+ height: Globals.canvasCssHeight,
2205
+ x: Globals.canvasCssWidth / 2,
2206
+ y: Globals.canvasCssHeight / 2
2207
+ },
2208
+ fillColor: [0, 0, 0, this.overlayAlpha],
2209
+ zPosition: -1,
2210
+ isUserInteractionEnabled: true,
2211
+ hidden: true
2212
+ });
2213
+ overlay.onTapDown((e) => {
2214
+ e.handled = true;
2215
+ if (this.eventListeners.length > 0) {
2216
+ this.eventListeners.filter((listener) => listener.type === "LocalePickerResult").forEach((listener) => {
2217
+ const languagePickerEvent = {
2218
+ type: "LocalePickerResult",
2219
+ target: this,
2220
+ handled: false,
2221
+ result: {
2222
+ locale: void 0
2223
+ }
2224
+ };
2225
+ listener.callback(languagePickerEvent);
2226
+ });
2227
+ }
2228
+ this.setDialogVisibility(false);
2229
+ });
2230
+ this.addChild(overlay);
2231
+ const lineHeight = this.fontSize / this.DEFAULT_FONT_SIZE * 50;
2232
+ const dialogHeight = this.localeOptions.length * lineHeight;
2233
+ const dialogWidth = Globals.canvasCssWidth / 2;
2234
+ const sceneCenter = {
2235
+ x: Globals.canvasCssWidth / 2,
2236
+ y: Globals.canvasCssHeight / 2
2237
+ };
2238
+ const localeDialog = new Shape({
2239
+ rect: {
2240
+ width: dialogWidth,
2241
+ height: dialogHeight,
2242
+ x: sceneCenter.x,
2243
+ y: sceneCenter.y
2244
+ },
2245
+ cornerRadius: this.cornerRadius,
2246
+ fillColor: this.backgroundColor,
2247
+ isUserInteractionEnabled: true,
2248
+ hidden: true
2249
+ });
2250
+ localeDialog.onTapDown((e) => {
2251
+ e.handled = true;
2252
+ });
2253
+ this.addChild(localeDialog);
2254
+ for (let i = 0; i < this.localeOptions.length; i++) {
2255
+ const localeOption = this.localeOptions[i];
2256
+ if (!localeOption.svg) {
2257
+ let labelText = localeOption.text;
2258
+ if (this.currentLocale === localeOption.locale) {
2259
+ labelText = `${this.LEFT_SELECTION_INDICATOR} ${labelText} ${this.RIGHT_SELECTION_INDICATOR}`;
2260
+ }
2261
+ const text = new Label({
2262
+ text: labelText,
2263
+ fontSize: this.fontSize,
2264
+ fontColor: this.fontColor,
2265
+ position: {
2266
+ x: sceneCenter.x,
2267
+ y: sceneCenter.y + i * lineHeight - dialogHeight / 2 + lineHeight / 2
2268
+ },
2269
+ isUserInteractionEnabled: true,
2270
+ zPosition: 1,
2271
+ hidden: true,
2272
+ // do not localize the text of each language option
2273
+ localize: false
2274
+ });
2275
+ text.onTapDown((e) => {
2276
+ this.handleLocaleSelection(e, localeOption);
2277
+ });
2278
+ this.addChild(text);
2279
+ } else {
2280
+ this.game.imageManager.loadImages([
2281
+ {
2282
+ imageName: localeOption.text,
2283
+ svgString: localeOption.svg.svgString,
2284
+ height: localeOption.svg.height,
2285
+ width: localeOption.svg.width
2286
+ }
2287
+ ]);
2288
+ const localeSprite = new Sprite({
2289
+ imageName: localeOption.text,
2290
+ position: {
2291
+ x: sceneCenter.x,
2292
+ y: sceneCenter.y + i * lineHeight - dialogHeight / 2 + lineHeight / 2
2293
+ },
2294
+ isUserInteractionEnabled: true,
2295
+ zPosition: 1,
2296
+ hidden: true
2297
+ });
2298
+ this.addChild(localeSprite);
2299
+ if (this.currentLocale === localeOption.locale) {
2300
+ const leftSelectionIndicator = new Label({
2301
+ text: this.LEFT_SELECTION_INDICATOR,
2302
+ fontSize: this.fontSize,
2303
+ fontColor: this.fontColor,
2304
+ position: {
2305
+ x: sceneCenter.x - localeOption.svg.width / 2,
2306
+ y: sceneCenter.y + i * lineHeight - dialogHeight / 2 + lineHeight / 2
2307
+ },
2308
+ hidden: true,
2309
+ // do not localize the left selection indicator
2310
+ localize: false
2311
+ });
2312
+ this.addChild(leftSelectionIndicator);
2313
+ const rightSelectionIndicator = new Label({
2314
+ text: this.RIGHT_SELECTION_INDICATOR,
2315
+ fontSize: this._fontSize,
2316
+ fontColor: this.fontColor,
2317
+ position: {
2318
+ x: sceneCenter.x + localeOption.svg.width / 2,
2319
+ y: sceneCenter.y + i * lineHeight - dialogHeight / 2 + lineHeight / 2
2320
+ },
2321
+ hidden: true,
2322
+ // do not localize the left selection indicator
2323
+ localize: false
2324
+ });
2325
+ this.addChild(rightSelectionIndicator);
2326
+ }
2327
+ localeSprite.onTapDown((e) => {
2328
+ this.handleLocaleSelection(e, localeOption);
2329
+ });
2330
+ }
2331
+ }
2332
+ this.needsInitialization = false;
2333
+ }
2334
+ handleLocaleSelection(e, localeOption) {
2335
+ e.handled = true;
2336
+ if (this.eventListeners.length > 0) {
2337
+ this.eventListeners.filter(
2338
+ (listener) => listener.type === M2EventType.CompositeCustom && listener.compositeType === "LocalePickerResult" && listener.nodeUuid == this.uuid
2339
+ ).forEach((listener) => {
2340
+ const languagePickerEvent = {
2341
+ type: M2EventType.CompositeCustom,
2342
+ compositeType: "LocalePickerResult",
2343
+ target: this,
2344
+ handled: false,
2345
+ result: {
2346
+ locale: localeOption.locale
2347
+ }
2348
+ };
2349
+ listener.callback(languagePickerEvent);
2350
+ });
2351
+ }
2352
+ this.setDialogVisibility(false);
2353
+ if (this.automaticallyChangeLocale) {
2354
+ this.game.i18n?.switchToLocale(localeOption.locale);
2355
+ this.currentLocale = localeOption.locale;
2356
+ }
2357
+ }
2358
+ setDialogVisibility(visible) {
2359
+ this.children.filter((child) => child.name !== "localePickerIcon").forEach((child) => {
2360
+ child.hidden = !visible;
2361
+ });
2362
+ }
2363
+ get backgroundColor() {
2364
+ return this._backgroundColor;
2365
+ }
2366
+ set backgroundColor(backgroundColor) {
2367
+ this._backgroundColor = backgroundColor;
2368
+ this.needsInitialization = true;
2369
+ }
2370
+ get fontSize() {
2371
+ return this._fontSize;
2372
+ }
2373
+ set fontSize(fontSize) {
2374
+ this._fontSize = fontSize;
2375
+ this.needsInitialization = true;
2376
+ }
2377
+ get fontColor() {
2378
+ return this._fontColor;
2379
+ }
2380
+ set fontColor(fontColor) {
2381
+ this._fontColor = fontColor;
2382
+ this.needsInitialization = true;
2383
+ }
2384
+ get cornerRadius() {
2385
+ return this._cornerRadius;
2386
+ }
2387
+ set cornerRadius(cornerRadius) {
2388
+ this._cornerRadius = cornerRadius;
2389
+ this.needsInitialization = true;
2390
+ }
2391
+ get overlayAlpha() {
2392
+ return this._overlayAlpha;
2393
+ }
2394
+ set overlayAlpha(alpha) {
2395
+ this._overlayAlpha = alpha;
2396
+ this.needsInitialization = true;
2397
+ }
2398
+ get icon() {
2399
+ const localePicker = this;
2400
+ return {
2401
+ get svgString() {
2402
+ return localePicker._icon.svgString;
2403
+ },
2404
+ set svgString(svgString) {
2405
+ localePicker._icon.svgString = svgString;
2406
+ localePicker.needsInitialization = true;
2407
+ },
2408
+ get imageName() {
2409
+ return localePicker._icon.imageName;
2410
+ },
2411
+ set imageName(imageName) {
2412
+ localePicker._icon.imageName = imageName;
2413
+ localePicker.needsInitialization = true;
2414
+ },
2415
+ get height() {
2416
+ return localePicker._icon.height;
2417
+ },
2418
+ set height(height) {
2419
+ localePicker._icon.height = height;
2420
+ localePicker.needsInitialization = true;
2421
+ },
2422
+ get width() {
2423
+ return localePicker._icon.width;
2424
+ },
2425
+ set width(width) {
2426
+ localePicker._icon.width = width;
2427
+ localePicker.needsInitialization = true;
2428
+ }
2429
+ };
2430
+ }
2431
+ set icon(icon) {
2432
+ this._icon = icon;
2433
+ this.needsInitialization = true;
2434
+ }
2435
+ get iconPosition() {
2436
+ const localePicker = this;
2437
+ return {
2438
+ get x() {
2439
+ return localePicker._iconPosition.x;
2440
+ },
2441
+ set x(x) {
2442
+ localePicker._iconPosition.x = x;
2443
+ if (localePicker.iconSprite) {
2444
+ localePicker.iconSprite.position = localePicker._iconPosition;
2445
+ }
2446
+ localePicker.needsInitialization = true;
2447
+ },
2448
+ get y() {
2449
+ return localePicker._iconPosition.y;
2450
+ },
2451
+ set y(y) {
2452
+ localePicker._iconPosition.y = y;
2453
+ if (localePicker.iconSprite) {
2454
+ localePicker.iconSprite.position = localePicker._iconPosition;
2455
+ }
2456
+ localePicker.needsInitialization = true;
2457
+ }
2458
+ };
2459
+ }
2460
+ set iconPosition(position) {
2461
+ this._iconPosition = position;
2462
+ if (this.iconSprite) {
2463
+ this.iconSprite.position = position;
2464
+ }
2465
+ this.needsInitialization = true;
2466
+ }
2467
+ get localeOptions() {
2468
+ return this._localeOptions;
2469
+ }
2470
+ set localeOptions(options) {
2471
+ this._localeOptions = options;
2472
+ this.needsInitialization = true;
2473
+ }
2474
+ get currentLocale() {
2475
+ return this._currentLocale;
2476
+ }
2477
+ set currentLocale(locale) {
2478
+ if (locale === this.currentLocale) {
2479
+ return;
2480
+ }
2481
+ this._currentLocale = locale;
2482
+ this.needsInitialization = true;
2483
+ }
2484
+ update() {
2485
+ super.update();
2486
+ }
2487
+ draw(canvas) {
2488
+ super.drawChildren(canvas);
2489
+ }
2490
+ warmup(canvas) {
2491
+ this.initialize();
2492
+ this.children.filter((child) => child.isDrawable).forEach((child) => {
2493
+ child.warmup(canvas);
2494
+ });
2495
+ }
2496
+ /**
2497
+ * Duplicates a node using deep copy.
2498
+ *
2499
+ * @remarks This is a deep recursive clone (node and children).
2500
+ * The uuid property of all duplicated nodes will be newly created,
2501
+ * because uuid must be unique.
2502
+ *
2503
+ * @param newName - optional name of the new, duplicated node. If not
2504
+ * provided, name will be the new uuid
2505
+ */
2506
+ duplicate(newName) {
2507
+ throw new Error(`duplicate not implemented. ${newName}`);
2508
+ }
2509
+ }
2510
+
2511
+ console.log("\u26AA @m2c2kit/addons version 0.3.15 (b3a70752)");
1985
2512
 
1986
- export { Button, CountdownScene, Dialog, DialogResult, DrawPad, DrawPadEventType, DrawPadItemEventType, Grid, Instructions, VirtualKeyboard };
2513
+ export { Button, CountdownScene, Dialog, DialogResult, DrawPad, DrawPadEventType, DrawPadItemEventType, Grid, Instructions, LocalePicker, VirtualKeyboard };
1987
2514
  //# sourceMappingURL=index.js.map