@vpmedia/phaser 1.62.0 → 1.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @vpmedia/phaser
2
2
 
3
- [![npm version](https://badge.fury.io/js/@vpmedia%2Fphaser.svg?v=1.62.0)](https://badge.fury.io/js/@vpmedia%2Fphaser)
3
+ [![npm version](https://badge.fury.io/js/@vpmedia%2Fphaser.svg?v=1.63.0)](https://badge.fury.io/js/@vpmedia%2Fphaser)
4
4
  [![Node.js CI](https://github.com/vpmedia/phaser/actions/workflows/ci.yml/badge.svg)](https://github.com/vpmedia/phaser/actions/workflows/ci.yml)
5
5
 
6
6
  @vpmedia/phaser is the modern ECMAScript port of the popular Phaser game engine v2.6.2.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpmedia/phaser",
3
- "version": "1.62.0",
3
+ "version": "1.63.0",
4
4
  "description": "@vpmedia/phaser is the modern ECMAScript port of the popular Phaser game engine v2.6.2",
5
5
  "author": "Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)",
6
6
  "license": "MIT",
@@ -148,7 +148,7 @@ export class Game {
148
148
  this.canvas.addEventListener('webglcontextlost', this.contextLostBinded, false);
149
149
  this.canvas.addEventListener('webglcontextrestored', this.contextRestoredBinded, false);
150
150
  isWebGlReady = true;
151
- } catch (e) {
151
+ } catch (error) {
152
152
  isWebGlReady = false;
153
153
  if (window.PhaserRegistry?.GL_PROGRAM_INFO_LOG) {
154
154
  this.logger.warn('WebGL program info', { log: window.PhaserRegistry.GL_PROGRAM_INFO_LOG });
@@ -156,7 +156,7 @@ export class Game {
156
156
  if (window.PhaserRegistry?.GL_SHADER_INFO_LOG) {
157
157
  this.logger.warn('WebGL shader info', { log: window.PhaserRegistry.GL_SHADER_INFO_LOG });
158
158
  }
159
- this.exceptionHandler(e);
159
+ this.exceptionHandler(error);
160
160
  }
161
161
  }
162
162
  if (!isWebGlReady) {
@@ -413,7 +413,7 @@ export class Loader {
413
413
  let xml = null;
414
414
  try {
415
415
  json = JSON.parse(atlasData);
416
- } catch (e) {
416
+ } catch (error) {
417
417
  xml = this.parseXml(atlasData);
418
418
  }
419
419
  if (!xml && !json) {
@@ -846,13 +846,13 @@ export class Loader {
846
846
  }
847
847
  }
848
848
  return onload.call(scope, file, xhr);
849
- } catch (e) {
849
+ } catch (error) {
850
850
  // If this was the last file in the queue and an error is thrown in the create method
851
851
  // then it's caught here, so be sure we don't carry on processing it
852
852
  if (!scope.hasLoaded) {
853
- scope.asyncComplete(file, e.message || 'Exception');
853
+ scope.asyncComplete(file, error.message || 'Exception');
854
854
  } else {
855
- scope.game.exceptionHandler(e);
855
+ scope.game.exceptionHandler(error);
856
856
  }
857
857
  }
858
858
  return null;
@@ -866,11 +866,11 @@ export class Loader {
866
866
  } else {
867
867
  try {
868
868
  return onerror.call(scope, file, xhr);
869
- } catch (e) {
869
+ } catch (error) {
870
870
  if (!scope.hasLoaded) {
871
- scope.asyncComplete(file, e.message || 'Exception');
871
+ scope.asyncComplete(file, error.message || 'Exception');
872
872
  } else {
873
- scope.game.exceptionHandler(e);
873
+ scope.game.exceptionHandler(error);
874
874
  }
875
875
  }
876
876
  }
@@ -1002,7 +1002,7 @@ export class Loader {
1002
1002
  try {
1003
1003
  // Try to parse as JSON, if it fails, then it's hopefully XML
1004
1004
  json = JSON.parse(bitmapFontXhr.responseText);
1005
- } catch (e) {
1005
+ } catch (error) {
1006
1006
  // pass
1007
1007
  }
1008
1008
  if (json) {
@@ -1102,7 +1102,7 @@ export class Loader {
1102
1102
  xml.async = 'false';
1103
1103
  xml.loadXML(data);
1104
1104
  }
1105
- } catch (e) {
1105
+ } catch (error) {
1106
1106
  xml = null;
1107
1107
  }
1108
1108
  if (!xml || !xml.documentElement || xml.getElementsByTagName('parsererror').length) {
@@ -11,6 +11,7 @@ export class SoundManager {
11
11
  constructor(game) {
12
12
  this.game = game;
13
13
  this.onChange = new Signal();
14
+ /** @type {AudioContext} */
14
15
  this.context = null;
15
16
  this.baseLatency = 0; // https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/baseLatency
16
17
  this.noAudio = false;
@@ -28,6 +29,16 @@ export class SoundManager {
28
29
  this._watchContext = null;
29
30
  }
30
31
 
32
+ /**
33
+ * TBD.
34
+ * @param {string} eventName - TBD.
35
+ * @param {object} eventData - TBD.
36
+ */
37
+ dispatchOnChangeEvent(eventName, eventData) {
38
+ this.game.logger.debug(eventName, eventData);
39
+ this.onChange.dispatch(eventName, eventData);
40
+ }
41
+
31
42
  /**
32
43
  * TBD.
33
44
  */
@@ -41,20 +52,20 @@ export class SoundManager {
41
52
  } else if (window.AudioContext) {
42
53
  try {
43
54
  this.context = new window.AudioContext();
44
- } catch (e) {
55
+ } catch (error) {
45
56
  this.context = null;
46
57
  this.noAudio = true;
47
58
  this.isLocked = false;
48
- this.game.exceptionHandler(e);
59
+ this.game.exceptionHandler(error);
49
60
  }
50
61
  } else if (window.webkitAudioContext) {
51
62
  try {
52
63
  this.context = new window.webkitAudioContext();
53
- } catch (e) {
64
+ } catch (error) {
54
65
  this.context = null;
55
66
  this.noAudio = true;
56
67
  this.isLocked = false;
57
- this.game.exceptionHandler(e);
68
+ this.game.exceptionHandler(error);
58
69
  }
59
70
  }
60
71
  if (
@@ -80,7 +91,7 @@ export class SoundManager {
80
91
  this.addUnlockHandlers();
81
92
  }
82
93
  this.context.addEventListener('statechange', () => {
83
- this.onChange.dispatch('onContextStateChange', {
94
+ this.dispatchOnChangeEvent('onContextStateChange', {
84
95
  state: this.context.state,
85
96
  isLocked: this.isLocked,
86
97
  });
@@ -97,11 +108,10 @@ export class SoundManager {
97
108
  */
98
109
  addUnlockHandlers() {
99
110
  this.isLocked = true;
100
- this.onChange.dispatch('addUnlockHandlers', {
111
+ this.dispatchOnChangeEvent('addUnlockHandlers', {
101
112
  state: this.context.state,
102
113
  isLocked: this.isLocked,
103
114
  });
104
- document.body.addEventListener('touchstart', this.onUnlockEventBinded, false);
105
115
  document.body.addEventListener('touchend', this.onUnlockEventBinded, false);
106
116
  document.body.addEventListener('click', this.onUnlockEventBinded, false);
107
117
  document.body.addEventListener('keydown', this.onUnlockEventBinded, false);
@@ -112,11 +122,10 @@ export class SoundManager {
112
122
  */
113
123
  removeUnlockHandlers() {
114
124
  this.isLocked = false;
115
- this.onChange.dispatch('removeUnlockHandlers', {
125
+ this.dispatchOnChangeEvent('removeUnlockHandlers', {
116
126
  state: this.context.state,
117
127
  isLocked: this.isLocked,
118
128
  });
119
- document.body.removeEventListener('touchstart', this.onUnlockEventBinded);
120
129
  document.body.removeEventListener('touchend', this.onUnlockEventBinded);
121
130
  document.body.removeEventListener('click', this.onUnlockEventBinded);
122
131
  document.body.removeEventListener('keydown', this.onUnlockEventBinded);
@@ -129,7 +138,7 @@ export class SoundManager {
129
138
  onUnlockEvent(event) {
130
139
  const initialState = this.context.state;
131
140
  if (initialState !== 'suspended' && initialState !== 'interrupted') {
132
- this.onChange.dispatch('onUnlockResumeDenied', {
141
+ this.dispatchOnChangeEvent('onUnlockResumeDenied', {
133
142
  state: initialState,
134
143
  isLocked: this.isLocked,
135
144
  event,
@@ -137,7 +146,7 @@ export class SoundManager {
137
146
  this.removeUnlockHandlers();
138
147
  return;
139
148
  }
140
- this.onChange.dispatch('onContextResumeStart', {
149
+ this.dispatchOnChangeEvent('onContextResumeStart', {
141
150
  state: initialState,
142
151
  isLocked: this.isLocked,
143
152
  event,
@@ -145,22 +154,22 @@ export class SoundManager {
145
154
  this.context
146
155
  .resume()
147
156
  .then(() => {
148
- this.onChange.dispatch('onContextResumeResult', {
157
+ this.dispatchOnChangeEvent('onContextResumeResult', {
149
158
  initialState,
150
159
  state: this.context.state,
151
160
  isLocked: this.isLocked,
152
161
  });
153
162
  this.removeUnlockHandlers();
154
163
  })
155
- .catch((e) => {
156
- this.onChange.dispatch('onContextResumeReject', {
164
+ .catch((error) => {
165
+ this.dispatchOnChangeEvent('onContextResumeReject', {
157
166
  initialState,
158
167
  state: this.context.state,
159
168
  isLocked: this.isLocked,
160
- error: e,
169
+ error,
161
170
  });
162
171
  this.removeUnlockHandlers();
163
- this.game.exceptionHandler(e, { 'audio.initialState': initialState, 'audio.state': this.context.state });
172
+ this.game.exceptionHandler(error, { 'audio.initialState': initialState, 'audio.state': this.context.state });
164
173
  });
165
174
  }
166
175
 
@@ -220,8 +229,8 @@ export class SoundManager {
220
229
  .then((buffer) => {
221
230
  this.game.cache.decodedSound(key, buffer);
222
231
  })
223
- .catch((e) => {
224
- this.game.exceptionHandler(e, { 'asset.key': key });
232
+ .catch((error) => {
233
+ this.game.exceptionHandler(error, { 'asset.key': key });
225
234
  });
226
235
  }
227
236
  }
@@ -124,7 +124,7 @@ export class WebGLRenderer {
124
124
  * @throws Error.
125
125
  */
126
126
  initContext(game) {
127
- game.logger.debug('initContext');
127
+ game.logger.info('initContext');
128
128
  // TODO: view.addEventListener('webglcontextcreationerror', this.onWebGLContextCreationError, false);
129
129
  /** @type {WebGLRenderingContext & { id: number }} */
130
130
  // @ts-ignore
@@ -13,7 +13,7 @@ export class Sound {
13
13
  key: string;
14
14
  loop: boolean;
15
15
  markers: {};
16
- context: any;
16
+ context: AudioContext;
17
17
  autoplay: boolean;
18
18
  totalDuration: number;
19
19
  startTime: number;
@@ -1 +1 @@
1
- {"version":3,"file":"sound.d.ts","sourceRoot":"","sources":["../../../src/phaser/core/sound.js"],"names":[],"mappings":"AAEA;IACE;;;;;;;OAOG;IACH,kBANW,OAAO,WAAW,EAAE,IAAI,OACxB,MAAM,WACN,MAAM,SACN,OAAO,YACP,OAAO,EAoEjB;IA5DC,+BAAgB;IAChB,aAAe;IACf,YAAc;IACd,cAAgB;IAChB,YAAiB;IACjB,aAAmB;IACnB,kBAAqB;IACrB,sBAAsB;IACtB,kBAAkB;IAClB,oBAAoB;IACpB,iBAAiB;IACjB,mBAAmB;IACnB,iBAAiB;IACjB,iBAAiB;IACjB,gBAAmB;IACnB,uBAAuB;IACvB,mBAAmB;IACnB,mBAAsB;IACtB,sBAAuB;IACvB,sCAAqB;IACrB,yBAA4B;IAC5B,kBAAqB;IACrB,uBAA0B;IAC1B,kBAAwB;IACxB,oBAA0B;IAC1B,cAAoB;IACpB,YAAkB;IAClB,yBAA4B;IAC5B,iCAAoC;IAcpC,eAA0B;IAC1B,gBAA2B;IAC3B,iBAA4B;IAC5B,eAA0B;IAC1B,eAA0B;IAC1B,eAA0B;IAC1B,yBAAoC;IACpC,uBAAkC;IAClC,gBAAqB;IACrB,aAAmB;IACnB,gBAAmB;IACnB,oBAAoB;IACpB,sBAAsB;IACtB,oBAAoB;IACpB,mBAAmB;IACnB,oBAAoB;IACpB,kBAAkB;IAClB,iBAAoB;IAGtB;;;OAGG;IACH,sBAFW,MAAM,QAOhB;IAED;;;;;;;OAOG;IACH,gBANW,MAAM,SACN,MAAM,aACN,MAAM,WACN,MAAM,SACN,OAAO,QAYjB;IAED;;;OAGG;IACH,mBAFW,MAAM,QAIhB;IAED;;OAEG;IACH,uBA2BC;IAED;;OAEG;IACH,eA6CC;IAED;;;;OAIG;IACH,iBAHW,MAAM,GACJ,KAAK,CAIjB;IAED;;;;;;;;OAQG;IACH,aAPW,MAAM,YACN,MAAM,UACN,MAAM,QACN,OAAO,gBACP,OAAO,GACL,KAAK,CA+IjB;IA8MD;;OAEG;IACH,0BAUC;IArBD;;;OAGG;IACH,qBAEC;IA1MD;;;;;;OAMG;IACH,iBALW,MAAM,aACN,MAAM,WACN,MAAM,SACN,OAAO,QAIjB;IAED;;OAEG;IACH,cASC;IAED;;OAEG;IACH,eAgCC;IAED;;OAEG;IACH,aA4BC;IAED;;;;;OAKG;IACH,iBAJW,MAAM,SACN,OAAO,WACP,MAAM,QAQhB;IAED;;;OAGG;IACH,kBAFW,MAAM,QAIhB;IAED;;;;OAIG;IACH,kBAHW,MAAM,WACN,MAAM,QAQhB;IAED;;OAEG;IACH,qBAKC;IAED;;;OAGG;IACH,iBAFW,OAAO,QAqBjB;IAUD;;OAEG;IACH,yBAkBC;IA7BD;;;OAGG;IACH,oBAEC;CA+CF;uBAnkBsB,aAAa"}
1
+ {"version":3,"file":"sound.d.ts","sourceRoot":"","sources":["../../../src/phaser/core/sound.js"],"names":[],"mappings":"AAEA;IACE;;;;;;;OAOG;IACH,kBANW,OAAO,WAAW,EAAE,IAAI,OACxB,MAAM,WACN,MAAM,SACN,OAAO,YACP,OAAO,EAoEjB;IA5DC,+BAAgB;IAChB,aAAe;IACf,YAAc;IACd,cAAgB;IAChB,YAAiB;IACjB,sBAAmB;IACnB,kBAAqB;IACrB,sBAAsB;IACtB,kBAAkB;IAClB,oBAAoB;IACpB,iBAAiB;IACjB,mBAAmB;IACnB,iBAAiB;IACjB,iBAAiB;IACjB,gBAAmB;IACnB,uBAAuB;IACvB,mBAAmB;IACnB,mBAAsB;IACtB,sBAAuB;IACvB,sCAAqB;IACrB,yBAA4B;IAC5B,kBAAqB;IACrB,uBAA0B;IAC1B,kBAAwB;IACxB,oBAA0B;IAC1B,cAAoB;IACpB,YAAkB;IAClB,yBAA4B;IAC5B,iCAAoC;IAcpC,eAA0B;IAC1B,gBAA2B;IAC3B,iBAA4B;IAC5B,eAA0B;IAC1B,eAA0B;IAC1B,eAA0B;IAC1B,yBAAoC;IACpC,uBAAkC;IAClC,gBAAqB;IACrB,aAAmB;IACnB,gBAAmB;IACnB,oBAAoB;IACpB,sBAAsB;IACtB,oBAAoB;IACpB,mBAAmB;IACnB,oBAAoB;IACpB,kBAAkB;IAClB,iBAAoB;IAGtB;;;OAGG;IACH,sBAFW,MAAM,QAOhB;IAED;;;;;;;OAOG;IACH,gBANW,MAAM,SACN,MAAM,aACN,MAAM,WACN,MAAM,SACN,OAAO,QAYjB;IAED;;;OAGG;IACH,mBAFW,MAAM,QAIhB;IAED;;OAEG;IACH,uBA2BC;IAED;;OAEG;IACH,eA6CC;IAED;;;;OAIG;IACH,iBAHW,MAAM,GACJ,KAAK,CAIjB;IAED;;;;;;;;OAQG;IACH,aAPW,MAAM,YACN,MAAM,UACN,MAAM,QACN,OAAO,gBACP,OAAO,GACL,KAAK,CA+IjB;IA8MD;;OAEG;IACH,0BAUC;IArBD;;;OAGG;IACH,qBAEC;IA1MD;;;;;;OAMG;IACH,iBALW,MAAM,aACN,MAAM,WACN,MAAM,SACN,OAAO,QAIjB;IAED;;OAEG;IACH,cASC;IAED;;OAEG;IACH,eAgCC;IAED;;OAEG;IACH,aA4BC;IAED;;;;;OAKG;IACH,iBAJW,MAAM,SACN,OAAO,WACP,MAAM,QAQhB;IAED;;;OAGG;IACH,kBAFW,MAAM,QAIhB;IAED;;;;OAIG;IACH,kBAHW,MAAM,WACN,MAAM,QAQhB;IAED;;OAEG;IACH,qBAKC;IAED;;;OAGG;IACH,iBAFW,OAAO,QAqBjB;IAUD;;OAEG;IACH,yBAkBC;IA7BD;;;OAGG;IACH,oBAEC;CA+CF;uBAnkBsB,aAAa"}
@@ -6,7 +6,8 @@ export class SoundManager {
6
6
  constructor(game: import("./game.js").Game);
7
7
  game: import("./game.js").Game;
8
8
  onChange: Signal;
9
- context: any;
9
+ /** @type {AudioContext} */
10
+ context: AudioContext;
10
11
  baseLatency: number;
11
12
  noAudio: boolean;
12
13
  connectToMaster: boolean;
@@ -21,6 +22,12 @@ export class SoundManager {
21
22
  _watching: boolean;
22
23
  _watchCallback: Function;
23
24
  _watchContext: any;
25
+ /**
26
+ * TBD.
27
+ * @param {string} eventName - TBD.
28
+ * @param {object} eventData - TBD.
29
+ */
30
+ dispatchOnChangeEvent(eventName: string, eventData: object): void;
24
31
  /**
25
32
  * TBD.
26
33
  */
@@ -1 +1 @@
1
- {"version":3,"file":"sound_manager.d.ts","sourceRoot":"","sources":["../../../src/phaser/core/sound_manager.js"],"names":[],"mappings":"AAKA;IACE;;;OAGG;IACH,kBAFW,OAAO,WAAW,EAAE,IAAI,EAoBlC;IAjBC,+BAAgB;IAChB,iBAA4B;IAC5B,aAAmB;IACnB,oBAAoB;IACpB,iBAAoB;IACpB,yBAA2B;IAC3B,kBAAqB;IACrB,qBAAuB;IACvB,oBAAuB;IACvB,gBAAmB;IACnB,mBAAyB;IACzB,gBAAgB;IAChB,eAAiB;IACjB,qBAAgC;IAChC,mBAAsB;IACtB,yBAA0B;IAC1B,mBAAyB;IAG3B;;OAEG;IACH,aA2DC;IAvBG,gBAA+C;IAQjD,6BAiDS,KAAK,UAjD0C;IAiB1D;;OAEG;IACH,0BAUC;IAED;;OAEG;IACH,6BAUC;IAED;;;OAGG;IACH,qBAFW,KAAK,QAsCf;IAED;;OAEG;IACH,gBASC;IAED;;OAEG;IACH,iBASC;IAED;;OAEG;IACH,kBASC;IAED;;;OAGG;IACH,YAFW,MAAM,QAiBhB;IAED;;;;;OAKG;IACH,0BAJW,KAAK,EAAE,GAAC,MAAM,EAAE,uCAEhB,MAAM,QAyBhB;IAED;;OAEG;IACH,eAoBC;IAED;;;;;;;OAOG;IACH,SANW,MAAM,WACN,MAAM,SACN,OAAO,YACP,OAAO,GACL,KAAK,CAMjB;IAED;;;;OAIG;IACH,eAHW,MAAM,GACJ,WAAW,CAIvB;IAED;;;;OAIG;IACH,cAHW,KAAK,GACH,OAAO,CAanB;IAED;;;;OAIG;IACH,iBAHW,MAAM,GACJ,MAAM,CAclB;IAED;;;;;;OAMG;IACH,UALW,MAAM,WACN,MAAM,SACN,OAAO,GACL,KAAK,CASjB;IAED;;OAEG;IACH,gBAUC;IAJG,iBAA6C;IAMjD;;OAEG;IACH,kBASC;IAED;;OAEG;IACH,gBAgBC;IAUD;;OAEG;IACH,yBAcC;IAzBD;;;OAGG;IACH,oBAEC;IA6BD;;OAEG;IACH,0BAYC;IAvBD;;;OAGG;IACH,qBAEC;CAkBF;uBA7csB,aAAa;yBADX,gBAAgB;sBAEnB,YAAY;4BACN,mBAAmB"}
1
+ {"version":3,"file":"sound_manager.d.ts","sourceRoot":"","sources":["../../../src/phaser/core/sound_manager.js"],"names":[],"mappings":"AAKA;IACE;;;OAGG;IACH,kBAFW,OAAO,WAAW,EAAE,IAAI,EAqBlC;IAlBC,+BAAgB;IAChB,iBAA4B;IAC5B,2BAA2B;IAC3B,SADW,YAAY,CACJ;IACnB,oBAAoB;IACpB,iBAAoB;IACpB,yBAA2B;IAC3B,kBAAqB;IACrB,qBAAuB;IACvB,oBAAuB;IACvB,gBAAmB;IACnB,mBAAyB;IACzB,gBAAgB;IAChB,eAAiB;IACjB,qBAAgC;IAChC,mBAAsB;IACtB,yBAA0B;IAC1B,mBAAyB;IAG3B;;;;OAIG;IACH,iCAHW,MAAM,aACN,MAAM,QAKhB;IAED;;OAEG;IACH,aA2DC;IAvBG,gBAA+C;IAQjD,6BA+CS,KAAK,UA/C0C;IAiB1D;;OAEG;IACH,0BASC;IAED;;OAEG;IACH,6BASC;IAED;;;OAGG;IACH,qBAFW,KAAK,QAsCf;IAED;;OAEG;IACH,gBASC;IAED;;OAEG;IACH,iBASC;IAED;;OAEG;IACH,kBASC;IAED;;;OAGG;IACH,YAFW,MAAM,QAiBhB;IAED;;;;;OAKG;IACH,0BAJW,KAAK,EAAE,GAAC,MAAM,EAAE,uCAEhB,MAAM,QAyBhB;IAED;;OAEG;IACH,eAoBC;IAED;;;;;;;OAOG;IACH,SANW,MAAM,WACN,MAAM,SACN,OAAO,YACP,OAAO,GACL,KAAK,CAMjB;IAED;;;;OAIG;IACH,eAHW,MAAM,GACJ,WAAW,CAIvB;IAED;;;;OAIG;IACH,cAHW,KAAK,GACH,OAAO,CAanB;IAED;;;;OAIG;IACH,iBAHW,MAAM,GACJ,MAAM,CAclB;IAED;;;;;;OAMG;IACH,UALW,MAAM,WACN,MAAM,SACN,OAAO,GACL,KAAK,CASjB;IAED;;OAEG;IACH,gBAUC;IAJG,iBAA6C;IAMjD;;OAEG;IACH,kBASC;IAED;;OAEG;IACH,gBAgBC;IAUD;;OAEG;IACH,yBAcC;IAzBD;;;OAGG;IACH,oBAEC;IA6BD;;OAEG;IACH,0BAYC;IAvBD;;;OAGG;IACH,qBAEC;CAkBF;uBAtdsB,aAAa;yBADX,gBAAgB;sBAEnB,YAAY;4BACN,mBAAmB"}