UNPKG

spotify-service-rg

Version:

This is a Angular service for connecting to and using Spotify API.

394 lines 36 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; export class SpotifyRgService { /** * @param {?} http */ constructor(http) { this.http = http; this.baseUrl = "https://api.spotify.com/v1"; } /** * @return {?} */ login() { window.location.href = 'https://accounts.spotify.com/authorize' + '?response_type=token' + '&client_id=' + this.clientId + (this.scopes ? '&scope=' + encodeURIComponent(this.scopes) : '') + '&redirect_uri=' + encodeURIComponent(this.callBackUrl); } //Setters for the configuration properties /** * @param {?} clientId * @return {?} */ setClientId(clientId) { this.clientId = clientId; } /** * @param {?} callBackUrl * @return {?} */ setCallBackUrl(callBackUrl) { this.callBackUrl = callBackUrl; } /** * @param {?} scopes * @return {?} */ setScopes(scopes) { this.scopes = scopes; } /** * @param {?} token * @return {?} */ setToken(token) { this.token = token; } /** * \@description Returns track * @param {?} trackId * @return {?} */ getTrack(trackId) { return this.apiGet("/tracks/" + trackId, null, this.getHeaders()); } /** * \@description Returns tracks * @param {?} trackIds * @return {?} */ getTracks(trackIds) { /** @type {?} */ const t = encodeURIComponent(trackIds); return this.apiGet("/tracks/?ids=" + t, null, this.getHeaders()); } /** * \@description Returns album * @param {?} albumId * @return {?} */ getAlbum(albumId) { return this.apiGet("/albums/" + albumId, null, this.getHeaders()); } /** * \@description Returns albums * @param {?} albumIds * @return {?} */ getAlbums(albumIds) { /** @type {?} */ const a = encodeURIComponent(albumIds); return this.apiGet("/albums/?ids=" + a, null, this.getHeaders()); } /** * \@description Returns albums tracks * @param {?} albumId * @return {?} */ getAlbumsTracks(albumId) { return this.apiGet("/albums/" + albumId + "/tracks", null, this.getHeaders()); } /** * \@description Returns artist * @param {?} artistId Artists spotify ID. * @return {?} */ getArtist(artistId) { return this.apiGet("/artists/" + artistId, null, this.getHeaders()); } /** * \@description Returns artists * @param {?} artistIds * @return {?} */ getArtists(artistIds) { /** @type {?} */ const a = encodeURIComponent(artistIds); return this.apiGet("/artists/?ids=" + a, null, this.getHeaders()); } /** * \@description Returns artists albums * @param {?} artistId Artists Spotify ID. * @return {?} */ getArtistsAlbums(artistId) { return this.apiGet("/artists/" + artistId + "/albums", null, this.getHeaders()); } /** * \@description Returns artists top tracks * @param {?} artistId Artists Spotify ID. * @param {?=} countryCode Country code in 2 char Format. For example FI. Defaults to extracting country code from token. * @return {?} */ getArtistsTopTracks(artistId, countryCode) { /** @type {?} */ var countryCode = (countryCode != null && countryCode.length == 2) ? countryCode : "from_token"; return this.apiGet("/artists/" + artistId + "/top-tracks?country=" + countryCode, null, this.getHeaders()); } /** * \@description Returns the user assosiated with auth token * @param {?} userId The Spotify User id * @return {?} */ getUserById(userId) { return this.apiGet('/users/' + userId, null, this.getHeaders()); } /** * \@description Returns the user assosiated with auth token * @return {?} */ getUser() { return this.apiGet('/me', null, this.getHeaders()); } /** * \@description Returns current users top tracks * @param {?} timeRange The range of time results are returned from. Use short_term, medium_term or long_term. Defaults to long_term. * @param {?=} count Amount of tracks returned. Max value 50. Defaults to 50. * @return {?} */ getUsersTopTracks(timeRange, count) { /** @type {?} */ const params = { //set backup default values 'time_range': timeRange == null ? 'long_term' : timeRange, 'limit': count == null ? '50' : count }; return this.apiGet("/me/top/tracks", params, this.getHeaders()); } /** * \@description Returns users playlists * @param {?} userId Users Spotify Id * @return {?} */ getUsersPlaylists(userId) { return this.apiGet('/users/' + userId + '/playlists', null, this.getHeaders()); } /** * \@description Returns recommendations based on seeds. Max 5 seeds allowed (thats total so for example 3 artists and 2 tracks) * @param {?} seedArtists Comma separated list of artist seed Ids * @param {?} seedTracks Comma separated list of track seed Ids * @return {?} */ getRecommendedTracks(seedArtists, seedTracks) { /** @type {?} */ const sA = encodeURIComponent(seedArtists); /** @type {?} */ const sT = encodeURIComponent(seedTracks); return this.apiGet('/recommendations?limit=50&seed_artists=' + sA + '&seed_tracks=' + sT, null, this.getHeaders()); } /** * \@description Get a list of new album releases featured in Spotify * @param {?=} countryCode Country code in 2 char Format. If not set searches from all. * @param {?=} count Amount of results returned. Defaults to 20. * @return {?} */ getNewReleases(countryCode, count) { /** @type {?} */ var query = ""; if (countryCode != null && countryCode != "") { query += "?country=" + countryCode; } if (count != null && count != "") { query += (query.length == 0) ? "?" : "&"; query += "limit=" + count; } return this.apiGet('/browse/new-releases' + query, null, this.getHeaders()); } /** * \@description Get a list of Spotify featured playlists * @param {?=} countryCode Country code in 2 char Format. If not set searches from all. * @param {?=} count Amount of results returned. Defaults to 20. * @return {?} */ getFeaturedPlaylists(countryCode, count) { /** @type {?} */ var query = ""; if (countryCode != null && countryCode != "") { query += "?country=" + countryCode; } if (count != null && count != "") { query += (query.length == 0) ? "?" : "&"; query += "limit=" + count; } return this.apiGet('/browse/featured-playlists' + query, null, this.getHeaders()); } /** * \@description Get a single category used to tag items in Spotify * @param {?} categoryId Spotifys Category Id * @return {?} */ getCategory(categoryId) { return this.apiGet('/browse/categories/' + categoryId, null, this.getHeaders()); } /** * \@description Get a list of categories used to tag items in Spotify * @param {?=} countryCode Country code in 2 char Format. If not set searches from all. * @param {?=} count Amount of results returned. Defaults to 20. * @return {?} */ getCategories(countryCode, count) { /** @type {?} */ var query = ""; if (countryCode != null && countryCode != "") { query += "?country=" + countryCode; } if (count != null && count != "") { query += (query.length == 0) ? "?" : "&"; query += "limit=" + count; } return this.apiGet('/browse/categories' + query, null, this.getHeaders()); } /** * \@description Get a list of Spotify playlists tagged with a particular category. * @param {?} categoryId The Spotify category ID for the category. * @param {?=} countryCode Country code in 2 char Format. If not set searches from all. * @param {?=} count Amount of results returned. Defaults to 20. * @return {?} */ getCategorysPlaylists(categoryId, countryCode, count) { /** @type {?} */ var query = ""; if (countryCode != null && countryCode != "") { query += "?country=" + countryCode; } if (count != null && count != "") { query += (query.length == 0) ? "?" : "&"; query += "limit=" + count; } return this.apiGet('/browse/categories/' + categoryId + '/playlists' + query, null, this.getHeaders()); } /** * \@description Creates a playlist * @param {?} userId Users spotify ID. * @param {?} name A name for the playlist . * @param {?} description A description for the playlist. * @param {?} isPublic Defines if a playlist is public or private * @return {?} */ createPlayList(userId, name, description, isPublic) { /** @type {?} */ var body = { "name": name, "description": description, "public": isPublic }; return this.apiPost('/me/playlists?user_id=' + userId, body, this.getHeaders()); } /** * \@description Adds tracks to playlist * @param {?} playListId * @param {?} trackUris Array of spotify track uris. Max 100 tracks can be added at a time. * @return {?} */ addTracksToPlaylist(playListId, trackUris) { /** @type {?} */ var body = { "uris": trackUris, }; return this.apiPost('/playlists/' + playListId + '/tracks', body, this.getHeaders()); } /** * \@description Returns Spotify Catalog information about artists, albums, tracks or playlists that match a keyword string. * @param {?} query Search word. * @param {?} types * @param {?} count The count is applied within each type, not on the total response. So count 3 with type album,track returns 3 albums and 3 tracks. Max 50. * @return {?} */ search(query, types, count) { /** @type {?} */ const q = encodeURIComponent(query); /** @type {?} */ const t = encodeURIComponent(types); return this.apiGet('/search?q=' + q + '&type=' + t + '&limit=' + count, null, this.getHeaders()); } /** * @private * @param {?} endpoint * @param {?} params * @param {?} headers * @return {?} */ apiGet(endpoint, params, headers) { return this.http.get(this.baseUrl + endpoint, { params: params, headers: headers, withCredentials: false }).toPromise(); } /** * @private * @param {?} endpoint * @param {?} data * @param {?} headers * @return {?} */ apiPost(endpoint, data, headers) { return this.http.post(this.baseUrl + endpoint, data, { headers: headers, }) .toPromise(); } /** * @private * @return {?} */ getHeaders() { return { 'Authorization': 'Bearer ' + this.token, 'Accept': 'application/json', 'Content-Type': 'application/json' }; } } SpotifyRgService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ SpotifyRgService.ctorParameters = () => [ { type: HttpClient } ]; /** @nocollapse */ SpotifyRgService.ngInjectableDef = i0.defineInjectable({ factory: function SpotifyRgService_Factory() { return new SpotifyRgService(i0.inject(i1.HttpClient)); }, token: SpotifyRgService, providedIn: "root" }); if (false) { /** * @type {?} * @private */ SpotifyRgService.prototype.baseUrl; /** * @type {?} * @private */ SpotifyRgService.prototype.token; /** * @type {?} * @private */ SpotifyRgService.prototype.scopes; /** * @type {?} * @private */ SpotifyRgService.prototype.callBackUrl; /** * @type {?} * @private */ SpotifyRgService.prototype.clientId; /** * @type {?} * @private */ SpotifyRgService.prototype.http; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BvdGlmeS1yZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vc3BvdGlmeS1zZXJ2aWNlLXJnLyIsInNvdXJjZXMiOlsibGliL3Nwb3RpZnktcmcuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7OztBQU9sRCxNQUFNLE9BQU8sZ0JBQWdCOzs7O0lBUTNCLFlBQTZCLElBQWdCO1FBQWhCLFNBQUksR0FBSixJQUFJLENBQVk7UUFOckMsWUFBTyxHQUFXLDRCQUE0QixDQUFDO0lBTU4sQ0FBQzs7OztJQUUzQyxLQUFLO1FBQ1YsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsd0NBQXdDO1lBQzdELHNCQUFzQjtZQUN0QixhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVE7WUFDN0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDaEUsZ0JBQWdCLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzVELENBQUM7Ozs7OztJQUdNLFdBQVcsQ0FBQyxRQUFnQjtRQUNqQyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMzQixDQUFDOzs7OztJQUNNLGNBQWMsQ0FBQyxXQUFtQjtRQUN2QyxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztJQUNqQyxDQUFDOzs7OztJQUNNLFNBQVMsQ0FBQyxNQUFjO1FBQzdCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7Ozs7O0lBQ00sUUFBUSxDQUFDLEtBQWE7UUFDM0IsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7SUFDckIs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Q2pCLENBQUM7Ozs7O0lBRU8sVUFBVTtRQUNoQixPQUFPO1lBQ0wsZUFBZSxFQUFFLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSztZQUN2QyxRQUFRLEVBQUUsa0JBQWtCO1lBQzVCLGNBQWMsRUFBRSxrQkFBa0I7U0FDbkMsQ0FBQTtJQUNILENBQUM7OztZQXRSRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7Ozs7WUFOUSxVQUFVOzs7Ozs7OztJQVNqQixtQ0FBdUQ7Ozs7O0lBQ3ZELGlDQUFzQjs7Ozs7SUFDdEIsa0NBQXVCOzs7OztJQUN2Qix1Q0FBNEI7Ozs7O0lBQzVCLG9DQUF5Qjs7Ozs7SUFFYixnQ0FBaUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgdG9Qcm9taXNlIH0gZnJvbSAncnhqcy9vcGVyYXRvci90b1Byb21pc2UnO1xuXG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIFNwb3RpZnlSZ1NlcnZpY2Uge1xuXG4gIHByaXZhdGUgYmFzZVVybDogc3RyaW5nID0gXCJodHRwczovL2FwaS5zcG90aWZ5LmNvbS92MVwiO1xuICBwcml2YXRlIHRva2VuOiBzdHJpbmc7XG4gIHByaXZhdGUgc2NvcGVzOiBzdHJpbmc7XG4gIHByaXZhdGUgY2FsbEJhY2tVcmw6IHN0cmluZztcbiAgcHJpdmF0ZSBjbGllbnRJZDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgaHR0cDogSHR0cENsaWVudCkgeyB9XG5cbiAgcHVibGljIGxvZ2luKCkge1xuICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gJ2h0dHBzOi8vYWNjb3VudHMuc3BvdGlmeS5jb20vYXV0aG9yaXplJyArXG4gICAgICAnP3Jlc3BvbnNlX3R5cGU9dG9rZW4nICtcbiAgICAgICcmY2xpZW50X2lkPScgKyB0aGlzLmNsaWVudElkICtcbiAgICAgICh0aGlzLnNjb3BlcyA/ICcmc2NvcGU9JyArIGVuY29kZVVSSUNvbXBvbmVudCh0aGlzLnNjb3BlcykgOiAnJykgK1xuICAgICAgJyZyZWRpcmVjdF91cmk9JyArIGVuY29kZVVSSUNvbXBvbmVudCh0aGlzLmNhbGxCYWNrVXJsKTtcbiAgfVxuXG4gIC8vU2V0dGVycyBmb3IgdGhlIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllc1xuICBwdWJsaWMgc2V0Q2xpZW50SWQoY2xpZW50SWQ6IHN0cmluZykge1xuICAgIHRoaXMuY2xpZW50SWQgPSBjbGllbnRJZDtcbiAgfVxuICBwdWJsaWMgc2V0Q2FsbEJhY2tVcmwoY2FsbEJhY2tVcmw6IHN0cmluZykge1xuICAgIHRoaXMuY2FsbEJhY2tVcmwgPSBjYWxsQmFja1VybDtcbiAgfVxuICBwdWJsaWMgc2V0U2NvcGVzKHNjb3Blczogc3RyaW5nKSB7XG4gICAgdGhpcy5zY29wZXMgPSBzY29wZXM7XG4gIH1cbiAgcHVibGljIHNldFRva2VuKHRva2VuOiBzdHJpbmcpIHtcbiAgICB0aGlzLnRva2VuID0gdG9rZW47XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgdHJhY2tcbiAqIEBwYXJhbSBhcnRpc3RJZCBUcmFja3MgU3BvdGlmeSBJRFxuICovXG4gIHB1YmxpYyBnZXRUcmFjayh0cmFja0lkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoXCIvdHJhY2tzL1wiICsgdHJhY2tJZCwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRyYWNrc1xuICAqIEBwYXJhbSBhcnRpc3RJZCBDb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiB0cmFjayBJRCdzIGluIGEgc3RyaW5nLlxuICAqL1xuICBwdWJsaWMgZ2V0VHJhY2tzKHRyYWNrSWRzOiBzdHJpbmcpIHtcbiAgICBjb25zdCB0ID0gZW5jb2RlVVJJQ29tcG9uZW50KHRyYWNrSWRzKTtcbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoXCIvdHJhY2tzLz9pZHM9XCIgKyB0LCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgYWxidW1cbiAgKiBAcGFyYW0gYXJ0aXN0SWQgQWxidW1zIFNwb3RpZnkgSUQuXG4gICovXG4gIHB1YmxpYyBnZXRBbGJ1bShhbGJ1bUlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoXCIvYWxidW1zL1wiICsgYWxidW1JZCwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIGFsYnVtc1xuICAqIEBwYXJhbSBhcnRpc3RJZCBDb21tYSBzZXBhcmF0ZWQgbGlzdCBvZiBhbGJ1bSBJRCdzIGluIGEgc3RyaW5nLi5cbiAgKi9cbiAgcHVibGljIGdldEFsYnVtcyhhbGJ1bUlkczogc3RyaW5nKSB7XG4gICAgY29uc3QgYSA9IGVuY29kZVVSSUNvbXBvbmVudChhbGJ1bUlkcyk7XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KFwiL2FsYnVtcy8/aWRzPVwiICsgYSwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIGFsYnVtcyB0cmFja3NcbiAgKiBAcGFyYW0gYXJ0aXN0SWQgQWxidW1zIFNwb3RpZnkgSUQuXG4gICovXG4gIHB1YmxpYyBnZXRBbGJ1bXNUcmFja3MoYWxidW1JZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KFwiL2FsYnVtcy9cIiArIGFsYnVtSWQgKyBcIi90cmFja3NcIiwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIGFydGlzdFxuICAqIEBwYXJhbSBhcnRpc3RJZCBBcnRpc3RzIHNwb3RpZnkgSUQuXG4gICovXG4gIHB1YmxpYyBnZXRBcnRpc3QoYXJ0aXN0SWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmFwaUdldChcIi9hcnRpc3RzL1wiICsgYXJ0aXN0SWQsIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gUmV0dXJucyBhcnRpc3RzXG4gICogQHBhcmFtIGFydGlzdElkIENvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIGFydGlzdCBJRCdzIGluIGEgc3RyaW5nLlxuICAqL1xuICBwdWJsaWMgZ2V0QXJ0aXN0cyhhcnRpc3RJZHM6IHN0cmluZykge1xuICAgIGNvbnN0IGEgPSBlbmNvZGVVUklDb21wb25lbnQoYXJ0aXN0SWRzKTtcbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoXCIvYXJ0aXN0cy8/aWRzPVwiICsgYSwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIGFydGlzdHMgYWxidW1zXG4gICogQHBhcmFtIGFydGlzdElkIEFydGlzdHMgU3BvdGlmeSBJRC5cbiAgKi9cbiAgcHVibGljIGdldEFydGlzdHNBbGJ1bXMoYXJ0aXN0SWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmFwaUdldChcIi9hcnRpc3RzL1wiICsgYXJ0aXN0SWQgKyBcIi9hbGJ1bXNcIiwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIGFydGlzdHMgdG9wIHRyYWNrc1xuICAqIEBwYXJhbSBhcnRpc3RJZCBBcnRpc3RzIFNwb3RpZnkgSUQuXG4gICogQHBhcmFtIGNvdW50cnlDb2RlIENvdW50cnkgY29kZSBpbiAyIGNoYXIgRm9ybWF0LiBGb3IgZXhhbXBsZSBGSS4gRGVmYXVsdHMgdG8gZXh0cmFjdGluZyBjb3VudHJ5IGNvZGUgZnJvbSB0b2tlbi5cbiAgKi9cbiAgcHVibGljIGdldEFydGlzdHNUb3BUcmFja3MoYXJ0aXN0SWQ6IHN0cmluZywgY291bnRyeUNvZGU/OiBzdHJpbmcpIHtcbiAgICB2YXIgY291bnRyeUNvZGUgPSAoY291bnRyeUNvZGUgIT0gbnVsbCAmJiBjb3VudHJ5Q29kZS5sZW5ndGggPT0gMikgPyBjb3VudHJ5Q29kZSA6IFwiZnJvbV90b2tlblwiO1xuICAgIHJldHVybiB0aGlzLmFwaUdldChcIi9hcnRpc3RzL1wiICsgYXJ0aXN0SWQgKyBcIi90b3AtdHJhY2tzP2NvdW50cnk9XCIgKyBjb3VudHJ5Q29kZSwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRoZSB1c2VyIGFzc29zaWF0ZWQgd2l0aCBhdXRoIHRva2VuXG4gICogQHBhcmFtIHVzZXJJZCBUaGUgU3BvdGlmeSBVc2VyIGlkXG4gICovXG4gIHB1YmxpYyBnZXRVc2VyQnlJZCh1c2VySWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmFwaUdldCgnL3VzZXJzLycgKyB1c2VySWQsIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gUmV0dXJucyB0aGUgdXNlciBhc3Nvc2lhdGVkIHdpdGggYXV0aCB0b2tlblxuICAqL1xuICBwdWJsaWMgZ2V0VXNlcigpIHtcbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoJy9tZScsIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gUmV0dXJucyBjdXJyZW50IHVzZXJzIHRvcCB0cmFja3NcbiAgKiBAcGFyYW0gdGltZVJhbmdlIFRoZSByYW5nZSBvZiB0aW1lIHJlc3VsdHMgYXJlIHJldHVybmVkIGZyb20uIFVzZSBzaG9ydF90ZXJtLCBtZWRpdW1fdGVybSBvciBsb25nX3Rlcm0uIERlZmF1bHRzIHRvIGxvbmdfdGVybS5cbiAgKiBAcGFyYW0gY291bnQgQW1vdW50IG9mIHRyYWNrcyByZXR1cm5lZC4gTWF4IHZhbHVlIDUwLiBEZWZhdWx0cyB0byA1MC4gXG4gICovXG4gIHB1YmxpYyBnZXRVc2Vyc1RvcFRyYWNrcyh0aW1lUmFuZ2UsIGNvdW50Pzogc3RyaW5nKTogYW55IHtcbiAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAvL3NldCBiYWNrdXAgZGVmYXVsdCB2YWx1ZXNcbiAgICAgICd0aW1lX3JhbmdlJzogdGltZVJhbmdlID09IG51bGwgPyAnbG9uZ190ZXJtJyA6IHRpbWVSYW5nZSxcbiAgICAgICdsaW1pdCc6IGNvdW50ID09IG51bGwgPyAnNTAnIDogY291bnRcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KFwiL21lL3RvcC90cmFja3NcIiwgcGFyYW1zLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgdXNlcnMgcGxheWxpc3RzXG4gICogQHBhcmFtIHVzZXJJZCBVc2VycyBTcG90aWZ5IElkXG4gICovXG4gIHB1YmxpYyBnZXRVc2Vyc1BsYXlsaXN0cyh1c2VySWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmFwaUdldCgnL3VzZXJzLycgKyB1c2VySWQgKyAnL3BsYXlsaXN0cycsIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gUmV0dXJucyByZWNvbW1lbmRhdGlvbnMgYmFzZWQgb24gc2VlZHMuIE1heCA1IHNlZWRzIGFsbG93ZWQgKHRoYXRzIHRvdGFsIHNvIGZvciBleGFtcGxlIDMgYXJ0aXN0cyBhbmQgMiB0cmFja3MpXG4gICogQHBhcmFtIHNlZWRBcnRpc3RzIENvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIGFydGlzdCBzZWVkIElkc1xuICAqIEBwYXJhbSBzZWVkVHJhY2tzIENvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIHRyYWNrIHNlZWQgSWRzXG4gICovXG4gIHB1YmxpYyBnZXRSZWNvbW1lbmRlZFRyYWNrcyhzZWVkQXJ0aXN0czogc3RyaW5nLCBzZWVkVHJhY2tzOiBzdHJpbmcpOiBhbnkge1xuICAgIGNvbnN0IHNBID0gZW5jb2RlVVJJQ29tcG9uZW50KHNlZWRBcnRpc3RzKTtcbiAgICBjb25zdCBzVCA9IGVuY29kZVVSSUNvbXBvbmVudChzZWVkVHJhY2tzKTtcbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoJy9yZWNvbW1lbmRhdGlvbnM/bGltaXQ9NTAmc2VlZF9hcnRpc3RzPScgKyBzQSArICcmc2VlZF90cmFja3M9JyArIHNULCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIEdldCBhIGxpc3Qgb2YgbmV3IGFsYnVtIHJlbGVhc2VzIGZlYXR1cmVkIGluIFNwb3RpZnkgXG4gICogQHBhcmFtIGNvdW50cnlDb2RlIENvdW50cnkgY29kZSBpbiAyIGNoYXIgRm9ybWF0LiBJZiBub3Qgc2V0IHNlYXJjaGVzIGZyb20gYWxsLlxuICAqIEBwYXJhbSBjb3VudCBBbW91bnQgb2YgcmVzdWx0cyByZXR1cm5lZC4gRGVmYXVsdHMgdG8gMjAuXG4gICovXG4gIHB1YmxpYyBnZXROZXdSZWxlYXNlcyhjb3VudHJ5Q29kZT86IHN0cmluZywgY291bnQ/OiBzdHJpbmcpIHtcbiAgICB2YXIgcXVlcnkgPSBcIlwiO1xuICAgIGlmIChjb3VudHJ5Q29kZSAhPSBudWxsICYmIGNvdW50cnlDb2RlICE9IFwiXCIpIHtcbiAgICAgIHF1ZXJ5ICs9IFwiP2NvdW50cnk9XCIgKyBjb3VudHJ5Q29kZTtcbiAgICB9XG4gICAgaWYgKGNvdW50ICE9IG51bGwgJiYgY291bnQgIT0gXCJcIikge1xuICAgICAgcXVlcnkgKz0gKHF1ZXJ5Lmxlbmd0aCA9PSAwKSA/IFwiP1wiIDogXCImXCI7XG4gICAgICBxdWVyeSArPSBcImxpbWl0PVwiICsgY291bnQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFwaUdldCgnL2Jyb3dzZS9uZXctcmVsZWFzZXMnICsgcXVlcnksIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gR2V0IGEgbGlzdCBvZiBTcG90aWZ5IGZlYXR1cmVkIHBsYXlsaXN0c1xuICAqIEBwYXJhbSBjb3VudHJ5Q29kZSBDb3VudHJ5IGNvZGUgaW4gMiBjaGFyIEZvcm1hdC4gSWYgbm90IHNldCBzZWFyY2hlcyBmcm9tIGFsbC5cbiAgKiBAcGFyYW0gY291bnQgQW1vdW50IG9mIHJlc3VsdHMgcmV0dXJuZWQuIERlZmF1bHRzIHRvIDIwLlxuICAqL1xuICBwdWJsaWMgZ2V0RmVhdHVyZWRQbGF5bGlzdHMoY291bnRyeUNvZGU/OiBzdHJpbmcsIGNvdW50Pzogc3RyaW5nKSB7XG4gICAgdmFyIHF1ZXJ5ID0gXCJcIjtcbiAgICBpZiAoY291bnRyeUNvZGUgIT0gbnVsbCAmJiBjb3VudHJ5Q29kZSAhPSBcIlwiKSB7XG4gICAgICBxdWVyeSArPSBcIj9jb3VudHJ5PVwiICsgY291bnRyeUNvZGU7XG4gICAgfVxuICAgIGlmIChjb3VudCAhPSBudWxsICYmIGNvdW50ICE9IFwiXCIpIHtcbiAgICAgIHF1ZXJ5ICs9IChxdWVyeS5sZW5ndGggPT0gMCkgPyBcIj9cIiA6IFwiJlwiO1xuICAgICAgcXVlcnkgKz0gXCJsaW1pdD1cIiArIGNvdW50O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoJy9icm93c2UvZmVhdHVyZWQtcGxheWxpc3RzJyArIHF1ZXJ5LCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIEdldCBhIHNpbmdsZSBjYXRlZ29yeSB1c2VkIHRvIHRhZyBpdGVtcyBpbiBTcG90aWZ5IFxuICAqIEBwYXJhbSBjYXRlZ29yeUlkIFNwb3RpZnlzIENhdGVnb3J5IElkXG4gICovXG4gIHB1YmxpYyBnZXRDYXRlZ29yeShjYXRlZ29yeUlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoJy9icm93c2UvY2F0ZWdvcmllcy8nK2NhdGVnb3J5SWQsIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBHZXQgYSBsaXN0IG9mIGNhdGVnb3JpZXMgdXNlZCB0byB0YWcgaXRlbXMgaW4gU3BvdGlmeVxuICAqIEBwYXJhbSBjb3VudHJ5Q29kZSBDb3VudHJ5IGNvZGUgaW4gMiBjaGFyIEZvcm1hdC4gSWYgbm90IHNldCBzZWFyY2hlcyBmcm9tIGFsbC5cbiAgKiBAcGFyYW0gY291bnQgQW1vdW50IG9mIHJlc3VsdHMgcmV0dXJuZWQuIERlZmF1bHRzIHRvIDIwLlxuICAqL1xuICBwdWJsaWMgZ2V0Q2F0ZWdvcmllcyhjb3VudHJ5Q29kZT86IHN0cmluZywgY291bnQ/OiBzdHJpbmcpIHtcbiAgICB2YXIgcXVlcnkgPSBcIlwiO1xuICAgIGlmIChjb3VudHJ5Q29kZSAhPSBudWxsICYmIGNvdW50cnlDb2RlICE9IFwiXCIpIHtcbiAgICAgIHF1ZXJ5ICs9IFwiP2NvdW50cnk9XCIgKyBjb3VudHJ5Q29kZTtcbiAgICB9XG4gICAgaWYgKGNvdW50ICE9IG51bGwgJiYgY291bnQgIT0gXCJcIikge1xuICAgICAgcXVlcnkgKz0gKHF1ZXJ5Lmxlbmd0aCA9PSAwKSA/IFwiP1wiIDogXCImXCI7XG4gICAgICBxdWVyeSArPSBcImxpbWl0PVwiICsgY291bnQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFwaUdldCgnL2Jyb3dzZS9jYXRlZ29yaWVzJyArIHF1ZXJ5LCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIEdldCBhIGxpc3Qgb2YgU3BvdGlmeSBwbGF5bGlzdHMgdGFnZ2VkIHdpdGggYSBwYXJ0aWN1bGFyIGNhdGVnb3J5LlxuICAqIEBwYXJhbSBjYXRlZ29yeUlkIFRoZSBTcG90aWZ5IGNhdGVnb3J5IElEIGZvciB0aGUgY2F0ZWdvcnkuXG4gICogQHBhcmFtIGNvdW50cnlDb2RlIENvdW50cnkgY29kZSBpbiAyIGNoYXIgRm9ybWF0LiBJZiBub3Qgc2V0IHNlYXJjaGVzIGZyb20gYWxsLlxuICAqIEBwYXJhbSBjb3VudCBBbW91bnQgb2YgcmVzdWx0cyByZXR1cm5lZC4gRGVmYXVsdHMgdG8gMjAuXG4gICovXG4gIHB1YmxpYyBnZXRDYXRlZ29yeXNQbGF5bGlzdHMoY2F0ZWdvcnlJZDogc3RyaW5nLCBjb3VudHJ5Q29kZT86IHN0cmluZywgY291bnQ/OiBzdHJpbmcpIHtcbiAgICB2YXIgcXVlcnkgPSBcIlwiO1xuICAgIGlmIChjb3VudHJ5Q29kZSAhPSBudWxsICYmIGNvdW50cnlDb2RlICE9IFwiXCIpIHtcbiAgICAgIHF1ZXJ5ICs9IFwiP2NvdW50cnk9XCIgKyBjb3VudHJ5Q29kZTtcbiAgICB9XG4gICAgaWYgKGNvdW50ICE9IG51bGwgJiYgY291bnQgIT0gXCJcIikge1xuICAgICAgcXVlcnkgKz0gKHF1ZXJ5Lmxlbmd0aCA9PSAwKSA/IFwiP1wiIDogXCImXCI7XG4gICAgICBxdWVyeSArPSBcImxpbWl0PVwiICsgY291bnQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFwaUdldCgnL2Jyb3dzZS9jYXRlZ29yaWVzLycrY2F0ZWdvcnlJZCsnL3BsYXlsaXN0cycgKyBxdWVyeSwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgcGxheWxpc3QgXG4gICogQHBhcmFtIHVzZXJJZCBVc2VycyBzcG90aWZ5IElELlxuICAqIEBwYXJhbSBuYW1lIEEgbmFtZSBmb3IgdGhlIHBsYXlsaXN0IC5cbiAgKiBAcGFyYW0gZGVzY3JpcHRpb24gQSBkZXNjcmlwdGlvbiBmb3IgdGhlIHBsYXlsaXN0LlxuICAqIEBwYXJhbSBpc1B1YmxpYyBEZWZpbmVzIGlmIGEgcGxheWxpc3QgaXMgcHVibGljIG9yIHByaXZhdGVcbiAgKi9cbiAgcHVibGljIGNyZWF0ZVBsYXlMaXN0KHVzZXJJZDogbnVtYmVyLCBuYW1lOiBzdHJpbmcsIGRlc2NyaXB0aW9uOiBzdHJpbmcsIGlzUHVibGljOiBib29sZWFuKSB7XG4gICAgdmFyIGJvZHkgPSB7XG4gICAgICBcIm5hbWVcIjogbmFtZSxcbiAgICAgIFwiZGVzY3JpcHRpb25cIjogZGVzY3JpcHRpb24sXG4gICAgICBcInB1YmxpY1wiOiBpc1B1YmxpY1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hcGlQb3N0KCcvbWUvcGxheWxpc3RzP3VzZXJfaWQ9JyArIHVzZXJJZCwgYm9keSwgdGhpcy5nZXRIZWFkZXJzKCkpXG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIEFkZHMgdHJhY2tzIHRvIHBsYXlsaXN0XG4gICogQHBhcmFtIHBsYXlsaXN0SWQgUGxheWxpc3QgSUQuXG4gICogQHBhcmFtIHRyYWNrVXJpcyBBcnJheSBvZiBzcG90aWZ5IHRyYWNrIHVyaXMuIE1heCAxMDAgdHJhY2tzIGNhbiBiZSBhZGRlZCBhdCBhIHRpbWUuXG4gICovXG4gIHB1YmxpYyBhZGRUcmFja3NUb1BsYXlsaXN0KHBsYXlMaXN0SWQ6IHN0cmluZywgdHJhY2tVcmlzOiBzdHJpbmdbXSkge1xuICAgIHZhciBib2R5ID0ge1xuICAgICAgXCJ1cmlzXCI6IHRyYWNrVXJpcyxcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYXBpUG9zdCgnL3BsYXlsaXN0cy8nICsgcGxheUxpc3RJZCArICcvdHJhY2tzJywgYm9keSwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIFNwb3RpZnkgQ2F0YWxvZyBpbmZvcm1hdGlvbiBhYm91dCBhcnRpc3RzLCBhbGJ1bXMsIHRyYWNrcyBvciBwbGF5bGlzdHMgdGhhdCBtYXRjaCBhIGtleXdvcmQgc3RyaW5nLlxuICAqIEBwYXJhbSBxdWVyeSBTZWFyY2ggd29yZC5cbiAgKiBAcGFyYW0gdHlwZSBBIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIGl0ZW0gdHlwZXMgdG8gc2VhcmNoIGFjcm9zcy4gVmFsaWQgdHlwZXMgYXJlIGFsYnVtLCBhcnRpc3QsIHBsYXlsaXN0LCBhbmQgdHJhY2suXG4gICogQHBhcmFtIGNvdW50IFRoZSBjb3VudCBpcyBhcHBsaWVkIHdpdGhpbiBlYWNoIHR5cGUsIG5vdCBvbiB0aGUgdG90YWwgcmVzcG9uc2UuIFNvIGNvdW50IDMgd2l0aCB0eXBlIGFsYnVtLHRyYWNrIHJldHVybnMgMyBhbGJ1bXMgYW5kIDMgdHJhY2tzLiBNYXggNTAuXG4gICovXG4gIHB1YmxpYyBzZWFyY2gocXVlcnk6IHN0cmluZywgdHlwZXM6IHN0cmluZywgY291bnQ6IHN0cmluZykge1xuICAgIGNvbnN0IHEgPSBlbmNvZGVVUklDb21wb25lbnQocXVlcnkpO1xuICAgIGNvbnN0IHQgPSBlbmNvZGVVUklDb21wb25lbnQodHlwZXMpO1xuICAgIHJldHVybiB0aGlzLmFwaUdldCgnL3NlYXJjaD9xPScgKyBxICsgJyZ0eXBlPScgKyB0ICsgJyZsaW1pdD0nICsgY291bnQsIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG5cbiAgcHJpdmF0ZSBhcGlHZXQoZW5kcG9pbnQ6IHN0cmluZywgcGFyYW1zLCBoZWFkZXJzKSB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQodGhpcy5iYXNlVXJsICsgZW5kcG9pbnQsIHtcbiAgICAgIHBhcmFtczogcGFyYW1zLFxuICAgICAgaGVhZGVyczogaGVhZGVycyxcbiAgICAgIHdpdGhDcmVkZW50aWFsczogZmFsc2VcbiAgICB9KS50b1Byb21pc2UoKVxuICB9XG5cbiAgcHJpdmF0ZSBhcGlQb3N0KGVuZHBvaW50OiBzdHJpbmcsIGRhdGEsIGhlYWRlcnMpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QodGhpcy5iYXNlVXJsICsgZW5kcG9pbnQsIGRhdGEsIHtcbiAgICAgIGhlYWRlcnM6IGhlYWRlcnMsXG4gICAgfSlcbiAgICAgIC50b1Byb21pc2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0SGVhZGVycygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgJ0F1dGhvcml6YXRpb24nOiAnQmVhcmVyICcgKyB0aGlzLnRva2VuLFxuICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbidcbiAgICB9XG4gIH1cbn1cbiJdfQ==