UNPKG

spotify-service-rg

Version:

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

635 lines 47.2 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"; var SpotifyRgService = /** @class */ (function () { function SpotifyRgService(http) { this.http = http; this.baseUrl = "https://api.spotify.com/v1"; } /** * @return {?} */ SpotifyRgService.prototype.login = /** * @return {?} */ function () { 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 //Setters for the configuration properties /** * @param {?} clientId * @return {?} */ SpotifyRgService.prototype.setClientId = //Setters for the configuration properties /** * @param {?} clientId * @return {?} */ function (clientId) { this.clientId = clientId; }; /** * @param {?} callBackUrl * @return {?} */ SpotifyRgService.prototype.setCallBackUrl = /** * @param {?} callBackUrl * @return {?} */ function (callBackUrl) { this.callBackUrl = callBackUrl; }; /** * @param {?} scopes * @return {?} */ SpotifyRgService.prototype.setScopes = /** * @param {?} scopes * @return {?} */ function (scopes) { this.scopes = scopes; }; /** * @param {?} token * @return {?} */ SpotifyRgService.prototype.setToken = /** * @param {?} token * @return {?} */ function (token) { this.token = token; }; /** @description Returns track * @param artistId Tracks Spotify ID */ /** * \@description Returns track * @param {?} trackId * @return {?} */ SpotifyRgService.prototype.getTrack = /** * \@description Returns track * @param {?} trackId * @return {?} */ function (trackId) { return this.apiGet("/tracks/" + trackId, null, this.getHeaders()); }; /** @description Returns tracks * @param artistId Comma separated list of track ID's in a string. */ /** * \@description Returns tracks * @param {?} trackIds * @return {?} */ SpotifyRgService.prototype.getTracks = /** * \@description Returns tracks * @param {?} trackIds * @return {?} */ function (trackIds) { /** @type {?} */ var t = encodeURIComponent(trackIds); return this.apiGet("/tracks/?ids=" + t, null, this.getHeaders()); }; /** @description Returns album * @param artistId Albums Spotify ID. */ /** * \@description Returns album * @param {?} albumId * @return {?} */ SpotifyRgService.prototype.getAlbum = /** * \@description Returns album * @param {?} albumId * @return {?} */ function (albumId) { return this.apiGet("/albums/" + albumId, null, this.getHeaders()); }; /** @description Returns albums * @param artistId Comma separated list of album ID's in a string.. */ /** * \@description Returns albums * @param {?} albumIds * @return {?} */ SpotifyRgService.prototype.getAlbums = /** * \@description Returns albums * @param {?} albumIds * @return {?} */ function (albumIds) { /** @type {?} */ var a = encodeURIComponent(albumIds); return this.apiGet("/albums/?ids=" + a, null, this.getHeaders()); }; /** @description Returns albums tracks * @param artistId Albums Spotify ID. */ /** * \@description Returns albums tracks * @param {?} albumId * @return {?} */ SpotifyRgService.prototype.getAlbumsTracks = /** * \@description Returns albums tracks * @param {?} albumId * @return {?} */ function (albumId) { return this.apiGet("/albums/" + albumId + "/tracks", null, this.getHeaders()); }; /** @description Returns artist * @param artistId Artists spotify ID. */ /** * \@description Returns artist * @param {?} artistId Artists spotify ID. * @return {?} */ SpotifyRgService.prototype.getArtist = /** * \@description Returns artist * @param {?} artistId Artists spotify ID. * @return {?} */ function (artistId) { return this.apiGet("/artists/" + artistId, null, this.getHeaders()); }; /** @description Returns artists * @param artistId Comma separated list of artist ID's in a string. */ /** * \@description Returns artists * @param {?} artistIds * @return {?} */ SpotifyRgService.prototype.getArtists = /** * \@description Returns artists * @param {?} artistIds * @return {?} */ function (artistIds) { /** @type {?} */ var a = encodeURIComponent(artistIds); return this.apiGet("/artists/?ids=" + a, null, this.getHeaders()); }; /** @description Returns artists albums * @param artistId Artists Spotify ID. */ /** * \@description Returns artists albums * @param {?} artistId Artists Spotify ID. * @return {?} */ SpotifyRgService.prototype.getArtistsAlbums = /** * \@description Returns artists albums * @param {?} artistId Artists Spotify ID. * @return {?} */ function (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. */ /** * \@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 {?} */ SpotifyRgService.prototype.getArtistsTopTracks = /** * \@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 {?} */ function (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 */ /** * \@description Returns the user assosiated with auth token * @param {?} userId The Spotify User id * @return {?} */ SpotifyRgService.prototype.getUserById = /** * \@description Returns the user assosiated with auth token * @param {?} userId The Spotify User id * @return {?} */ function (userId) { return this.apiGet('/users/' + userId, null, this.getHeaders()); }; /** @description Returns the user assosiated with auth token */ /** * \@description Returns the user assosiated with auth token * @return {?} */ SpotifyRgService.prototype.getUser = /** * \@description Returns the user assosiated with auth token * @return {?} */ function () { 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. */ /** * \@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 {?} */ SpotifyRgService.prototype.getUsersTopTracks = /** * \@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 {?} */ function (timeRange, count) { /** @type {?} */ var 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 */ /** * \@description Returns users playlists * @param {?} userId Users Spotify Id * @return {?} */ SpotifyRgService.prototype.getUsersPlaylists = /** * \@description Returns users playlists * @param {?} userId Users Spotify Id * @return {?} */ function (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 */ /** * \@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 {?} */ SpotifyRgService.prototype.getRecommendedTracks = /** * \@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 {?} */ function (seedArtists, seedTracks) { /** @type {?} */ var sA = encodeURIComponent(seedArtists); /** @type {?} */ var 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. */ /** * \@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 {?} */ SpotifyRgService.prototype.getNewReleases = /** * \@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 {?} */ function (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. */ /** * \@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 {?} */ SpotifyRgService.prototype.getFeaturedPlaylists = /** * \@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 {?} */ function (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 */ /** * \@description Get a single category used to tag items in Spotify * @param {?} categoryId Spotifys Category Id * @return {?} */ SpotifyRgService.prototype.getCategory = /** * \@description Get a single category used to tag items in Spotify * @param {?} categoryId Spotifys Category Id * @return {?} */ function (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. */ /** * \@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 {?} */ SpotifyRgService.prototype.getCategories = /** * \@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 {?} */ function (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. */ /** * \@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 {?} */ SpotifyRgService.prototype.getCategorysPlaylists = /** * \@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 {?} */ function (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 */ /** * \@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 {?} */ SpotifyRgService.prototype.createPlayList = /** * \@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 {?} */ function (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 Playlist ID. * @param trackUris Array of spotify track uris. Max 100 tracks can be added at a time. */ /** * \@description Adds tracks to playlist * @param {?} playListId * @param {?} trackUris Array of spotify track uris. Max 100 tracks can be added at a time. * @return {?} */ SpotifyRgService.prototype.addTracksToPlaylist = /** * \@description Adds tracks to playlist * @param {?} playListId * @param {?} trackUris Array of spotify track uris. Max 100 tracks can be added at a time. * @return {?} */ function (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 type A comma-separated list of item types to search across. Valid types are album, artist, playlist, and track. * @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. */ /** * \@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 {?} */ SpotifyRgService.prototype.search = /** * \@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 {?} */ function (query, types, count) { /** @type {?} */ var q = encodeURIComponent(query); /** @type {?} */ var t = encodeURIComponent(types); return this.apiGet('/search?q=' + q + '&type=' + t + '&limit=' + count, null, this.getHeaders()); }; /** * @private * @param {?} endpoint * @param {?} params * @param {?} headers * @return {?} */ SpotifyRgService.prototype.apiGet = /** * @private * @param {?} endpoint * @param {?} params * @param {?} headers * @return {?} */ function (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 {?} */ SpotifyRgService.prototype.apiPost = /** * @private * @param {?} endpoint * @param {?} data * @param {?} headers * @return {?} */ function (endpoint, data, headers) { return this.http.post(this.baseUrl + endpoint, data, { headers: headers, }) .toPromise(); }; /** * @private * @return {?} */ SpotifyRgService.prototype.getHeaders = /** * @private * @return {?} */ function () { return { 'Authorization': 'Bearer ' + this.token, 'Accept': 'application/json', 'Content-Type': 'application/json' }; }; SpotifyRgService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ SpotifyRgService.ctorParameters = function () { return [ { type: HttpClient } ]; }; /** @nocollapse */ SpotifyRgService.ngInjectableDef = i0.defineInjectable({ factory: function SpotifyRgService_Factory() { return new SpotifyRgService(i0.inject(i1.HttpClient)); }, token: SpotifyRgService, providedIn: "root" }); return SpotifyRgService; }()); export { SpotifyRgService }; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BvdGlmeS1yZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vc3BvdGlmeS1zZXJ2aWNlLXJnLyIsInNvdXJjZXMiOlsibGliL3Nwb3RpZnktcmcuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7OztBQUlsRDtJQVdFLDBCQUE2QixJQUFnQjtRQUFoQixTQUFJLEdBQUosSUFBSSxDQUFZO1FBTnJDLFlBQU8sR0FBVyw0QkFBNEIsQ0FBQztJQU1OLENBQUM7Ozs7SUFFM0MsZ0NBQUs7OztJQUFaO1FBQ0UsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsd0NBQXdDO1lBQzdELHNCQUFzQjtZQUN0QixhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVE7WUFDN0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDaEUsZ0JBQWdCLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCwwQ0FBMEM7Ozs7OztJQUNuQyxzQ0FBVzs7Ozs7O0lBQWxCLFVBQW1CLFFBQWdCO1FBQ2pDLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO0lBQzNCLENBQUM7Ozs7O0lBQ00seUNBQWM7Ozs7SUFBckIsVUFBc0IsV0FBbUI7UUFDdkMsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7SUFDakMsQ0FBQzs7Ozs7SUFDTSxvQ0FBUzs7OztJQUFoQixVQUFpQixNQUFjO1FBQzdCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7Ozs7O0lBQ00sbUNBQVE7Ozs7SUFBZixVQUFnQixL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LHVDQUE0Qjs7Ozs7SUFDNUIsb0NBQXlCOzs7OztJQUViLGdDQUFpQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyB0b1Byb21pc2UgfSBmcm9tICdyeGpzL29wZXJhdG9yL3RvUHJvbWlzZSc7XG5cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgU3BvdGlmeVJnU2VydmljZSB7XG5cbiAgcHJpdmF0ZSBiYXNlVXJsOiBzdHJpbmcgPSBcImh0dHBzOi8vYXBpLnNwb3RpZnkuY29tL3YxXCI7XG4gIHByaXZhdGUgdG9rZW46IHN0cmluZztcbiAgcHJpdmF0ZSBzY29wZXM6IHN0cmluZztcbiAgcHJpdmF0ZSBjYWxsQmFja1VybDogc3RyaW5nO1xuICBwcml2YXRlIGNsaWVudElkOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBodHRwOiBIdHRwQ2xpZW50KSB7IH1cblxuICBwdWJsaWMgbG9naW4oKSB7XG4gICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSAnaHR0cHM6Ly9hY2NvdW50cy5zcG90aWZ5LmNvbS9hdXRob3JpemUnICtcbiAgICAgICc/cmVzcG9uc2VfdHlwZT10b2tlbicgK1xuICAgICAgJyZjbGllbnRfaWQ9JyArIHRoaXMuY2xpZW50SWQgK1xuICAgICAgKHRoaXMuc2NvcGVzID8gJyZzY29wZT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMuc2NvcGVzKSA6ICcnKSArXG4gICAgICAnJnJlZGlyZWN0X3VyaT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMuY2FsbEJhY2tVcmwpO1xuICB9XG5cbiAgLy9TZXR0ZXJzIGZvciB0aGUgY29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzXG4gIHB1YmxpYyBzZXRDbGllbnRJZChjbGllbnRJZDogc3RyaW5nKSB7XG4gICAgdGhpcy5jbGllbnRJZCA9IGNsaWVudElkO1xuICB9XG4gIHB1YmxpYyBzZXRDYWxsQmFja1VybChjYWxsQmFja1VybDogc3RyaW5nKSB7XG4gICAgdGhpcy5jYWxsQmFja1VybCA9IGNhbGxCYWNrVXJsO1xuICB9XG4gIHB1YmxpYyBzZXRTY29wZXMoc2NvcGVzOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNjb3BlcyA9IHNjb3BlcztcbiAgfVxuICBwdWJsaWMgc2V0VG9rZW4odG9rZW46IHN0cmluZykge1xuICAgIHRoaXMudG9rZW4gPSB0b2tlbjtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gUmV0dXJucyB0cmFja1xuICogQHBhcmFtIGFydGlzdElkIFRyYWNrcyBTcG90aWZ5IElEXG4gKi9cbiAgcHVibGljIGdldFRyYWNrKHRyYWNrSWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmFwaUdldChcIi90cmFja3MvXCIgKyB0cmFja0lkLCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgdHJhY2tzXG4gICogQHBhcmFtIGFydGlzdElkIENvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIHRyYWNrIElEJ3MgaW4gYSBzdHJpbmcuXG4gICovXG4gIHB1YmxpYyBnZXRUcmFja3ModHJhY2tJZHM6IHN0cmluZykge1xuICAgIGNvbnN0IHQgPSBlbmNvZGVVUklDb21wb25lbnQodHJhY2tJZHMpO1xuICAgIHJldHVybiB0aGlzLmFwaUdldChcIi90cmFja3MvP2lkcz1cIiArIHQsIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gUmV0dXJucyBhbGJ1bVxuICAqIEBwYXJhbSBhcnRpc3RJZCBBbGJ1bXMgU3BvdGlmeSBJRC5cbiAgKi9cbiAgcHVibGljIGdldEFsYnVtKGFsYnVtSWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmFwaUdldChcIi9hbGJ1bXMvXCIgKyBhbGJ1bUlkLCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgYWxidW1zXG4gICogQHBhcmFtIGFydGlzdElkIENvbW1hIHNlcGFyYXRlZCBsaXN0IG9mIGFsYnVtIElEJ3MgaW4gYSBzdHJpbmcuLlxuICAqL1xuICBwdWJsaWMgZ2V0QWxidW1zKGFsYnVtSWRzOiBzdHJpbmcpIHtcbiAgICBjb25zdCBhID0gZW5jb2RlVVJJQ29tcG9uZW50KGFsYnVtSWRzKTtcbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoXCIvYWxidW1zLz9pZHM9XCIgKyBhLCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgYWxidW1zIHRyYWNrc1xuICAqIEBwYXJhbSBhcnRpc3RJZCBBbGJ1bXMgU3BvdGlmeSBJRC5cbiAgKi9cbiAgcHVibGljIGdldEFsYnVtc1RyYWNrcyhhbGJ1bUlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoXCIvYWxidW1zL1wiICsgYWxidW1JZCArIFwiL3RyYWNrc1wiLCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgYXJ0aXN0XG4gICogQHBhcmFtIGFydGlzdElkIEFydGlzdHMgc3BvdGlmeSBJRC5cbiAgKi9cbiAgcHVibGljIGdldEFydGlzdChhcnRpc3RJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KFwiL2FydGlzdHMvXCIgKyBhcnRpc3RJZCwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIGFydGlzdHNcbiAgKiBAcGFyYW0gYXJ0aXN0SWQgQ29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YgYXJ0aXN0IElEJ3MgaW4gYSBzdHJpbmcuXG4gICovXG4gIHB1YmxpYyBnZXRBcnRpc3RzKGFydGlzdElkczogc3RyaW5nKSB7XG4gICAgY29uc3QgYSA9IGVuY29kZVVSSUNvbXBvbmVudChhcnRpc3RJZHMpO1xuICAgIHJldHVybiB0aGlzLmFwaUdldChcIi9hcnRpc3RzLz9pZHM9XCIgKyBhLCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgYXJ0aXN0cyBhbGJ1bXNcbiAgKiBAcGFyYW0gYXJ0aXN0SWQgQXJ0aXN0cyBTcG90aWZ5IElELlxuICAqL1xuICBwdWJsaWMgZ2V0QXJ0aXN0c0FsYnVtcyhhcnRpc3RJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KFwiL2FydGlzdHMvXCIgKyBhcnRpc3RJZCArIFwiL2FsYnVtc1wiLCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgYXJ0aXN0cyB0b3AgdHJhY2tzXG4gICogQHBhcmFtIGFydGlzdElkIEFydGlzdHMgU3BvdGlmeSBJRC5cbiAgKiBAcGFyYW0gY291bnRyeUNvZGUgQ291bnRyeSBjb2RlIGluIDIgY2hhciBGb3JtYXQuIEZvciBleGFtcGxlIEZJLiBEZWZhdWx0cyB0byBleHRyYWN0aW5nIGNvdW50cnkgY29kZSBmcm9tIHRva2VuLlxuICAqL1xuICBwdWJsaWMgZ2V0QXJ0aXN0c1RvcFRyYWNrcyhhcnRpc3RJZDogc3RyaW5nLCBjb3VudHJ5Q29kZT86IHN0cmluZykge1xuICAgIHZhciBjb3VudHJ5Q29kZSA9IChjb3VudHJ5Q29kZSAhPSBudWxsICYmIGNvdW50cnlDb2RlLmxlbmd0aCA9PSAyKSA/IGNvdW50cnlDb2RlIDogXCJmcm9tX3Rva2VuXCI7XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KFwiL2FydGlzdHMvXCIgKyBhcnRpc3RJZCArIFwiL3RvcC10cmFja3M/Y291bnRyeT1cIiArIGNvdW50cnlDb2RlLCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIHVzZXIgYXNzb3NpYXRlZCB3aXRoIGF1dGggdG9rZW5cbiAgKiBAcGFyYW0gdXNlcklkIFRoZSBTcG90aWZ5IFVzZXIgaWRcbiAgKi9cbiAgcHVibGljIGdldFVzZXJCeUlkKHVzZXJJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KCcvdXNlcnMvJyArIHVzZXJJZCwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHRoZSB1c2VyIGFzc29zaWF0ZWQgd2l0aCBhdXRoIHRva2VuXG4gICovXG4gIHB1YmxpYyBnZXRVc2VyKCkge1xuICAgIHJldHVybiB0aGlzLmFwaUdldCgnL21lJywgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIGN1cnJlbnQgdXNlcnMgdG9wIHRyYWNrc1xuICAqIEBwYXJhbSB0aW1lUmFuZ2UgVGhlIHJhbmdlIG9mIHRpbWUgcmVzdWx0cyBhcmUgcmV0dXJuZWQgZnJvbS4gVXNlIHNob3J0X3Rlcm0sIG1lZGl1bV90ZXJtIG9yIGxvbmdfdGVybS4gRGVmYXVsdHMgdG8gbG9uZ190ZXJtLlxuICAqIEBwYXJhbSBjb3VudCBBbW91bnQgb2YgdHJhY2tzIHJldHVybmVkLiBNYXggdmFsdWUgNTAuIERlZmF1bHRzIHRvIDUwLiBcbiAgKi9cbiAgcHVibGljIGdldFVzZXJzVG9wVHJhY2tzKHRpbWVSYW5nZSwgY291bnQ/OiBzdHJpbmcpOiBhbnkge1xuICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgIC8vc2V0IGJhY2t1cCBkZWZhdWx0IHZhbHVlc1xuICAgICAgJ3RpbWVfcmFuZ2UnOiB0aW1lUmFuZ2UgPT0gbnVsbCA/ICdsb25nX3Rlcm0nIDogdGltZVJhbmdlLFxuICAgICAgJ2xpbWl0JzogY291bnQgPT0gbnVsbCA/ICc1MCcgOiBjb3VudFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hcGlHZXQoXCIvbWUvdG9wL3RyYWNrc1wiLCBwYXJhbXMsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gUmV0dXJucyB1c2VycyBwbGF5bGlzdHNcbiAgKiBAcGFyYW0gdXNlcklkIFVzZXJzIFNwb3RpZnkgSWRcbiAgKi9cbiAgcHVibGljIGdldFVzZXJzUGxheWxpc3RzKHVzZXJJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KCcvdXNlcnMvJyArIHVzZXJJZCArICcvcGxheWxpc3RzJywgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIHJlY29tbWVuZGF0aW9ucyBiYXNlZCBvbiBzZWVkcy4gTWF4IDUgc2VlZHMgYWxsb3dlZCAodGhhdHMgdG90YWwgc28gZm9yIGV4YW1wbGUgMyBhcnRpc3RzIGFuZCAyIHRyYWNrcylcbiAgKiBAcGFyYW0gc2VlZEFydGlzdHMgQ29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YgYXJ0aXN0IHNlZWQgSWRzXG4gICogQHBhcmFtIHNlZWRUcmFja3MgQ29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YgdHJhY2sgc2VlZCBJZHNcbiAgKi9cbiAgcHVibGljIGdldFJlY29tbWVuZGVkVHJhY2tzKHNlZWRBcnRpc3RzOiBzdHJpbmcsIHNlZWRUcmFja3M6IHN0cmluZyk6IGFueSB7XG4gICAgY29uc3Qgc0EgPSBlbmNvZGVVUklDb21wb25lbnQoc2VlZEFydGlzdHMpO1xuICAgIGNvbnN0IHNUID0gZW5jb2RlVVJJQ29tcG9uZW50KHNlZWRUcmFja3MpO1xuICAgIHJldHVybiB0aGlzLmFwaUdldCgnL3JlY29tbWVuZGF0aW9ucz9saW1pdD01MCZzZWVkX2FydGlzdHM9JyArIHNBICsgJyZzZWVkX3RyYWNrcz0nICsgc1QsIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gR2V0IGEgbGlzdCBvZiBuZXcgYWxidW0gcmVsZWFzZXMgZmVhdHVyZWQgaW4gU3BvdGlmeSBcbiAgKiBAcGFyYW0gY291bnRyeUNvZGUgQ291bnRyeSBjb2RlIGluIDIgY2hhciBGb3JtYXQuIElmIG5vdCBzZXQgc2VhcmNoZXMgZnJvbSBhbGwuXG4gICogQHBhcmFtIGNvdW50IEFtb3VudCBvZiByZXN1bHRzIHJldHVybmVkLiBEZWZhdWx0cyB0byAyMC5cbiAgKi9cbiAgcHVibGljIGdldE5ld1JlbGVhc2VzKGNvdW50cnlDb2RlPzogc3RyaW5nLCBjb3VudD86IHN0cmluZykge1xuICAgIHZhciBxdWVyeSA9IFwiXCI7XG4gICAgaWYgKGNvdW50cnlDb2RlICE9IG51bGwgJiYgY291bnRyeUNvZGUgIT0gXCJcIikge1xuICAgICAgcXVlcnkgKz0gXCI/Y291bnRyeT1cIiArIGNvdW50cnlDb2RlO1xuICAgIH1cbiAgICBpZiAoY291bnQgIT0gbnVsbCAmJiBjb3VudCAhPSBcIlwiKSB7XG4gICAgICBxdWVyeSArPSAocXVlcnkubGVuZ3RoID09IDApID8gXCI/XCIgOiBcIiZcIjtcbiAgICAgIHF1ZXJ5ICs9IFwibGltaXQ9XCIgKyBjb3VudDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KCcvYnJvd3NlL25ldy1yZWxlYXNlcycgKyBxdWVyeSwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cbiAgLyoqIEBkZXNjcmlwdGlvbiBHZXQgYSBsaXN0IG9mIFNwb3RpZnkgZmVhdHVyZWQgcGxheWxpc3RzXG4gICogQHBhcmFtIGNvdW50cnlDb2RlIENvdW50cnkgY29kZSBpbiAyIGNoYXIgRm9ybWF0LiBJZiBub3Qgc2V0IHNlYXJjaGVzIGZyb20gYWxsLlxuICAqIEBwYXJhbSBjb3VudCBBbW91bnQgb2YgcmVzdWx0cyByZXR1cm5lZC4gRGVmYXVsdHMgdG8gMjAuXG4gICovXG4gIHB1YmxpYyBnZXRGZWF0dXJlZFBsYXlsaXN0cyhjb3VudHJ5Q29kZT86IHN0cmluZywgY291bnQ/OiBzdHJpbmcpIHtcbiAgICB2YXIgcXVlcnkgPSBcIlwiO1xuICAgIGlmIChjb3VudHJ5Q29kZSAhPSBudWxsICYmIGNvdW50cnlDb2RlICE9IFwiXCIpIHtcbiAgICAgIHF1ZXJ5ICs9IFwiP2NvdW50cnk9XCIgKyBjb3VudHJ5Q29kZTtcbiAgICB9XG4gICAgaWYgKGNvdW50ICE9IG51bGwgJiYgY291bnQgIT0gXCJcIikge1xuICAgICAgcXVlcnkgKz0gKHF1ZXJ5Lmxlbmd0aCA9PSAwKSA/IFwiP1wiIDogXCImXCI7XG4gICAgICBxdWVyeSArPSBcImxpbWl0PVwiICsgY291bnQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFwaUdldCgnL2Jyb3dzZS9mZWF0dXJlZC1wbGF5bGlzdHMnICsgcXVlcnksIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gR2V0IGEgc2luZ2xlIGNhdGVnb3J5IHVzZWQgdG8gdGFnIGl0ZW1zIGluIFNwb3RpZnkgXG4gICogQHBhcmFtIGNhdGVnb3J5SWQgU3BvdGlmeXMgQ2F0ZWdvcnkgSWRcbiAgKi9cbiAgcHVibGljIGdldENhdGVnb3J5KGNhdGVnb3J5SWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmFwaUdldCgnL2Jyb3dzZS9jYXRlZ29yaWVzLycrY2F0ZWdvcnlJZCwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cblxuICAvKiogQGRlc2NyaXB0aW9uIEdldCBhIGxpc3Qgb2YgY2F0ZWdvcmllcyB1c2VkIHRvIHRhZyBpdGVtcyBpbiBTcG90aWZ5XG4gICogQHBhcmFtIGNvdW50cnlDb2RlIENvdW50cnkgY29kZSBpbiAyIGNoYXIgRm9ybWF0LiBJZiBub3Qgc2V0IHNlYXJjaGVzIGZyb20gYWxsLlxuICAqIEBwYXJhbSBjb3VudCBBbW91bnQgb2YgcmVzdWx0cyByZXR1cm5lZC4gRGVmYXVsdHMgdG8gMjAuXG4gICovXG4gIHB1YmxpYyBnZXRDYXRlZ29yaWVzKGNvdW50cnlDb2RlPzogc3RyaW5nLCBjb3VudD86IHN0cmluZykge1xuICAgIHZhciBxdWVyeSA9IFwiXCI7XG4gICAgaWYgKGNvdW50cnlDb2RlICE9IG51bGwgJiYgY291bnRyeUNvZGUgIT0gXCJcIikge1xuICAgICAgcXVlcnkgKz0gXCI/Y291bnRyeT1cIiArIGNvdW50cnlDb2RlO1xuICAgIH1cbiAgICBpZiAoY291bnQgIT0gbnVsbCAmJiBjb3VudCAhPSBcIlwiKSB7XG4gICAgICBxdWVyeSArPSAocXVlcnkubGVuZ3RoID09IDApID8gXCI/XCIgOiBcIiZcIjtcbiAgICAgIHF1ZXJ5ICs9IFwibGltaXQ9XCIgKyBjb3VudDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KCcvYnJvd3NlL2NhdGVnb3JpZXMnICsgcXVlcnksIG51bGwsIHRoaXMuZ2V0SGVhZGVycygpKTtcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gR2V0IGEgbGlzdCBvZiBTcG90aWZ5IHBsYXlsaXN0cyB0YWdnZWQgd2l0aCBhIHBhcnRpY3VsYXIgY2F0ZWdvcnkuXG4gICogQHBhcmFtIGNhdGVnb3J5SWQgVGhlIFNwb3RpZnkgY2F0ZWdvcnkgSUQgZm9yIHRoZSBjYXRlZ29yeS5cbiAgKiBAcGFyYW0gY291bnRyeUNvZGUgQ291bnRyeSBjb2RlIGluIDIgY2hhciBGb3JtYXQuIElmIG5vdCBzZXQgc2VhcmNoZXMgZnJvbSBhbGwuXG4gICogQHBhcmFtIGNvdW50IEFtb3VudCBvZiByZXN1bHRzIHJldHVybmVkLiBEZWZhdWx0cyB0byAyMC5cbiAgKi9cbiAgcHVibGljIGdldENhdGVnb3J5c1BsYXlsaXN0cyhjYXRlZ29yeUlkOiBzdHJpbmcsIGNvdW50cnlDb2RlPzogc3RyaW5nLCBjb3VudD86IHN0cmluZykge1xuICAgIHZhciBxdWVyeSA9IFwiXCI7XG4gICAgaWYgKGNvdW50cnlDb2RlICE9IG51bGwgJiYgY291bnRyeUNvZGUgIT0gXCJcIikge1xuICAgICAgcXVlcnkgKz0gXCI/Y291bnRyeT1cIiArIGNvdW50cnlDb2RlO1xuICAgIH1cbiAgICBpZiAoY291bnQgIT0gbnVsbCAmJiBjb3VudCAhPSBcIlwiKSB7XG4gICAgICBxdWVyeSArPSAocXVlcnkubGVuZ3RoID09IDApID8gXCI/XCIgOiBcIiZcIjtcbiAgICAgIHF1ZXJ5ICs9IFwibGltaXQ9XCIgKyBjb3VudDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KCcvYnJvd3NlL2NhdGVnb3JpZXMvJytjYXRlZ29yeUlkKycvcGxheWxpc3RzJyArIHF1ZXJ5LCBudWxsLCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBwbGF5bGlzdCBcbiAgKiBAcGFyYW0gdXNlcklkIFVzZXJzIHNwb3RpZnkgSUQuXG4gICogQHBhcmFtIG5hbWUgQSBuYW1lIGZvciB0aGUgcGxheWxpc3QgLlxuICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBBIGRlc2NyaXB0aW9uIGZvciB0aGUgcGxheWxpc3QuXG4gICogQHBhcmFtIGlzUHVibGljIERlZmluZXMgaWYgYSBwbGF5bGlzdCBpcyBwdWJsaWMgb3IgcHJpdmF0ZVxuICAqL1xuICBwdWJsaWMgY3JlYXRlUGxheUxpc3QodXNlcklkOiBudW1iZXIsIG5hbWU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZywgaXNQdWJsaWM6IGJvb2xlYW4pIHtcbiAgICB2YXIgYm9keSA9IHtcbiAgICAgIFwibmFtZVwiOiBuYW1lLFxuICAgICAgXCJkZXNjcmlwdGlvblwiOiBkZXNjcmlwdGlvbixcbiAgICAgIFwicHVibGljXCI6IGlzUHVibGljXG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFwaVBvc3QoJy9tZS9wbGF5bGlzdHM/dXNlcl9pZD0nICsgdXNlcklkLCBib2R5LCB0aGlzLmdldEhlYWRlcnMoKSlcbiAgfVxuXG4gIC8qKiBAZGVzY3JpcHRpb24gQWRkcyB0cmFja3MgdG8gcGxheWxpc3RcbiAgKiBAcGFyYW0gcGxheWxpc3RJZCBQbGF5bGlzdCBJRC5cbiAgKiBAcGFyYW0gdHJhY2tVcmlzIEFycmF5IG9mIHNwb3RpZnkgdHJhY2sgdXJpcy4gTWF4IDEwMCB0cmFja3MgY2FuIGJlIGFkZGVkIGF0IGEgdGltZS5cbiAgKi9cbiAgcHVibGljIGFkZFRyYWNrc1RvUGxheWxpc3QocGxheUxpc3RJZDogc3RyaW5nLCB0cmFja1VyaXM6IHN0cmluZ1tdKSB7XG4gICAgdmFyIGJvZHkgPSB7XG4gICAgICBcInVyaXNcIjogdHJhY2tVcmlzLFxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hcGlQb3N0KCcvcGxheWxpc3RzLycgKyBwbGF5TGlzdElkICsgJy90cmFja3MnLCBib2R5LCB0aGlzLmdldEhlYWRlcnMoKSk7XG4gIH1cblxuICAvKiogQGRlc2NyaXB0aW9uIFJldHVybnMgU3BvdGlmeSBDYXRhbG9nIGluZm9ybWF0aW9uIGFib3V0IGFydGlzdHMsIGFsYnVtcywgdHJhY2tzIG9yIHBsYXlsaXN0cyB0aGF0IG1hdGNoIGEga2V5d29yZCBzdHJpbmcuXG4gICogQHBhcmFtIHF1ZXJ5IFNlYXJjaCB3b3JkLlxuICAqIEBwYXJhbSB0eXBlIEEgY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgaXRlbSB0eXBlcyB0byBzZWFyY2ggYWNyb3NzLiBWYWxpZCB0eXBlcyBhcmUgYWxidW0sIGFydGlzdCwgcGxheWxpc3QsIGFuZCB0cmFjay5cbiAgKiBAcGFyYW0gY291bnQgVGhlIGNvdW50IGlzIGFwcGxpZWQgd2l0aGluIGVhY2ggdHlwZSwgbm90IG9uIHRoZSB0b3RhbCByZXNwb25zZS4gU28gY291bnQgMyB3aXRoIHR5cGUgYWxidW0sdHJhY2sgcmV0dXJucyAzIGFsYnVtcyBhbmQgMyB0cmFja3MuIE1heCA1MC5cbiAgKi9cbiAgcHVibGljIHNlYXJjaChxdWVyeTogc3RyaW5nLCB0eXBlczogc3RyaW5nLCBjb3VudDogc3RyaW5nKSB7XG4gICAgY29uc3QgcSA9IGVuY29kZVVSSUNvbXBvbmVudChxdWVyeSk7XG4gICAgY29uc3QgdCA9IGVuY29kZVVSSUNvbXBvbmVudCh0eXBlcyk7XG4gICAgcmV0dXJuIHRoaXMuYXBpR2V0KCcvc2VhcmNoP3E9JyArIHEgKyAnJnR5cGU9JyArIHQgKyAnJmxpbWl0PScgKyBjb3VudCwgbnVsbCwgdGhpcy5nZXRIZWFkZXJzKCkpO1xuICB9XG5cblxuICBwcml2YXRlIGFwaUdldChlbmRwb2ludDogc3RyaW5nLCBwYXJhbXMsIGhlYWRlcnMpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldCh0aGlzLmJhc2VVcmwgKyBlbmRwb2ludCwge1xuICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgICAgd2l0aENyZWRlbnRpYWxzOiBmYWxzZVxuICAgIH0pLnRvUHJvbWlzZSgpXG4gIH1cblxuICBwcml2YXRlIGFwaVBvc3QoZW5kcG9pbnQ6IHN0cmluZywgZGF0YSwgaGVhZGVycykge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdCh0aGlzLmJhc2VVcmwgKyBlbmRwb2ludCwgZGF0YSwge1xuICAgICAgaGVhZGVyczogaGVhZGVycyxcbiAgICB9KVxuICAgICAgLnRvUHJvbWlzZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRIZWFkZXJzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnQXV0aG9yaXphdGlvbic6ICdCZWFyZXIgJyArIHRoaXMudG9rZW4sXG4gICAgICAnQWNjZXB0JzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgIH1cbiAgfVxufVxuIl19