@gcorevideo/player 2.22.30 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/assets/media-control/container.scss +2 -3
  2. package/assets/poster/poster.ejs +3 -1
  3. package/assets/poster/poster.scss +3 -3
  4. package/assets/style/main.scss +1 -1
  5. package/assets/thumbnails/scrub-thumbnails.ejs +5 -10
  6. package/assets/thumbnails/style.scss +4 -5
  7. package/dist/core.js +1 -1
  8. package/dist/index.css +533 -532
  9. package/dist/index.js +273 -377
  10. package/dist/player.d.ts +63 -33
  11. package/docs/api/{player.seektime.bindevents.md → player.clapprstats.clearmetrics.md} +3 -3
  12. package/docs/api/player.clapprstats.md +14 -0
  13. package/docs/api/player.extendedevents.md +14 -0
  14. package/docs/api/player.md +13 -2
  15. package/docs/api/player.seektime.attributes.md +0 -1
  16. package/docs/api/player.seektime.md +6 -197
  17. package/docs/api/{player.seektime.render.md → player.seektimesettings.md} +7 -7
  18. package/docs/api/player.skiptime.md +3 -184
  19. package/lib/plugins/clips/Clips.d.ts +7 -0
  20. package/lib/plugins/clips/Clips.d.ts.map +1 -1
  21. package/lib/plugins/clips/Clips.js +8 -0
  22. package/lib/plugins/media-control/MediaControl.d.ts +1 -7
  23. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  24. package/lib/plugins/media-control/MediaControl.js +9 -18
  25. package/lib/plugins/poster/Poster.d.ts +24 -14
  26. package/lib/plugins/poster/Poster.d.ts.map +1 -1
  27. package/lib/plugins/poster/Poster.js +67 -97
  28. package/lib/plugins/thumbnails/Thumbnails.d.ts +36 -33
  29. package/lib/plugins/thumbnails/Thumbnails.d.ts.map +1 -1
  30. package/lib/plugins/thumbnails/Thumbnails.js +174 -259
  31. package/lib/plugins/thumbnails/utils.d.ts +5 -0
  32. package/lib/plugins/thumbnails/utils.d.ts.map +1 -0
  33. package/lib/plugins/thumbnails/utils.js +12 -0
  34. package/lib/testUtils.d.ts +13 -39
  35. package/lib/testUtils.d.ts.map +1 -1
  36. package/lib/testUtils.js +15 -67
  37. package/package.json +2 -1
  38. package/src/plugins/clips/Clips.ts +10 -1
  39. package/src/plugins/media-control/MediaControl.ts +10 -21
  40. package/src/plugins/media-control/__tests__/__snapshots__/MediaControl.test.ts.snap +1 -1
  41. package/src/plugins/poster/Poster.ts +91 -110
  42. package/src/plugins/poster/__tests__/Poster.test.ts +119 -0
  43. package/src/plugins/poster/__tests__/__snapshots__/Poster.test.ts.snap +8 -0
  44. package/src/plugins/source-controller/__tests__/SourceController.test.ts +1 -2
  45. package/src/plugins/thumbnails/Thumbnails.ts +228 -330
  46. package/src/plugins/thumbnails/__tests__/Thumbnails.test.ts +72 -0
  47. package/src/plugins/thumbnails/__tests__/__snapshots__/Thumbnails.test.ts.snap +10 -0
  48. package/src/plugins/thumbnails/utils.ts +12 -0
  49. package/src/testUtils.ts +15 -88
  50. package/temp/player.api.json +295 -829
  51. package/tsconfig.tsbuildinfo +1 -1
  52. package/docs/api/player.seektime.durationshown.md +0 -14
  53. package/docs/api/player.seektime.getseektime.md +0 -20
  54. package/docs/api/player.seektime.islivestreamwithdvr.md +0 -14
  55. package/docs/api/player.seektime.mediacontrol.md +0 -14
  56. package/docs/api/player.seektime.mediacontrolcontainer.md +0 -14
  57. package/docs/api/player.seektime.shouldbevisible.md +0 -18
  58. package/docs/api/player.seektime.template.md +0 -14
  59. package/docs/api/player.seektime.update.md +0 -18
  60. package/docs/api/player.skiptime.attributes.md +0 -17
  61. package/docs/api/player.skiptime.bindevents.md +0 -18
  62. package/docs/api/player.skiptime.events.md +0 -18
  63. package/docs/api/player.skiptime.handlerewindclicks.md +0 -18
  64. package/docs/api/player.skiptime.render.md +0 -18
  65. package/docs/api/player.skiptime.setback.md +0 -18
  66. package/docs/api/player.skiptime.setforward.md +0 -18
  67. package/docs/api/player.skiptime.setmidclick.md +0 -18
  68. package/docs/api/player.skiptime.template.md +0 -14
  69. package/docs/api/player.skiptime.togglefullscreen.md +0 -18
