@jellybrick/mpris-service 2.1.5 → 2.2.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/dist/index.js DELETED
@@ -1,442 +0,0 @@
1
- "use strict";
2
-
3
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
4
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
6
- function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
7
- function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
8
- function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
9
- require('source-map-support').install();
10
- const {
11
- EventEmitter
12
- } = require('events');
13
- const dbus = require('@jellybrick/dbus-next');
14
- const PlayerInterface = require('./interfaces/player');
15
- const RootInterface = require('./interfaces/root');
16
- const PlaylistsInterface = require('./interfaces/playlists');
17
- const TracklistInterface = require('./interfaces/tracklist');
18
- const types = require('./interfaces/types');
19
- const constants = require('./constants');
20
- const MPRIS_PATH = '/org/mpris/MediaPlayer2';
21
- function lcfirst(str) {
22
- return str[0].toLowerCase() + str.substring(1);
23
- }
24
- var _Player_brand = /*#__PURE__*/new WeakSet();
25
- class Player extends EventEmitter {
26
- /**
27
- * Construct a new Player and export it on the DBus session bus.
28
- *
29
- * For more information about the properties of this class, see [the MPRIS DBus Interface Specification](https://specifications.freedesktop.org/mpris-spec/latest/).
30
- *
31
- * Method Call Events
32
- * ------------------
33
- *
34
- * The Player is an `EventEmitter` that emits events when the corresponding
35
- * methods are called on the DBus interface over the wire.
36
- *
37
- * The Player emits events whenever the corresponding methods on the DBus
38
- * interface are called.
39
- *
40
- * * `raise` - Brings the media player's user interface to the front using any appropriate mechanism available.
41
- * * `quit` - Causes the media player to stop running.
42
- * * `next` - Skips to the next track in the tracklist.
43
- * * `previous` - Skips to the previous track in the tracklist.
44
- * * `pause` - Pauses playback.
45
- * * `playPause` - Pauses playback. If playback is already paused, resumes playback. If playback is stopped, starts playback.
46
- * * `stop` - Stops playback.
47
- * * `play` - Starts or resumes playback.
48
- * * `seek` - Seeks forward in the current track by the specified number of microseconds. With event data `offset`.
49
- * * `position` - Sets the current track position in microseconds. With event data `{ trackId, position }`.
50
- * * `open` - Opens the Uri given as an argument. With event data `{ uri }`.
51
- * * `volume` - Sets the volume of the player. With event data `volume` (between 0.0 and 1.0).
52
- * * `shuffle` - Sets whether shuffle is enabled on the player. With event data `shuffleStatus` (boolean).
53
- * * `rate` - Sets the playback rate of the player. A value of 1.0 is the normal rate. With event data `rate`.
54
- * * `loopStatus` - Sets the loop status of the player to either 'None', 'Track', or 'Playlist'. With event data `loopStatus`.
55
- * * `activatePlaylist` - Starts playing the given playlist. With event data `playlistId`.
56
- *
57
- * The Player may also emit an `error` event with the underlying Node `Error`
58
- * as the event data. After receiving this event, the Player may be
59
- * disconnected.
60
- *
61
- * ```
62
- * player.on('play', () => {
63
- * realPlayer.play();
64
- * });
65
- *
66
- * player.on('shuffle', (enableShuffle) => {
67
- * realPlayer.setShuffle(enableShuffle);
68
- * player.shuffle = enableShuffle;
69
- * });
70
- * ```
71
- *
72
- * Player Properties
73
- * -----------------
74
- *
75
- * Player properties (documented below) should be kept up to date to reflect
76
- * the state of your real player. These properties can be gotten by the client
77
- * through the `org.freedesktop.DBus.Properties` interface which will return
78
- * the value currently set on the player. Setting these properties on the
79
- * player to a different value will emit the `PropertiesChanged` signal on the
80
- * properties interface to notify clients that properties of the player have
81
- * changed.
82
- *
83
- * ```
84
- * realPlayer.on('shuffle:changed', (shuffleEnabled) => {
85
- * player.shuffle = shuffleEnabled;
86
- * });
87
- *
88
- * realPlayer.on('play', () => {
89
- * player.playbackStatus = 'Playing';
90
- * });
91
- * ```
92
- *
93
- * Player Position
94
- * ---------------
95
- *
96
- * Clients can get the position of your player by getting the `Position`
97
- * property of the `org.mpris.MediaPlayer2.Player` interface. Since position
98
- * updates continuously, {@link Player#getPosition} is implemented as a getter
99
- * you can override on your Player. This getter will be called when a client
100
- * requests the position and should return the position of your player for the
101
- * client in microseconds.
102
- *
103
- * ```
104
- * player.getPosition() {
105
- * return realPlayer.getPositionInMicroseconds();
106
- * }
107
- * ```
108
- *
109
- * When your real player seeks to a new location, such as when someone clicks
110
- * on the time bar, you can notify clients of the new position by calling the
111
- * {@link Player#seeked} method. This will raise the `Seeked` signal on the
112
- * `org.mpris.MediaPlayer2.Player` interface with the given current time of the
113
- * player in microseconds.
114
- *
115
- * ```
116
- * realPlayer.on('seeked', (positionInMicroseconds) => {
117
- * player.seeked(positionInMicroseconds);
118
- * });
119
- * ```
120
- *
121
- * Clients can request to set position using the `Seek` and `SetPosition`
122
- * methods of the `org.mpris.MediaPlayer2.Player` interface. These requests are
123
- * implemented as events on the Player similar to the other requests.
124
- *
125
- * ```
126
- * player.on('seek', (offset) => {
127
- * // note that offset may be negative
128
- * let currentPosition = realPlayer.getPositionInMicroseconds();
129
- * let newPosition = currentPosition + offset;
130
- * realPlayer.setPosition(newPosition);
131
- * });
132
- *
133
- * player.on('position', (event) => {
134
- * // check that event.trackId is the current track before continuing.
135
- * realPlayer.setPosition(event.position);
136
- * });
137
- * ```
138
- *
139
- * @class Player
140
- * @param {
141
- * name: String,
142
- * identity: String,
143
- * supportedMimeTypes: string[],
144
- * supportedInterfaces: string[]
145
- * } options - Options for the player.
146
- * @param {String} options.name - Name on the bus to export to as `org.mpris.MediaPlayer2.{name}`.
147
- * @param {String} options.identity - Identity for the player to display on the root media player interface.
148
- * @param {Array} options.supportedMimeTypes - Mime types this player can open with the `org.mpris.MediaPlayer2.Open` method.
149
- * @param {Array} options.supportedInterfaces - The interfaces this player supports. Can include `'player'`, `'playlists'`, and `'trackList'`.
150
- * @property {String} identity - A friendly name to identify the media player to users.
151
- * @property {Boolean} fullscreen - Whether the media player is occupying the fullscreen.
152
- * @property {Array} supportedUriSchemes - The URI schemes supported by the media player.
153
- * @property {Array} supportedMimeTypes - The mime-types supported by the media player.
154
- * @property {Boolean} canQuit - Whether the player can quit.
155
- * @property {Boolean} canRaise - Whether the player can raise.
156
- * @property {Boolean} canSetFullscreen - Whether the player can be set to fullscreen.
157
- * @property {Boolean} hasTrackList - Indicates whether the /org/mpris/MediaPlayer2 object implements the org.mpris.MediaPlayer2.TrackList interface.
158
- * @property {String} desktopEntry - The basename of an installed .desktop file which complies with the Desktop entry specification, with the ".desktop" extension stripped.
159
- * @property {String} playbackStatus - The current playback status. May be "Playing", "Paused" or "Stopped".
160
- * @property {String} loopStatus - The current loop/repeat status. May be "None", "Track", or "Playlist".
161
- * @property {Boolean} shuffle - Whether the player is shuffling.
162
- * @property {Object} metadata - The metadata of the current element. If there is a current track, this must have a "mpris:trackid" entry (of D-Bus type "o") at the very least, which contains a D-Bus path that uniquely identifies this track.
163
- * @property {Number} volume - The volume level. (Double)
164
- * @property {Boolean} canControl - Whether the media player may be controlled over this interface.
165
- * @property {Boolean} canPause - Whether playback can be paused using Pause or PlayPause.
166
- * @property {Boolean} canPlay - Whether playback can be started using Play or PlayPause.
167
- * @property {Boolean} canSeek - Whether the client can control the playback position using Seek and SetPosition.
168
- * @property {Boolean} canGoNext - Whether the client can call the Next method on this interface and expect the current track to change.
169
- * @property {Boolean} canGoPrevious - Whether the client can call the Previous method on this interface and expect the current track to change.
170
- * @property {Number} rate - The current playback rate. (Double)
171
- * @property {Number} minimumRate - The minimum value which the Rate property can take. (Double)
172
- * @property {Number} maximumRate - The maximum value which the Rate property can take. (Double)
173
- * @property {Array} playlists - The current playlists set by {@link Player#setPlaylists}. (Not a DBus property).
174
- * @property {String} activePlaylist - The id of the currently-active playlist.
175
- */
176
- constructor(options) {
177
- super();
178
- _classPrivateMethodInitSpec(this, _Player_brand);
179
- this.name = options.name;
180
- this.supportedInterfaces = options.supportedInterfaces || ['player'];
181
- this._tracks = [];
182
- this.init(options);
183
- }
184
- init(opts) {
185
- this.serviceName = `org.mpris.MediaPlayer2.${this.name}`;
186
- dbus.validators.assertBusNameValid(this.serviceName);
187
- this._bus = dbus.sessionBus();
188
- this._bus.on('error', err => {
189
- this.emit('error', err);
190
- });
191
- this.interfaces = {};
192
- _assertClassBrand(_Player_brand, this, _addRootInterface).call(this, this._bus, opts);
193
- if (this.supportedInterfaces.indexOf('player') >= 0) {
194
- _assertClassBrand(_Player_brand, this, _addPlayerInterface).call(this, this._bus);
195
- }
196
- if (this.supportedInterfaces.indexOf('trackList') >= 0) {
197
- _assertClassBrand(_Player_brand, this, _addTracklistInterface).call(this, this._bus);
198
- }
199
- if (this.supportedInterfaces.indexOf('playlists') >= 0) {
200
- _assertClassBrand(_Player_brand, this, _addPlaylistsInterface).call(this, this._bus);
201
- }
202
- for (let k of Object.keys(this.interfaces)) {
203
- let iface = this.interfaces[k];
204
- this._bus.export(MPRIS_PATH, iface);
205
- }
206
- this._bus.requestName(this.serviceName, dbus.NameFlag.DO_NOT_QUEUE).then(reply => {
207
- if (reply === dbus.RequestNameReply.EXISTS) {
208
- this.serviceName = `${this.serviceName}.instance${process.pid}`;
209
- return this._bus.requestName(this.serviceName);
210
- }
211
- }).catch(err => {
212
- this.emit('error', err);
213
- });
214
- }
215
- /**
216
- * Get a valid object path with the `subpath` as the basename which is suitable
217
- * for use as an id.
218
- *
219
- * @name Player#objectPath
220
- * @function
221
- * @param {String} subpath - The basename of this path
222
- * @returns {String} - A valid object path that can be used as an id.
223
- */
224
- objectPath(subpath) {
225
- let path = `/org/node/mediaplayer/${this.name}`;
226
- if (subpath) {
227
- path += `/${subpath}`;
228
- }
229
- return path;
230
- }
231
- /**
232
- * Gets the position of this player. This method is intended to be overridden
233
- * by the user to return the position of the player in microseconds.
234
- *
235
- * @name Player#getPosition
236
- * @function
237
- * @returns {Number} - The current position of the player in microseconds. (Integer)
238
- */
239
- getPosition() {
240
- return 0;
241
- }
242
-
243
- /**
244
- * Emits the `Seeked` DBus signal to listening clients with the given position.
245
- *
246
- * @name Player#seeked
247
- * @function
248
- * @param {Number} position - The position in microseconds. (Integer)
249
- */
250
- seeked(position) {
251
- let seekTo = Math.floor(position || 0);
252
- if (isNaN(seekTo)) {
253
- throw new Error(`seeked expected a number (got ${position})`);
254
- }
255
- this.interfaces.player.Seeked(seekTo);
256
- }
257
- getTrackIndex(trackId) {
258
- for (let i = 0; i < this.tracks.length; i++) {
259
- let track = this.tracks[i];
260
- if (track['mpris:trackid'] === trackId) {
261
- return i;
262
- }
263
- }
264
- return -1;
265
- }
266
- getTrack(trackId) {
267
- return this.tracks[this.getTrackIndex(trackId)];
268
- }
269
- addTrack(track) {
270
- this.tracks.push(track);
271
- this.interfaces.tracklist.setTracks(this.tracks);
272
- let afterTrack = '/org/mpris/MediaPlayer2/TrackList/NoTrack';
273
- if (this.tracks.length > 2) {
274
- afterTrack = this.tracks[this.tracks.length - 2]['mpris:trackid'];
275
- }
276
- this.interfaces.tracklist.TrackAdded(afterTrack);
277
- }
278
- removeTrack(trackId) {
279
- let i = this.getTrackIndex(trackId);
280
- this.tracks.splice(i, 1);
281
- this.interfaces.tracklist.setTracks(this.tracks);
282
- this.interfaces.tracklist.TrackRemoved(trackId);
283
- }
284
-
285
- /**
286
- * Get the index of a playlist entry in the `playlists` list property of the
287
- * player from the given id.
288
- *
289
- * @name Player#getPlaylistIndex
290
- * @function
291
- * @param {String} playlistId - The id for the playlist entry.
292
- */
293
- getPlaylistIndex(playlistId) {
294
- for (let i = 0; i < this.playlists.length; i++) {
295
- let playlist = this.playlists[i];
296
- if (playlist.Id === playlistId) {
297
- return i;
298
- }
299
- }
300
- return -1;
301
- }
302
-
303
- /**
304
- * Set the list of playlists advertised to listeners on the bus. Each playlist
305
- * must have string members `Id`, `Name`, and `Icon`.
306
- *
307
- * @name Player#setPlaylists
308
- * @function
309
- * @param {Array} playlists - A list of playlists.
310
- */
311
- setPlaylists(playlists) {
312
- this.playlists = playlists;
313
- this.playlistCount = playlists.length;
314
- this.playlists.forEach(playlist => {
315
- if (playlist) {
316
- this.interfaces.playlists.PlaylistChanged(playlist);
317
- }
318
- });
319
- }
320
-
321
- /**
322
- * Set the playlist identified by `playlistId` to be the currently active
323
- * playlist.
324
- *
325
- * @name Player#setActivePlaylist
326
- * @function
327
- * @param {String} playlistId - The id of the playlist to activate.
328
- */
329
- setActivePlaylist(playlistId) {
330
- this.interfaces.playlists.setActivePlaylistId(playlistId);
331
- }
332
-
333
- /**
334
- * Enumerated value for the `playbackStatus` property of the player to indicate
335
- * a track is currently playing.
336
- *
337
- * @name Player#PLAYBACK_STATUS_PLAYING
338
- * @static
339
- * @constant
340
- */
341
- }
342
- function _addRootInterface(bus, opts) {
343
- this.interfaces.root = new RootInterface(this, opts);
344
- _assertClassBrand(_Player_brand, this, _addEventedPropertiesList).call(this, this.interfaces.root, ['Identity', 'Fullscreen', 'SupportedUriSchemes', 'SupportedMimeTypes', 'CanQuit', 'CanRaise', 'CanSetFullscreen', 'HasTrackList', 'DesktopEntry']);
345
- }
346
- function _addPlayerInterface(bus) {
347
- this.interfaces.player = new PlayerInterface(this);
348
- let eventedProps = ['PlaybackStatus', 'LoopStatus', 'Rate', 'Shuffle', 'Metadata', 'Volume', 'CanControl', 'CanPause', 'CanPlay', 'CanSeek', 'CanGoNext', 'CanGoPrevious', 'MinimumRate', 'MaximumRate'];
349
- _assertClassBrand(_Player_brand, this, _addEventedPropertiesList).call(this, this.interfaces.player, eventedProps);
350
- }
351
- function _addTracklistInterface(bus) {
352
- this.interfaces.tracklist = new TracklistInterface(this);
353
- _assertClassBrand(_Player_brand, this, _addEventedPropertiesList).call(this, this.interfaces.tracklist, ['CanEditTracks']);
354
- Object.defineProperty(this, 'tracks', {
355
- get: function () {
356
- return this._tracks;
357
- },
358
- set: function (value) {
359
- this._tracks = value;
360
- this.interfaces.tracklist.TrackListReplaced(value);
361
- },
362
- enumerable: true,
363
- configurable: true
364
- });
365
- }
366
- function _addPlaylistsInterface(bus) {
367
- this.interfaces.playlists = new PlaylistsInterface(this);
368
- _assertClassBrand(_Player_brand, this, _addEventedPropertiesList).call(this, this.interfaces.playlists, ['PlaylistCount', 'ActivePlaylist']);
369
- }
370
- function _addEventedProperty(iface, name) {
371
- let localName = lcfirst(name);
372
- Object.defineProperty(this, localName, {
373
- get: function () {
374
- let value = iface[name];
375
- if (name === 'ActivePlaylist') {
376
- return types.playlistToPlain(value);
377
- } else if (name === 'Metadata') {
378
- return types.metadataToPlain(value);
379
- }
380
- return value;
381
- },
382
- set: function (value) {
383
- iface.setProperty(name, value);
384
- },
385
- enumerable: true,
386
- configurable: true
387
- });
388
- }
389
- function _addEventedPropertiesList(iface, props) {
390
- for (let i = 0; i < props.length; i++) {
391
- _assertClassBrand(_Player_brand, this, _addEventedProperty).call(this, iface, props[i]);
392
- }
393
- }
394
- _defineProperty(Player, "PLAYBACK_STATUS_PLAYING", constants.PLAYBACK_STATUS_PLAYING);
395
- /**
396
- * Enumerated value for the `playbackStatus` property of the player to indicate
397
- * a track is currently paused.
398
- *
399
- * @name Player#PLAYBACK_STATUS_PAUSED
400
- * @static
401
- * @constant
402
- */
403
- _defineProperty(Player, "PLAYBACK_STATUS_PAUSED", constants.PLAYBACK_STATUS_PAUSED);
404
- /**
405
- * Enumerated value for the `playbackStatus` property of the player to indicate
406
- * there is no track currently playing.
407
- *
408
- * @name Player#PLAYBACK_STATUS_STOPPED
409
- * @static
410
- * @constant
411
- */
412
- _defineProperty(Player, "PLAYBACK_STATUS_STOPPED", constants.PLAYBACK_STATUS_STOPPED);
413
- /**
414
- * Enumerated value for the `loopStatus` property of the player to indicate
415
- * playback will stop when there are no more tracks to play.
416
- *
417
- * @name Player#LOOP_STATUS_NONE
418
- * @static
419
- * @constant
420
- */
421
- _defineProperty(Player, "LOOP_STATUS_NONE", constants.LOOP_STATUS_NONE);
422
- /**
423
- * Enumerated value for the `loopStatus` property of the player to indicate the
424
- * current track will start again from the beginning once it has finished
425
- * playing.
426
- *
427
- * @name Player#LOOP_STATUS_TRACK
428
- * @static
429
- * @constant
430
- */
431
- _defineProperty(Player, "LOOP_STATUS_TRACK", constants.LOOP_STATUS_TRACK);
432
- /**
433
- * Enumerated value for the `loopStatus` property of the player to indicate the
434
- * playback loops through a list of tracks.
435
- *
436
- * @name Player#LOOP_STATUS_PLAYLIST
437
- * @static
438
- * @constant
439
- */
440
- _defineProperty(Player, "LOOP_STATUS_PLAYLIST", constants.LOOP_STATUS_PLAYLIST);
441
- module.exports = Player;
442
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["require","install","EventEmitter","dbus","PlayerInterface","RootInterface","PlaylistsInterface","TracklistInterface","types","constants","MPRIS_PATH","lcfirst","str","toLowerCase","substring","_Player_brand","WeakSet","Player","constructor","options","_classPrivateMethodInitSpec","name","supportedInterfaces","_tracks","init","opts","serviceName","validators","assertBusNameValid","_bus","sessionBus","on","err","emit","interfaces","_assertClassBrand","_addRootInterface","call","indexOf","_addPlayerInterface","_addTracklistInterface","_addPlaylistsInterface","k","Object","keys","iface","export","requestName","NameFlag","DO_NOT_QUEUE","then","reply","RequestNameReply","EXISTS","process","pid","catch","objectPath","subpath","path","getPosition","seeked","position","seekTo","Math","floor","isNaN","Error","player","Seeked","getTrackIndex","trackId","i","tracks","length","track","getTrack","addTrack","push","tracklist","setTracks","afterTrack","TrackAdded","removeTrack","splice","TrackRemoved","getPlaylistIndex","playlistId","playlists","playlist","Id","setPlaylists","playlistCount","forEach","PlaylistChanged","setActivePlaylist","setActivePlaylistId","bus","root","_addEventedPropertiesList","eventedProps","defineProperty","get","set","value","TrackListReplaced","enumerable","configurable","_addEventedProperty","localName","playlistToPlain","metadataToPlain","setProperty","props","_defineProperty","PLAYBACK_STATUS_PLAYING","PLAYBACK_STATUS_PAUSED","PLAYBACK_STATUS_STOPPED","LOOP_STATUS_NONE","LOOP_STATUS_TRACK","LOOP_STATUS_PLAYLIST","module","exports"],"sourceRoot":"../src/","sources":["index.js"],"sourcesContent":["require('source-map-support').install();\n\nconst { EventEmitter } = require('events');\n\nconst dbus = require('@jellybrick/dbus-next');\nconst PlayerInterface = require('./interfaces/player');\nconst RootInterface = require('./interfaces/root');\nconst PlaylistsInterface = require('./interfaces/playlists');\nconst TracklistInterface = require('./interfaces/tracklist');\nconst types = require('./interfaces/types');\nconst constants = require('./constants');\n\nconst MPRIS_PATH = '/org/mpris/MediaPlayer2';\n\nfunction lcfirst(str) {\n return str[0].toLowerCase() + str.substring(1);\n}\n\nclass Player extends EventEmitter {\n /**\n * Construct a new Player and export it on the DBus session bus.\n *\n * For more information about the properties of this class, see [the MPRIS DBus Interface Specification](https://specifications.freedesktop.org/mpris-spec/latest/).\n *\n * Method Call Events\n * ------------------\n *\n * The Player is an `EventEmitter` that emits events when the corresponding\n * methods are called on the DBus interface over the wire.\n *\n * The Player emits events whenever the corresponding methods on the DBus\n * interface are called.\n *\n * * `raise` - Brings the media player's user interface to the front using any appropriate mechanism available.\n * * `quit` - Causes the media player to stop running.\n * * `next` - Skips to the next track in the tracklist.\n * * `previous` - Skips to the previous track in the tracklist.\n * * `pause` - Pauses playback.\n * * `playPause` - Pauses playback. If playback is already paused, resumes playback. If playback is stopped, starts playback.\n * * `stop` - Stops playback.\n * * `play` - Starts or resumes playback.\n * * `seek` - Seeks forward in the current track by the specified number of microseconds. With event data `offset`.\n * * `position` - Sets the current track position in microseconds. With event data `{ trackId, position }`.\n * * `open` - Opens the Uri given as an argument. With event data `{ uri }`.\n * * `volume` - Sets the volume of the player. With event data `volume` (between 0.0 and 1.0).\n * * `shuffle` - Sets whether shuffle is enabled on the player. With event data `shuffleStatus` (boolean).\n * * `rate` - Sets the playback rate of the player. A value of 1.0 is the normal rate. With event data `rate`.\n * * `loopStatus` - Sets the loop status of the player to either 'None', 'Track', or 'Playlist'. With event data `loopStatus`.\n * * `activatePlaylist` - Starts playing the given playlist. With event data `playlistId`.\n *\n * The Player may also emit an `error` event with the underlying Node `Error`\n * as the event data. After receiving this event, the Player may be\n * disconnected.\n *\n * ```\n * player.on('play', () => {\n * realPlayer.play();\n * });\n *\n * player.on('shuffle', (enableShuffle) => {\n * realPlayer.setShuffle(enableShuffle);\n * player.shuffle = enableShuffle;\n * });\n * ```\n *\n * Player Properties\n * -----------------\n *\n * Player properties (documented below) should be kept up to date to reflect\n * the state of your real player. These properties can be gotten by the client\n * through the `org.freedesktop.DBus.Properties` interface which will return\n * the value currently set on the player. Setting these properties on the\n * player to a different value will emit the `PropertiesChanged` signal on the\n * properties interface to notify clients that properties of the player have\n * changed.\n *\n * ```\n * realPlayer.on('shuffle:changed', (shuffleEnabled) => {\n * player.shuffle = shuffleEnabled;\n * });\n *\n * realPlayer.on('play', () => {\n * player.playbackStatus = 'Playing';\n * });\n * ```\n *\n * Player Position\n * ---------------\n *\n * Clients can get the position of your player by getting the `Position`\n * property of the `org.mpris.MediaPlayer2.Player` interface. Since position\n * updates continuously, {@link Player#getPosition} is implemented as a getter\n * you can override on your Player. This getter will be called when a client\n * requests the position and should return the position of your player for the\n * client in microseconds.\n *\n * ```\n * player.getPosition() {\n * return realPlayer.getPositionInMicroseconds();\n * }\n * ```\n *\n * When your real player seeks to a new location, such as when someone clicks\n * on the time bar, you can notify clients of the new position by calling the\n * {@link Player#seeked} method. This will raise the `Seeked` signal on the\n * `org.mpris.MediaPlayer2.Player` interface with the given current time of the\n * player in microseconds.\n *\n * ```\n * realPlayer.on('seeked', (positionInMicroseconds) => {\n * player.seeked(positionInMicroseconds);\n * });\n * ```\n *\n * Clients can request to set position using the `Seek` and `SetPosition`\n * methods of the `org.mpris.MediaPlayer2.Player` interface. These requests are\n * implemented as events on the Player similar to the other requests.\n *\n * ```\n * player.on('seek', (offset) => {\n * // note that offset may be negative\n * let currentPosition = realPlayer.getPositionInMicroseconds();\n * let newPosition = currentPosition + offset;\n * realPlayer.setPosition(newPosition);\n * });\n *\n * player.on('position', (event) => {\n * // check that event.trackId is the current track before continuing.\n * realPlayer.setPosition(event.position);\n * });\n * ```\n *\n * @class Player\n * @param {\n * name: String,\n * identity: String,\n * supportedMimeTypes: string[],\n * supportedInterfaces: string[]\n * } options - Options for the player.\n * @param {String} options.name - Name on the bus to export to as `org.mpris.MediaPlayer2.{name}`.\n * @param {String} options.identity - Identity for the player to display on the root media player interface.\n * @param {Array} options.supportedMimeTypes - Mime types this player can open with the `org.mpris.MediaPlayer2.Open` method.\n * @param {Array} options.supportedInterfaces - The interfaces this player supports. Can include `'player'`, `'playlists'`, and `'trackList'`.\n * @property {String} identity - A friendly name to identify the media player to users.\n * @property {Boolean} fullscreen - Whether the media player is occupying the fullscreen.\n * @property {Array} supportedUriSchemes - The URI schemes supported by the media player.\n * @property {Array} supportedMimeTypes - The mime-types supported by the media player.\n * @property {Boolean} canQuit - Whether the player can quit.\n * @property {Boolean} canRaise - Whether the player can raise.\n * @property {Boolean} canSetFullscreen - Whether the player can be set to fullscreen.\n * @property {Boolean} hasTrackList - Indicates whether the /org/mpris/MediaPlayer2 object implements the org.mpris.MediaPlayer2.TrackList interface.\n * @property {String} desktopEntry - The basename of an installed .desktop file which complies with the Desktop entry specification, with the \".desktop\" extension stripped.\n * @property {String} playbackStatus - The current playback status. May be \"Playing\", \"Paused\" or \"Stopped\".\n * @property {String} loopStatus - The current loop/repeat status. May be \"None\", \"Track\", or \"Playlist\".\n * @property {Boolean} shuffle - Whether the player is shuffling.\n * @property {Object} metadata - The metadata of the current element. If there is a current track, this must have a \"mpris:trackid\" entry (of D-Bus type \"o\") at the very least, which contains a D-Bus path that uniquely identifies this track.\n * @property {Number} volume - The volume level. (Double)\n * @property {Boolean} canControl - Whether the media player may be controlled over this interface.\n * @property {Boolean} canPause - Whether playback can be paused using Pause or PlayPause.\n * @property {Boolean} canPlay - Whether playback can be started using Play or PlayPause.\n * @property {Boolean} canSeek - Whether the client can control the playback position using Seek and SetPosition.\n * @property {Boolean} canGoNext - Whether the client can call the Next method on this interface and expect the current track to change.\n * @property {Boolean} canGoPrevious - Whether the client can call the Previous method on this interface and expect the current track to change.\n * @property {Number} rate - The current playback rate. (Double)\n * @property {Number} minimumRate - The minimum value which the Rate property can take. (Double)\n * @property {Number} maximumRate - The maximum value which the Rate property can take. (Double)\n * @property {Array} playlists - The current playlists set by {@link Player#setPlaylists}. (Not a DBus property).\n * @property {String} activePlaylist - The id of the currently-active playlist.\n */\n constructor(options) {\n super();\n\n this.name = options.name;\n this.supportedInterfaces = options.supportedInterfaces || ['player'];\n this._tracks = [];\n this.init(options);\n }\n\n init(opts) {\n this.serviceName = `org.mpris.MediaPlayer2.${this.name}`;\n dbus.validators.assertBusNameValid(this.serviceName);\n\n this._bus = dbus.sessionBus();\n\n this._bus.on('error', (err) => {\n this.emit('error', err);\n });\n\n this.interfaces = {};\n\n this.#addRootInterface(this._bus, opts);\n\n if (this.supportedInterfaces.indexOf('player') >= 0) {\n this.#addPlayerInterface(this._bus);\n }\n if (this.supportedInterfaces.indexOf('trackList') >= 0) {\n this.#addTracklistInterface(this._bus);\n }\n if (this.supportedInterfaces.indexOf('playlists') >= 0) {\n this.#addPlaylistsInterface(this._bus);\n }\n\n for (let k of Object.keys(this.interfaces)) {\n let iface = this.interfaces[k];\n this._bus.export(MPRIS_PATH, iface);\n }\n\n this._bus.requestName(this.serviceName, dbus.NameFlag.DO_NOT_QUEUE)\n .then((reply) => {\n if (reply === dbus.RequestNameReply.EXISTS) {\n this.serviceName = `${this.serviceName}.instance${process.pid}`;\n return this._bus.requestName(this.serviceName);\n }\n })\n .catch((err) => {\n this.emit('error', err);\n });\n }\n\n #addRootInterface(bus, opts) {\n this.interfaces.root = new RootInterface(this, opts);\n this.#addEventedPropertiesList(this.interfaces.root,\n ['Identity', 'Fullscreen', 'SupportedUriSchemes', 'SupportedMimeTypes',\n 'CanQuit', 'CanRaise', 'CanSetFullscreen', 'HasTrackList',\n 'DesktopEntry']);\n }\n\n #addPlayerInterface(bus) {\n this.interfaces.player = new PlayerInterface(this);\n let eventedProps = ['PlaybackStatus', 'LoopStatus', 'Rate', 'Shuffle',\n 'Metadata', 'Volume', 'CanControl', 'CanPause', 'CanPlay', 'CanSeek',\n 'CanGoNext', 'CanGoPrevious', 'MinimumRate', 'MaximumRate'];\n this.#addEventedPropertiesList(this.interfaces.player, eventedProps);\n }\n\n #addTracklistInterface(bus) {\n this.interfaces.tracklist = new TracklistInterface(this);\n this.#addEventedPropertiesList(this.interfaces.tracklist, ['CanEditTracks']);\n\n Object.defineProperty(this, 'tracks', {\n get: function() {\n return this._tracks;\n },\n set: function(value) {\n this._tracks = value;\n this.interfaces.tracklist.TrackListReplaced(value);\n },\n enumerable: true,\n configurable: true\n });\n }\n\n #addPlaylistsInterface(bus) {\n this.interfaces.playlists = new PlaylistsInterface(this);\n this.#addEventedPropertiesList(this.interfaces.playlists,\n ['PlaylistCount', 'ActivePlaylist']);\n }\n\n /**\n * Get a valid object path with the `subpath` as the basename which is suitable\n * for use as an id.\n *\n * @name Player#objectPath\n * @function\n * @param {String} subpath - The basename of this path\n * @returns {String} - A valid object path that can be used as an id.\n */\n objectPath(subpath) {\n let path = `/org/node/mediaplayer/${this.name}`;\n if (subpath) {\n path += `/${subpath}`;\n }\n return path;\n }\n\n #addEventedProperty(iface, name) {\n let localName = lcfirst(name);\n\n Object.defineProperty(this, localName, {\n get: function() {\n let value = iface[name];\n if (name === 'ActivePlaylist') {\n return types.playlistToPlain(value);\n } else if (name === 'Metadata') {\n return types.metadataToPlain(value);\n }\n return value;\n },\n set: function(value) {\n iface.setProperty(name, value);\n },\n enumerable: true,\n configurable: true\n });\n }\n\n #addEventedPropertiesList(iface, props) {\n for (let i = 0; i < props.length; i++) {\n this.#addEventedProperty(iface, props[i]);\n }\n }\n\n /**\n * Gets the position of this player. This method is intended to be overridden\n * by the user to return the position of the player in microseconds.\n *\n * @name Player#getPosition\n * @function\n * @returns {Number} - The current position of the player in microseconds. (Integer)\n */\n getPosition() {\n return 0;\n }\n\n /**\n * Emits the `Seeked` DBus signal to listening clients with the given position.\n *\n * @name Player#seeked\n * @function\n * @param {Number} position - The position in microseconds. (Integer)\n */\n seeked(position) {\n let seekTo = Math.floor(position || 0);\n if (isNaN(seekTo)) {\n throw new Error(`seeked expected a number (got ${position})`);\n }\n this.interfaces.player.Seeked(seekTo);\n }\n\n getTrackIndex(trackId) {\n for (let i = 0; i < this.tracks.length; i++) {\n let track = this.tracks[i];\n\n if (track['mpris:trackid'] === trackId) {\n return i;\n }\n }\n\n return -1;\n }\n\n getTrack(trackId) {\n return this.tracks[this.getTrackIndex(trackId)];\n }\n\n addTrack(track) {\n this.tracks.push(track);\n this.interfaces.tracklist.setTracks(this.tracks);\n\n let afterTrack = '/org/mpris/MediaPlayer2/TrackList/NoTrack';\n if (this.tracks.length > 2) {\n afterTrack = this.tracks[this.tracks.length - 2]['mpris:trackid'];\n }\n this.interfaces.tracklist.TrackAdded(afterTrack);\n }\n\n removeTrack(trackId) {\n let i = this.getTrackIndex(trackId);\n this.tracks.splice(i, 1);\n this.interfaces.tracklist.setTracks(this.tracks);\n\n this.interfaces.tracklist.TrackRemoved(trackId);\n }\n\n /**\n * Get the index of a playlist entry in the `playlists` list property of the\n * player from the given id.\n *\n * @name Player#getPlaylistIndex\n * @function\n * @param {String} playlistId - The id for the playlist entry.\n */\n getPlaylistIndex(playlistId) {\n for (let i = 0; i < this.playlists.length; i++) {\n let playlist = this.playlists[i];\n\n if (playlist.Id === playlistId) {\n return i;\n }\n }\n\n return -1;\n }\n\n /**\n * Set the list of playlists advertised to listeners on the bus. Each playlist\n * must have string members `Id`, `Name`, and `Icon`.\n *\n * @name Player#setPlaylists\n * @function\n * @param {Array} playlists - A list of playlists.\n */\n setPlaylists(playlists) {\n this.playlists = playlists;\n this.playlistCount = playlists.length;\n\n this.playlists.forEach((playlist) => {\n if (playlist) {\n this.interfaces.playlists.PlaylistChanged(playlist);\n }\n });\n }\n\n /**\n * Set the playlist identified by `playlistId` to be the currently active\n * playlist.\n *\n * @name Player#setActivePlaylist\n * @function\n * @param {String} playlistId - The id of the playlist to activate.\n */\n setActivePlaylist(playlistId) {\n this.interfaces.playlists.setActivePlaylistId(playlistId);\n }\n\n /**\n * Enumerated value for the `playbackStatus` property of the player to indicate\n * a track is currently playing.\n *\n * @name Player#PLAYBACK_STATUS_PLAYING\n * @static\n * @constant\n */\n static PLAYBACK_STATUS_PLAYING = constants.PLAYBACK_STATUS_PLAYING;\n /**\n * Enumerated value for the `playbackStatus` property of the player to indicate\n * a track is currently paused.\n *\n * @name Player#PLAYBACK_STATUS_PAUSED\n * @static\n * @constant\n */\n static PLAYBACK_STATUS_PAUSED = constants.PLAYBACK_STATUS_PAUSED;\n\n /**\n * Enumerated value for the `playbackStatus` property of the player to indicate\n * there is no track currently playing.\n *\n * @name Player#PLAYBACK_STATUS_STOPPED\n * @static\n * @constant\n */\n static PLAYBACK_STATUS_STOPPED = constants.PLAYBACK_STATUS_STOPPED;\n\n /**\n * Enumerated value for the `loopStatus` property of the player to indicate\n * playback will stop when there are no more tracks to play.\n *\n * @name Player#LOOP_STATUS_NONE\n * @static\n * @constant\n */\n static LOOP_STATUS_NONE = constants.LOOP_STATUS_NONE;\n\n /**\n * Enumerated value for the `loopStatus` property of the player to indicate the\n * current track will start again from the beginning once it has finished\n * playing.\n *\n * @name Player#LOOP_STATUS_TRACK\n * @static\n * @constant\n */\n static LOOP_STATUS_TRACK = constants.LOOP_STATUS_TRACK;\n\n /**\n * Enumerated value for the `loopStatus` property of the player to indicate the\n * playback loops through a list of tracks.\n *\n * @name Player#LOOP_STATUS_PLAYLIST\n * @static\n * @constant\n */\n static LOOP_STATUS_PLAYLIST = constants.LOOP_STATUS_PLAYLIST;\n}\n\nmodule.exports = Player;"],"mappings":";;;;;;;;AAAAA,OAAO,CAAC,oBAAoB,CAAC,CAACC,OAAO,CAAC,CAAC;AAEvC,MAAM;EAAEC;AAAa,CAAC,GAAGF,OAAO,CAAC,QAAQ,CAAC;AAE1C,MAAMG,IAAI,GAAGH,OAAO,CAAC,uBAAuB,CAAC;AAC7C,MAAMI,eAAe,GAAGJ,OAAO,CAAC,qBAAqB,CAAC;AACtD,MAAMK,aAAa,GAAGL,OAAO,CAAC,mBAAmB,CAAC;AAClD,MAAMM,kBAAkB,GAAGN,OAAO,CAAC,wBAAwB,CAAC;AAC5D,MAAMO,kBAAkB,GAAGP,OAAO,CAAC,wBAAwB,CAAC;AAC5D,MAAMQ,KAAK,GAAGR,OAAO,CAAC,oBAAoB,CAAC;AAC3C,MAAMS,SAAS,GAAGT,OAAO,CAAC,aAAa,CAAC;AAExC,MAAMU,UAAU,GAAG,yBAAyB;AAE5C,SAASC,OAAOA,CAACC,GAAG,EAAE;EACpB,OAAOA,GAAG,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC,GAAGD,GAAG,CAACE,SAAS,CAAC,CAAC,CAAC;AAChD;AAAC,IAAAC,aAAA,oBAAAC,OAAA;AAED,MAAMC,MAAM,SAASf,YAAY,CAAC;EAChC;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC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","ignoreList":[]}
@@ -1,49 +0,0 @@
1
- "use strict";
2
-
3
- const dbus = require('@jellybrick/dbus-next');
4
- const types = require('./types');
5
- const deepEqual = require('deep-equal');
6
- const constants = require('../constants');
7
- const logging = require('../logging');
8
- const {
9
- Interface
10
- } = dbus.interface;
11
- class MprisInterface extends Interface {
12
- constructor(name, player) {
13
- super(name);
14
- this.player = player;
15
- }
16
- _setPropertyInternal(property, valueDbus) {
17
- // nothing is currently settable internally that needs conversion to plain
18
- this.player.emit(property[0].toLowerCase() + property.substring(1), valueDbus);
19
- }
20
- setProperty(property, valuePlain) {
21
- // convert the plain value to a dbus value (default to the plain value)
22
- let valueDbus = valuePlain;
23
- if (property === 'Metadata') {
24
- valueDbus = types.metadataToDbus(valuePlain);
25
- } else if (property === 'ActivePlaylist') {
26
- if (valuePlain) {
27
- valueDbus = [true, types.playlistToDbus(valuePlain)];
28
- } else {
29
- valueDbus = [false, types.emptyPlaylist];
30
- }
31
- } else if (property === 'Tracks') {
32
- valueDbus = valuePlain.filter(t => t['mpris:trackid']).map(t => t['mpris:trackid']);
33
- }
34
- if (!deepEqual(this[`_${property}`], valueDbus)) {
35
- this[`_${property}`] = valueDbus;
36
- if (property === 'LoopStatus' && !constants.isLoopStatusValid(valuePlain)) {
37
- logging.warn(`setting player loop status to an invalid value: ${valuePlain}`);
38
- } else if (property === 'PlaybackStatus' && !constants.isPlaybackStatusValid(valuePlain)) {
39
- logging.warn(`setting player playback status to an invalid value: ${valuePlain}`);
40
- } else {
41
- let changedProperties = {};
42
- changedProperties[property] = valueDbus;
43
- Interface.emitPropertiesChanged(this, changedProperties);
44
- }
45
- }
46
- }
47
- }
48
- module.exports = MprisInterface;
49
- //# sourceMappingURL=mpris-interface.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mpris-interface.js","names":["dbus","require","types","deepEqual","constants","logging","Interface","interface","MprisInterface","constructor","name","player","_setPropertyInternal","property","valueDbus","emit","toLowerCase","substring","setProperty","valuePlain","metadataToDbus","playlistToDbus","emptyPlaylist","filter","t","map","isLoopStatusValid","warn","isPlaybackStatusValid","changedProperties","emitPropertiesChanged","module","exports"],"sourceRoot":"../../src/","sources":["interfaces/mpris-interface.js"],"sourcesContent":["const dbus = require('@jellybrick/dbus-next');\nconst types = require('./types');\nconst deepEqual = require('deep-equal');\nconst constants = require('../constants');\nconst logging = require('../logging');\n\nconst { Interface } = dbus.interface;\n\nclass MprisInterface extends Interface {\n constructor(name, player) {\n super(name);\n this.player = player;\n }\n\n _setPropertyInternal(property, valueDbus) {\n // nothing is currently settable internally that needs conversion to plain\n this.player.emit(property[0].toLowerCase() + property.substring(1), valueDbus);\n }\n\n setProperty(property, valuePlain) {\n // convert the plain value to a dbus value (default to the plain value)\n let valueDbus = valuePlain;\n\n if (property === 'Metadata') {\n valueDbus = types.metadataToDbus(valuePlain);\n } else if (property === 'ActivePlaylist') {\n if (valuePlain) {\n valueDbus = [ true, types.playlistToDbus(valuePlain) ];\n } else {\n valueDbus = [ false, types.emptyPlaylist ];\n }\n } else if (property === 'Tracks') {\n valueDbus =\n valuePlain.filter((t) => t['mpris:trackid']).map((t) => t['mpris:trackid']);\n }\n\n if (!deepEqual(this[`_${property}`], valueDbus)) {\n this[`_${property}`] = valueDbus;\n\n if (property === 'LoopStatus' && !constants.isLoopStatusValid(valuePlain)) {\n logging.warn(`setting player loop status to an invalid value: ${valuePlain}`);\n } else if (property === 'PlaybackStatus' && !constants.isPlaybackStatusValid(valuePlain)) {\n logging.warn(`setting player playback status to an invalid value: ${valuePlain}`);\n } else {\n let changedProperties = {};\n changedProperties[property] = valueDbus;\n Interface.emitPropertiesChanged(this, changedProperties);\n }\n }\n }\n}\n\nmodule.exports = MprisInterface;\n"],"mappings":";;AAAA,MAAMA,IAAI,GAAGC,OAAO,CAAC,uBAAuB,CAAC;AAC7C,MAAMC,KAAK,GAAGD,OAAO,CAAC,SAAS,CAAC;AAChC,MAAME,SAAS,GAAGF,OAAO,CAAC,YAAY,CAAC;AACvC,MAAMG,SAAS,GAAGH,OAAO,CAAC,cAAc,CAAC;AACzC,MAAMI,OAAO,GAAGJ,OAAO,CAAC,YAAY,CAAC;AAErC,MAAM;EAAEK;AAAU,CAAC,GAAGN,IAAI,CAACO,SAAS;AAEpC,MAAMC,cAAc,SAASF,SAAS,CAAC;EACrCG,WAAWA,CAACC,IAAI,EAAEC,MAAM,EAAE;IACxB,KAAK,CAACD,IAAI,CAAC;IACX,IAAI,CAACC,MAAM,GAAGA,MAAM;EACtB;EAEAC,oBAAoBA,CAACC,QAAQ,EAAEC,SAAS,EAAE;IACxC;IACA,IAAI,CAACH,MAAM,CAACI,IAAI,CAACF,QAAQ,CAAC,CAAC,CAAC,CAACG,WAAW,CAAC,CAAC,GAAGH,QAAQ,CAACI,SAAS,CAAC,CAAC,CAAC,EAAEH,SAAS,CAAC;EAChF;EAEAI,WAAWA,CAACL,QAAQ,EAAEM,UAAU,EAAE;IAChC;IACA,IAAIL,SAAS,GAAGK,UAAU;IAE1B,IAAIN,QAAQ,KAAK,UAAU,EAAE;MAC3BC,SAAS,GAAGZ,KAAK,CAACkB,cAAc,CAACD,UAAU,CAAC;IAC9C,CAAC,MAAM,IAAIN,QAAQ,KAAK,gBAAgB,EAAE;MACxC,IAAIM,UAAU,EAAE;QACdL,SAAS,GAAG,CAAE,IAAI,EAAEZ,KAAK,CAACmB,cAAc,CAACF,UAAU,CAAC,CAAE;MACxD,CAAC,MAAM;QACLL,SAAS,GAAG,CAAE,KAAK,EAAEZ,KAAK,CAACoB,aAAa,CAAE;MAC5C;IACF,CAAC,MAAM,IAAIT,QAAQ,KAAK,QAAQ,EAAE;MAChCC,SAAS,GACPK,UAAU,CAACI,MAAM,CAAEC,CAAC,IAAKA,CAAC,CAAC,eAAe,CAAC,CAAC,CAACC,GAAG,CAAED,CAAC,IAAKA,CAAC,CAAC,eAAe,CAAC,CAAC;IAC/E;IAEA,IAAI,CAACrB,SAAS,CAAC,IAAI,CAAC,IAAIU,QAAQ,EAAE,CAAC,EAAEC,SAAS,CAAC,EAAE;MAC/C,IAAI,CAAC,IAAID,QAAQ,EAAE,CAAC,GAAGC,SAAS;MAEhC,IAAID,QAAQ,KAAK,YAAY,IAAI,CAACT,SAAS,CAACsB,iBAAiB,CAACP,UAAU,CAAC,EAAE;QACzEd,OAAO,CAACsB,IAAI,CAAC,mDAAmDR,UAAU,EAAE,CAAC;MAC/E,CAAC,MAAM,IAAIN,QAAQ,KAAK,gBAAgB,IAAI,CAACT,SAAS,CAACwB,qBAAqB,CAACT,UAAU,CAAC,EAAE;QACxFd,OAAO,CAACsB,IAAI,CAAC,uDAAuDR,UAAU,EAAE,CAAC;MACnF,CAAC,MAAM;QACL,IAAIU,iBAAiB,GAAG,CAAC,CAAC;QAC1BA,iBAAiB,CAAChB,QAAQ,CAAC,GAAGC,SAAS;QACvCR,SAAS,CAACwB,qBAAqB,CAAC,IAAI,EAAED,iBAAiB,CAAC;MAC1D;IACF;EACF;AACF;AAEAE,MAAM,CAACC,OAAO,GAAGxB,cAAc","ignoreList":[]}