@@ -1,7 +1,7 @@
1
1
  //Copyright 2014 Globo.com Player authors. All rights reserved.
2
2
  // Use of this source code is governed by a BSD-style
3
3
  // license that can be found in the LICENSE file.
4
- import { Events, Playback, PlayerError, UIContainerPlugin, template, $, } from '@clappr/core';
4
+ import { Events, Playback, PlayerError, UIContainerPlugin, template, } from '@clappr/core';
5
5
  import { trace } from '@gcorevideo/utils';
6
6
  import { CLAPPR_VERSION } from '../../build.js';
7
7
  import '../../../assets/poster/poster.scss';
@@ -12,19 +12,13 @@ const T = 'plugins.poster';
12
12
  * `PLUGIN` that displays a poster image in the background and a big play button on top when playback is stopped
13
13
  * @beta
14
14
  * @remarks
15
- * When the playback is stopped, media control UI is disabled.
15
+ * When the playback is stopped or not yet started, the media control UI is disabled and hidden.
16
+ * Media control gets activated once the metadata is loaded after playback is initiated.
17
+ * This plugin displays a big play button on top of the poster image to allow user to start playback.
16
18
  * Note that the poster image, if specified via the player config, will be used to update video element's poster attribute by the
17
19
  * HTML5-video-based playback module.
18
20
  *
19
- * Configuration options:
20
- *
21
- * - `poster.custom` - custom CSS background
22
- *
23
- * - `poster.showForNoOp` - whether to show the poster when the playback is not started
24
- *
25
- * - `poster.url` - the URL of the poster image
26
- *
27
- * - `poster.showOnVideoEnd` - whether to show the poster when the playback is ended
21
+ * Configuration options - {@link PosterPluginSettings}
28
22
  *
29
23
  * @example
30
24
  * ```ts
@@ -40,10 +34,9 @@ const T = 'plugins.poster';
40
34
  export class Poster extends UIContainerPlugin {
41
35
  // TODO merge non-poster related functionality into the ClickToPause plugin
42
36
  hasFatalError = false;
43
- hasStartedPlaying = false;
37
+ playing = false;
44
38
  playRequested = false;
45
39
  $playButton = null;
46
- $playWrapper = null;
47
40
  /**
48
41
  * @internal
49
42
  */
@@ -63,8 +56,10 @@ export class Poster extends UIContainerPlugin {
63
56
  }
64
57
  const showForNoOp = !!this.options.poster?.showForNoOp;
65
58
  return (this.container.playback.name !== 'html_img' &&
66
- (this.container.playback.getPlaybackType() !== Playback.NO_OP ||
67
- showForNoOp));
59
+ (!this.isNoOp || showForNoOp));
60
+ }
61
+ get isNoOp() {
62
+ return this.container.playback.getPlaybackType() === Playback.NO_OP;
68
63
  }
69
64
  /**
70
65
  * @internal
@@ -72,7 +67,6 @@ export class Poster extends UIContainerPlugin {
72
67
  get attributes() {
73
68
  return {
74
69
  class: 'player-poster',
75
- 'data-poster': '',
76
70
  };
77
71
  }
78
72
  /**
@@ -83,9 +77,6 @@ export class Poster extends UIContainerPlugin {
83
77
  click: 'clicked',
84
78
  };
85
79
  }
86
- get showOnVideoEnd() {
87
- return this.options.poster?.showOnVideoEnd !== false;
88
- }
89
80
  /**
90
81
  * @internal
91
82
  */
@@ -94,19 +85,22 @@ export class Poster extends UIContainerPlugin {
94
85
  this.listenTo(this.container, Events.CONTAINER_PLAY, this.onPlay);
95
86
  this.listenTo(this.container, Events.CONTAINER_STATE_BUFFERING, this.update);
96
87
  this.listenTo(this.container, Events.CONTAINER_STATE_BUFFERFULL, this.update);
97
- this.listenTo(this.container, Events.CONTAINER_OPTIONS_CHANGE, this.render);
88
+ this.listenTo(this.container, Events.CONTAINER_OPTIONS_CHANGE, this.update);
98
89
  this.listenTo(this.container, Events.CONTAINER_ERROR, this.onError);
99
- this.showOnVideoEnd &&
90
+ // TODO check if this event is always accompanied with the CONTAINER_STOP
91
+ if (this.options.poster?.showOnVideoEnd !== false) {
100
92
  this.listenTo(this.container, Events.CONTAINER_ENDED, this.onStop);
93
+ }
101
94
  this.listenTo(this.container, Events.CONTAINER_READY, this.render);
102
- this.listenTo(this.container, Events.PLAYBACK_PLAY_INTENT, this.onPlayIntent);
95
+ this.listenTo(this.container.playback, Events.PLAYBACK_PLAY_INTENT, this.onPlayIntent);
103
96
  }
104
97
  /**
105
98
  * Reenables earlier disabled plugin
106
99
  */
107
100
  enable() {
101
+ trace(`${T} enable`);
108
102
  super.enable();
109
- this.hasStartedPlaying = this.container.playback.isPlaying();
103
+ this.playing = this.container.playback.isPlaying();
110
104
  this.update();
111
105
  }
112
106
  /**
@@ -114,7 +108,7 @@ export class Poster extends UIContainerPlugin {
114
108
  */
115
109
  disable() {
116
110
  trace(`${T} disable`);
117
- this.hasStartedPlaying = false;
111
+ this.playing = false;
118
112
  this.playRequested = false;
119
113
  super.disable();
120
114
  }
@@ -123,17 +117,15 @@ export class Poster extends UIContainerPlugin {
123
117
  error,
124
118
  enabled: this.enabled,
125
119
  });
126
- this.hasFatalError = error.level === PlayerError.Levels.FATAL;
127
120
  if (this.hasFatalError) {
128
- this.hasStartedPlaying = false;
129
- if (!this.playRequested) {
130
- this.showPlayButton();
131
- }
121
+ return;
132
122
  }
123
+ this.hasFatalError = error.level === PlayerError.Levels.FATAL;
124
+ // this.hasFatalError is reset on container recreate
133
125
  }
134
126
  onPlay() {
135
127
  trace(`${T} onPlay`);
136
- this.hasStartedPlaying = true;
128
+ this.playing = true;
137
129
  this.playRequested = false;
138
130
  this.update();
139
131
  }
@@ -143,21 +135,21 @@ export class Poster extends UIContainerPlugin {
143
135
  this.update();
144
136
  }
145
137
  onStop() {
146
- trace(`${T} onStop`, {
147
- enabled: this.enabled,
148
- });
149
- this.hasStartedPlaying = false;
138
+ trace(`${T} onStop`);
139
+ this.playing = false;
150
140
  this.playRequested = false;
151
141
  this.update();
152
142
  }
153
- updatePlayButton(show) {
154
- trace(`${T} updatePlayButton`, {
155
- show,
156
- chromeless: this.options.chromeless,
157
- allowUserInteraction: this.options.allowUserInteraction,
158
- });
159
- if (show &&
160
- (!this.options.chromeless || this.options.allowUserInteraction)) {
143
+ updatePlayButton() {
144
+ trace(`${T} updatePlayButton`);
145
+ const show = !this.isNoOp &&
146
+ !(this.options.chromeless && !this.options.allowUserInteraction) &&
147
+ !this.playRequested &&
148
+ !this.playing &&
149
+ !this.container.buffering &&
150
+ !this.hasFatalError &&
151
+ !this.options.disableMediaControl;
152
+ if (show) {
161
153
  this.showPlayButton();
162
154
  }
163
155
  else {
@@ -165,59 +157,42 @@ export class Poster extends UIContainerPlugin {
165
157
  }
166
158
  }
167
159
  showPlayButton() {
168
- if (this.options.disableMediaControl) {
169
- return;
170
- }
171
- if (this.hasFatalError && !this.options.disableErrorScreen) {
172
- return;
173
- }
174
- this.$playButton?.show();
160
+ trace(`${T} showPlayButton`);
161
+ this.$el.find('#poster-play').show();
175
162
  this.$el.addClass('clickable');
176
163
  this.container.$el.addClass('container-with-poster-clickable');
177
164
  }
178
165
  hidePlayButton() {
179
- this.$playButton.hide();
166
+ trace(`${T} hidePlayButton`);
167
+ this.$el.find('#poster-play').hide();
180
168
  this.$el.removeClass('clickable');
181
169
  }
182
- clicked() {
183
- trace(`${T} clicked`, {
184
- hasStartedPlaying: this.hasStartedPlaying,
185
- chromeless: this.options.chromeless,
186
- allowUserInteraction: this.options.allowUserInteraction,
187
- });
170
+ clicked(e) {
171
+ trace(`${T} clicked`);
172
+ e.preventDefault();
173
+ e.stopPropagation();
174
+ if (this.options.chromeless && !this.options.allowUserInteraction) {
175
+ return;
176
+ }
188
177
  // Let "click_to_pause" plugin handle click event if media has started playing
189
- if (!this.hasStartedPlaying) {
190
- if (!this.options.chromeless || this.options.allowUserInteraction) {
191
- this.playRequested = true;
192
- this.update();
193
- this.container.playback.consent();
194
- this.container.playback.play();
195
- }
178
+ if (!this.playing) {
179
+ this.playRequested = true;
180
+ this.update();
181
+ this.container.play();
196
182
  }
197
- return false;
198
183
  }
199
184
  shouldHideOnPlay() {
200
185
  // Audio broadcasts should keep the poster up; video should hide poster while playing.
201
186
  return !this.container.playback.isAudioOnly;
202
187
  }
203
188
  update() {
204
- trace(`${T} update`, {
205
- shouldRender: this.shouldRender,
206
- });
207
- if (!this.shouldRender) {
208
- return;
209
- }
210
- const showPlayButton = !this.playRequested &&
211
- !this.hasStartedPlaying &&
212
- !this.container.buffering;
213
- this.updatePlayButton(showPlayButton);
189
+ trace(`${T} update`);
190
+ this.updatePlayButton();
214
191
  this.updatePoster();
215
192
  }
216
193
  updatePoster() {
217
- trace(`${T} updatePoster`, {
218
- hasStartedPlaying: this.hasStartedPlaying,
219
- });
220
- if (!this.hasStartedPlaying) {
194
+ trace(`${T} updatePoster`);
195
+ if (!this.playing) {
221
196
  this.showPoster();
222
197
  }
223
198
  else {
@@ -229,9 +204,7 @@ export class Poster extends UIContainerPlugin {
229
204
  this.$el.show();
230
205
  }
231
206
  hidePoster() {
232
- trace(`${T} hidePoster`, {
233
- shouldHideOnPlay: this.shouldHideOnPlay(),
234
- });
207
+ trace(`${T} hidePoster`);
235
208
  if (!this.options.disableMediaControl) {
236
209
  this.container.enableMediaControl();
237
210
  }
@@ -247,27 +220,24 @@ export class Poster extends UIContainerPlugin {
247
220
  return this;
248
221
  }
249
222
  this.$el.html(Poster.template());
250
- const isRegularPoster = this.options.poster && this.options.poster.custom === undefined;
251
- if (isRegularPoster) {
252
- const posterUrl = this.options.poster.url || this.options.poster;
253
- this.$el.css({ 'background-image': 'url(' + posterUrl + ')' });
254
- }
255
- else if (this.options.poster) {
223
+ const isCustomPoster = this.options.poster?.custom !== undefined;
224
+ if (isCustomPoster) {
256
225
  this.$el.css({ background: this.options.poster.custom });
257
226
  }
227
+ else {
228
+ const posterUrl = typeof this.options.poster === 'string'
229
+ ? this.options.poster
230
+ : this.options.poster?.url;
231
+ if (posterUrl) {
232
+ this.$el.css({ 'background-image': 'url(' + posterUrl + ')' });
233
+ }
234
+ }
258
235
  this.container.$el.removeClass('container-with-poster-clickable');
259
236
  this.container.$el.append(this.el);
260
- this.$playWrapper = this.$el.find('.play-wrapper');
261
- this.$playWrapper.addClass('control-need-disable');
262
- this.$playButton = $("<div class='circle-poster gcore-skin-button-color gcore-skin-border-color'></div>");
263
- this.$playWrapper.append(this.$playButton);
264
- this.$playButton.append(playIcon);
265
- if (this.options.autoPlay) {
266
- this.$playButton.hide();
237
+ this.$el.find('#poster-play').append(playIcon);
238
+ if (this.options.autoPlay || this.isNoOp) {
239
+ this.$el.find('#poster-play').hide();
267
240
  }
268
- this.$playButton.addClass('poster-icon');
269
- this.$playButton.attr('data-poster', '');
270
- this.update();
271
241
  return this;
272
242
  }
273
243
  /**
@@ -1,20 +1,26 @@
1
- import { UICorePlugin } from '@clappr/core';
1
+ import { UICorePlugin, Core } from '@clappr/core';
2
2
  import '../../../assets/thumbnails/style.scss';
3
3
  /**
4
4
  * Plugin configuration options for the thumbnails plugin.
5
5
  * @beta
6
6
  */
7
7
  export type ThumbnailsPluginSettings = {
8
- backdropHeight: number;
9
- backdropMaxOpacity: number;
10
- backdropMinOpacity: number;
11
- spotlightHeight: number;
8
+ backdropHeight?: number;
9
+ backdropMaxOpacity?: number;
10
+ backdropMinOpacity?: number;
11
+ spotlightHeight?: number;
12
12
  sprite: string;
13
13
  vtt: string;
14
14
  };
15
15
  /**
16
16
  * `PLUGIN` that displays the thumbnails of the video when available.
17
17
  * @beta
18
+ * @remarks
19
+ * The plugin needs specially crafted VTT file with a thumbnail sprite sheet to work.
20
+ * The VTT consist of timestamp records followed by a thumbnail area
21
+ *
22
+ * Configuration options - {@link ThumbnailsPluginSettings}
23
+ *
18
24
  * @example
19
25
  * ```ts
20
26
  * import { Thumbnails } from '@gcorevideo/player'
@@ -35,19 +41,15 @@ export type ThumbnailsPluginSettings = {
35
41
  * ```
36
42
  */
37
43
  export declare class Thumbnails extends UICorePlugin {
38
- private _$spotlight;
39
- private _$backdrop;
40
- private $container;
41
- private $img;
42
- private _$carousel;
43
- private $textThumbnail;
44
- private _$backdropCarouselImgs;
44
+ private $backdropCarouselImgs;
45
45
  private spriteSheetHeight;
46
- private _hoverPosition;
47
- private _show;
48
- private _thumbsLoaded;
49
- private _oldContainer;
50
- private _thumbs;
46
+ private spriteSheetWidth;
47
+ private hoverPosition;
48
+ private showing;
49
+ private thumbsLoaded;
50
+ private spotlightHeight;
51
+ private backdropHeight;
52
+ private thumbs;
51
53
  /**
52
54
  * @internal
53
55
  */
@@ -65,28 +67,29 @@ export declare class Thumbnails extends UICorePlugin {
65
67
  class: string;
66
68
  };
67
69
  private static readonly template;
70
+ constructor(core: Core);
68
71
  private buildSpriteConfig;
69
72
  /**
70
73
  * @internal
71
74
  */
72
75
  bindEvents(): void;
73
- private _bindContainerEvents;
74
- private _onCoreReady;
76
+ private bindContainerEvents;
77
+ private onCoreReady;
75
78
  private loadSpriteSheet;
76
- private _onMediaControlContainerChanged;
77
- private _init;
78
- private _getOptions;
79
- private _appendElToMediaControl;
80
- private _onMouseMove;
81
- private _onMouseLeave;
82
- private _calculateHoverPosition;
83
- private _buildImg;
84
- private _loadBackdrop;
79
+ private onContainerChanged;
80
+ private init;
81
+ private mount;
82
+ private onMouseMoveSeekbar;
83
+ private onMouseLeave;
84
+ private buildThumbImage;
85
+ private loadBackdrop;
85
86
  private setText;
86
- private _updateCarousel;
87
- private _updateSpotlightThumb;
88
- private _getThumbIndexForTime;
89
- private _renderPlugin;
90
- private _createElements;
87
+ private updateCarousel;
88
+ private updateSpotlightThumb;
89
+ private getThumbIndexForTime;
90
+ private update;
91
+ private fixElements;
92
+ private get shouldRender();
93
+ render(): this;
91
94
  }
92
95
  //# sourceMappingURL=Thumbnails.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Thumbnails.d.ts","sourceRoot":"","sources":["../../../src/plugins/thumbnails/Thumbnails.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAkC,MAAM,cAAc,CAAA;AAS3E,OAAO,uCAAuC,CAAA;AAI9C;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,cAAc,EAAE,MAAM,CAAA;IACtB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAeD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,WAAW,CAA2B;IAE9C,OAAO,CAAC,UAAU,CAA2B;IAE7C,OAAO,CAAC,UAAU,CAA2B;IAE7C,OAAO,CAAC,IAAI,CAA2B;IAEvC,OAAO,CAAC,UAAU,CAA2B;IAE7C,OAAO,CAAC,cAAc,CAA2B;IAEjD,OAAO,CAAC,sBAAsB,CAAoB;IAElD,OAAO,CAAC,iBAAiB,CAAY;IAErC,OAAO,CAAC,cAAc,CAAI;IAE1B,OAAO,CAAC,KAAK,CAAQ;IAErB,OAAO,CAAC,aAAa,CAAQ;IAE7B,OAAO,CAAC,aAAa,CAAyB;IAE9C,OAAO,CAAC,OAAO,CAAc;IAE7B;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAcvD,OAAO,CAAC,iBAAiB;IAmCzB;;OAEG;IACM,UAAU;IAwBnB,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,YAAY;YAiCN,eAAe;IAY7B,OAAO,CAAC,+BAA+B;IAIvC,OAAO,CAAC,KAAK;IAcb,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,uBAAuB;IAM/B,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,uBAAuB;IAgF/B,OAAO,CAAC,SAAS;IA2BjB,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,eAAe;IA4EvB,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,eAAe;CAgBxB"}
1
+ {"version":3,"file":"Thumbnails.d.ts","sourceRoot":"","sources":["../../../src/plugins/thumbnails/Thumbnails.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAKZ,IAAI,EACL,MAAM,cAAc,CAAA;AAUrB,OAAO,uCAAuC,CAAA;AAM9C;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,qBAAqB,CAAoB;IAEjD,OAAO,CAAC,iBAAiB,CAAY;IAErC,OAAO,CAAC,gBAAgB,CAAY;IAEpC,OAAO,CAAC,aAAa,CAAI;IAEzB,OAAO,CAAC,OAAO,CAAQ;IAEvB,OAAO,CAAC,YAAY,CAAQ;IAE5B,OAAO,CAAC,eAAe,CAAI;IAE3B,OAAO,CAAC,cAAc,CAAI;IAE1B,OAAO,CAAC,MAAM,CAAsB;IAEpC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAuB;gBAE3C,IAAI,EAAE,IAAI;IAgBtB,OAAO,CAAC,iBAAiB;IAiCzB;;OAEG;IACM,UAAU;IAInB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,WAAW;YAmDL,eAAe;IAO7B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,IAAI;IAaZ,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,cAAc;IAuEtB,OAAO,CAAC,oBAAoB;IA+C5B,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,WAAW;IAgBnB,OAAO,KAAK,YAAY,GAMvB;IAEQ,MAAM;CAShB"}