UNPKG

@fdot/edms-api-lib

Version:

The edms-api-lib package wraps service calls to FDOT EDMS API. ## Installation `npm install @fdot/edms-api-lib --save`

250 lines (249 loc) 27.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Injectable, Inject } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { throwError } from 'rxjs'; import { of } from 'rxjs'; import { Config } from '../models/Config'; import * as FineUploaderCore from 'fine-uploader/lib/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; export class EdmsService { /** * @param {?} httpClient * @param {?} config */ constructor(httpClient, config) { this.httpClient = httpClient; this.config = config; this.defaultPropertyMap = {}; if (!config) { throw Error('Call EdmsApiLibModule with for root passing in the config object'); } this.headers = { 'Ocp-Apim-Subscription-Key': config.apiKey }; this.httpOptions = { headers: new HttpHeaders(this.headers) }; } /** * @param {?} authTokenInputs * @return {?} */ getAuthToken(authTokenInputs) { /** @type {?} */ const url = `${this.config.host}/api/authenticationToken`; /** @type {?} */ const body = { server: authTokenInputs.server, library: authTokenInputs.library, userId: authTokenInputs.userId, password: authTokenInputs.password }; return this.httpClient.post(url, body, this.httpOptions) .pipe(map((response) => { this.token = response; return response; })); } /** * @return {?} */ getBusinessAreas() { if (!this.token) return throwError("Please call Get Auth Token before making additional calls to establish a security token"); /** @type {?} */ const url = `${this.config.host}/api/businessAreas?authenticationToken=${this.token}`; return this.httpClient.get(url, this.httpOptions) .pipe(map((response) => { return response; })); } /** * @param {?} businessArea * @return {?} */ getDocumentGroupsByBusinessArea(businessArea) { if (!this.token) return throwError("Please call Get Auth Token before making additional calls to establish a security token"); /** @type {?} */ const url = `${this.config.host}/api/businessArea/${businessArea.SystemId}/documentGroups?authenticationToken=${this.token}`; return this.httpClient.get(url, this.httpOptions) .pipe(map((response) => { return response; })); } /** * @param {?} documentGroup * @return {?} */ getDocumentTypesByDocumentGroup(documentGroup) { if (!this.token) return throwError("Please call Get Auth Token before making additional calls to establish a security token"); /** @type {?} */ const url = `${this.config.host}/api/documentGroup/${documentGroup.SystemId}/documentTypes?authenticationToken=${this.token}`; return this.httpClient.get(url, this.httpOptions) .pipe(map((response) => { return response; })); } /** * @return {?} */ getDefaultPropertyData() { if (!this.token) return throwError("Please call Get Auth Token before making additional calls to establish a security token"); /** @type {?} */ var cachedValue = this.defaultPropertyMap[this.token]; if (cachedValue) { return of(Object.assign({}, cachedValue)); } /** @type {?} */ const url = `${this.config.host}/api/defaultPropertyData?authenticationToken=${this.token}`; return this.httpClient.get(url, this.httpOptions) .pipe(map((response) => { this.defaultPropertyMap[this.token] = Object.assign({}, response); return response; })); } /** * @param {?} file * @param {?} documentMetadata * @return {?} */ addNewDocument(file, documentMetadata) { if (!this.token) return throwError("Please call Get Auth Token before making additional calls to establish a security token"); if (file.size < this.config.uploadChunkThreshold) { return this.uploadDocumentWithOneRequest(file, documentMetadata); } else { return this.uploadDocumentInSimultaneousChunks(file, documentMetadata); } } /** * @param {?} file * @param {?} documentMetadata * @return {?} */ uploadDocumentInSimultaneousChunks(file, documentMetadata) { return Observable.create(observer => { /** @type {?} */ const completeCallback = (id, name, document, xhr) => { if (xhr.status != 200) { observer.error(xhr.response); } else { observer.next(document); observer.complete(); } }; /** @type {?} */ var chunkingSuccessOptions = { endpoint: `${this.config.host}/api/chunkComplete?authenticationToken=${this.token}`, jsonPayload: true, params: function (fileId) { return { documentMetadata, id: fineUploaderBasic.getUuid(fileId), totalParts: 3 }; } }; /** @type {?} */ var chunkingOptions = { enabled: true, partSize: this.config.uploadChunkSize, concurrent: { enabled: true }, paramNames: { partIndex: "partIndex", totalParts: "totalParts" }, success: chunkingSuccessOptions }; /** @type {?} */ var requestOptions = { customHeaders: this.headers, endpoint: `${this.config.host}/api/chunkNewDocument?authenticationToken=${this.token}`, filenameParam: 'filename', forceMultipart: true, omitDefaultParams: false, paramsInBody: true, uuidName: "id", inputName: "file" }; /** @type {?} */ var callbackOptions = { onComplete: (id, name, responseJSON, xhr) => completeCallback(id, name, responseJSON, xhr), onError: (id, name, errorReason, xhr) => { debugger; console.log(JSON.stringify(xhr)); } }; /** @type {?} */ var options = { maxConnections: 6, multiple: false, chunking: chunkingOptions, request: requestOptions, callbacks: callbackOptions, autoUpload: false, debug: true }; /** @type {?} */ var fineUploaderBasic = new FineUploaderCore.FineUploaderBasic(options); fineUploaderBasic.addFiles([file]); fineUploaderBasic.uploadStoredFiles(); }); } /** * @param {?} file * @param {?} documentMetadata * @return {?} */ uploadDocumentWithOneRequest(file, documentMetadata) { /** @type {?} */ const url = `${this.config.host}/api/addNewDocument?authenticationToken=${this.token}`; /** @type {?} */ const formData = new FormData(); formData.append('file', file, file.name); formData.append("metadata", JSON.stringify(documentMetadata)); return this.httpClient.post(url, formData, this.httpOptions).pipe(map((response) => { return response; })); } /** * @param {?} docId * @return {?} */ getDocumentDownloadUrl(docId) { return `${this.config.host}/api/document/${docId}?subscription-key=${this.config.apiKey}&authenticationToken=${this.token}`; } } EdmsService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ EdmsService.ctorParameters = () => [ { type: HttpClient }, { type: Config, decorators: [{ type: Inject, args: ['config',] }] } ]; /** @nocollapse */ EdmsService.ngInjectableDef = i0.defineInjectable({ factory: function EdmsService_Factory() { return new EdmsService(i0.inject(i1.HttpClient), i0.inject("config")); }, token: EdmsService, providedIn: "root" }); if (false) { /** @type {?} */ EdmsService.prototype.headers; /** @type {?} */ EdmsService.prototype.httpOptions; /** @type {?} */ EdmsService.prototype.token; /** @type {?} */ EdmsService.prototype.defaultPropertyMap; /** @type {?} */ EdmsService.prototype.httpClient; /** @type {?} */ EdmsService.prototype.config; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWRtc1NlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AZmRvdC9lZG1zLWFwaS1saWIvIiwic291cmNlcyI6WyJsaWIvc2VydmljZXMvRWRtc1NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFL0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsQyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTFCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQVExQyxPQUFPLEtBQUssZ0JBQWdCLE1BQU0sd0JBQXdCLENBQUM7OztBQUszRCxNQUFNOzs7OztJQU9KLFlBQW9CLFVBQXNCLEVBQTRCLE1BQWM7UUFBaEUsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUE0QixXQUFNLEdBQU4sTUFBTSxDQUFRO2tDQUZiLEVBQUU7UUFHdkUsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNYLE1BQU0sS0FBSyxDQUFDLGtFQUFrRSxDQUFDLENBQUM7U0FDakY7UUFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzlELElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxPQUFPLEVBQUUsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7S0FDL0Q7Ozs7O0lBRU0sWUFBWSxDQUFDLGVBQWdDOztRQUNsRCxNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFN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QyxRQUFrQixFQUFFLEVBQUU7WUFDckIsT0FBTyxRQUFRLENBQUM7U0FDakIsQ0FBQyxDQUFDLENBQUM7Ozs7OztJQUdELHNCQUFzQixDQUFDLEtBQWE7UUFDekMsT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxpQkFBaUIsS0FBSyxxQkFBcUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7Ozs7WUFuTC9ILFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7OztZQW5CUSxVQUFVO1lBT1YsTUFBTSx1QkFvQmdDLE1BQU0sU0FBQyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBIZWFkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5cclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IHRocm93RXJyb3IgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgb2YgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IENvbmZpZyB9IGZyb20gJy4uL21vZGVscy9Db25maWcnO1xyXG5pbXBvcnQgeyBBdXRoVG9rZW5JbnB1dHMgfSBmcm9tICcuLi9tb2RlbHMvQXV0aFRva2VuSW5wdXRzJztcclxuaW1wb3J0IHsgQnVzaW5lc3NBcmVhIH0gZnJvbSAnLi4vbW9kZWxzL0J1c2luZXNzQXJlYSc7XHJcbmltcG9ydCB7IERvY3VtZW50RGF0YSB9IGZyb20gJy4uL21vZGVscy9Eb2N1bWVudERhdGEnO1xyXG5pbXBvcnQgeyBEb2N1bWVudEdyb3VwIH0gZnJvbSAnLi4vbW9kZWxzL0RvY3VtZW50R3JvdXAnO1xyXG5pbXBvcnQgeyBEb2N1bWVudFByb3BlcnR5IH0gZnJvbSAnLi4vbW9kZWxzL0RvY3VtZW50UHJvcGVydHknO1xyXG5pbXBvcnQgeyBEb2N1bWVudFR5cGUgfSBmcm9tICcuLi9tb2RlbHMvRG9jdW1lbnRUeXBlJztcclxuXHJcbmltcG9ydCAqIGFzIEZpbmVVcGxvYWRlckNvcmUgZnJvbSAnZmluZS11cGxvYWRlci9saWIvY29yZSc7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBFZG1zU2VydmljZSB7XHJcbiAgcHJpdmF0ZSBoZWFkZXJzO1xyXG4gIHByaXZhdGUgaHR0cE9wdGlvbnM7XHJcblxyXG4gIHByaXZhdGUgdG9rZW46IHN0cmluZztcclxuICBwcml2YXRlIGRlZmF1bHRQcm9wZXJ0eU1hcDogeyBbdG9rZW46IHN0cmluZ106IERvY3VtZW50UHJvcGVydHlbXTsgfSA9IHt9O1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHBDbGllbnQ6IEh0dHBDbGllbnQsIEBJbmplY3QoJ2NvbmZpZycpIHByaXZhdGUgY29uZmlnOiBDb25maWcpIHtcclxuICAgIGlmICghY29uZmlnKSB7XHJcbiAgICAgIHRocm93IEVycm9yKCdDYWxsIEVkbXNBcGlMaWJNb2R1bGUgd2l0aCBmb3Igcm9vdCBwYXNzaW5nIGluIHRoZSBjb25maWcgb2JqZWN0Jyk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmhlYWRlcnMgPSB7ICdPY3AtQXBpbS1TdWJzY3JpcHRpb24tS2V5JzogY29uZmlnLmFwaUtleSB9O1xyXG4gICAgdGhpcy5odHRwT3B0aW9ucyA9IHsgaGVhZGVyczogbmV3IEh0dHBIZWFkZXJzKHRoaXMuaGVhZGVycykgfTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXRBdXRoVG9rZW4oYXV0aFRva2VuSW5wdXRzOiBBdXRoVG9rZW5JbnB1dHMpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5jb25maWcuaG9zdH0vYXBpL2F1dGhlbnRpY2F0aW9uVG9rZW5gO1xyXG4gICAgY29uc3QgYm9keSA9IHtcclxuICAgICAgc2VydmVyOiBhdXRoVG9rZW5JbnB1dHMuc2VydmVyLFxyXG4gICAgICBsaWJyYXJ5OiBhdXRoVG9rZW5JbnB1dHMubGlicmFyeSxcclxuICAgICAgdXNlcklkOiBhdXRoVG9rZW5JbnB1dHMudXNlcklkLFxyXG4gICAgICBwYXNzd29yZDogYXV0aFRva2VuSW5wdXRzLnBhc3N3b3JkXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cENsaWVudC5wb3N0PHN0cmluZz4odXJsLCBib2R5LCB0aGlzLmh0dHBPcHRpb25zKVxyXG4gICAgICAucGlwZShtYXAoXHJcbiAgICAgICAgKHJlc3BvbnNlOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgIHRoaXMudG9rZW4gPSByZXNwb25zZTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0QnVzaW5lc3NBcmVhcygpOiBPYnNlcnZhYmxlPEJ1c2luZXNzQXJlYVtdPiB7XHJcbiAgICBpZiAoIXRoaXMudG9rZW4pIHJldHVybiB0aHJvd0Vycm9yKFwiUGxlYXNlIGNhbGwgR2V0IEF1dGggVG9rZW4gYmVmb3JlIG1ha2luZyBhZGRpdGlvbmFsIGNhbGxzIHRvIGVzdGFibGlzaCBhIHNlY3VyaXR5IHRva2VuXCIpO1xyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5jb25maWcuaG9zdH0vYXBpL2J1c2luZXNzQXJlYXM/YXV0aGVudGljYXRpb25Ub2tlbj0ke3RoaXMudG9rZW59YDtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldDxCdXNpbmVzc0FyZWFbXT4odXJsLCB0aGlzLmh0dHBPcHRpb25zKVxyXG4gICAgICAucGlwZShtYXAoXHJcbiAgICAgICAgKHJlc3BvbnNlOiBCdXNpbmVzc0FyZWFbXSkgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXREb2N1bWVudEdyb3Vwc0J5QnVzaW5lc3NBcmVhKGJ1c2luZXNzQXJlYTogQnVzaW5lc3NBcmVhKTogT2JzZXJ2YWJsZTxEb2N1bWVudEdyb3VwW10+IHtcclxuICAgIGlmICghdGhpcy50b2tlbikgcmV0dXJuIHRocm93RXJyb3IoXCJQbGVhc2UgY2FsbCBHZXQgQXV0aCBUb2tlbiBiZWZvcmUgbWFraW5nIGFkZGl0aW9uYWwgY2FsbHMgdG8gZXN0YWJsaXNoIGEgc2VjdXJpdHkgdG9rZW5cIik7XHJcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmNvbmZpZy5ob3N0fS9hcGkvYnVzaW5lc3NBcmVhLyR7YnVzaW5lc3NBcmVhLlN5c3RlbUlkfS9kb2N1bWVudEdyb3Vwcz9hdXRoZW50aWNhdGlvblRva2VuPSR7dGhpcy50b2tlbn1gO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cENsaWVudC5nZXQ8RG9jdW1lbnRHcm91cFtdPih1cmwsIHRoaXMuaHR0cE9wdGlvbnMpXHJcbiAgICAgIC5waXBlKG1hcChcclxuICAgICAgICAocmVzcG9uc2U6IERvY3VtZW50R3JvdXBbXSkgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXREb2N1bWVudFR5cGVzQnlEb2N1bWVudEdyb3VwKGRvY3VtZW50R3JvdXA6IERvY3VtZW50R3JvdXApOiBPYnNlcnZhYmxlPERvY3VtZW50VHlwZVtdPiB7XHJcbiAgICBpZiAoIXRoaXMudG9rZW4pIHJldHVybiB0aHJvd0Vycm9yKFwiUGxlYXNlIGNhbGwgR2V0IEF1dGggVG9rZW4gYmVmb3JlIG1ha2luZyBhZGRpdGlvbmFsIGNhbGxzIHRvIGVzdGFibGlzaCBhIHNlY3VyaXR5IHRva2VuXCIpO1xyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5jb25maWcuaG9zdH0vYXBpL2RvY3VtZW50R3JvdXAvJHtkb2N1bWVudEdyb3VwLlN5c3RlbUlkfS9kb2N1bWVudFR5cGVzP2F1dGhlbnRpY2F0aW9uVG9rZW49JHt0aGlzLnRva2VufWA7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldDxEb2N1bWVudFR5cGVbXT4odXJsLCB0aGlzLmh0dHBPcHRpb25zKVxyXG4gICAgICAucGlwZShtYXAoKHJlc3BvbnNlOiBEb2N1bWVudEdyb3VwKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICB9KSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0RGVmYXVsdFByb3BlcnR5RGF0YSgpOiBPYnNlcnZhYmxlPERvY3VtZW50UHJvcGVydHlbXT4ge1xyXG4gICAgaWYgKCF0aGlzLnRva2VuKSByZXR1cm4gdGhyb3dFcnJvcihcIlBsZWFzZSBjYWxsIEdldCBBdXRoIFRva2VuIGJlZm9yZSBtYWtpbmcgYWRkaXRpb25hbCBjYWxscyB0byBlc3RhYmxpc2ggYSBzZWN1cml0eSB0b2tlblwiKTtcclxuICAgIHZhciBjYWNoZWRWYWx1ZSA9IHRoaXMuZGVmYXVsdFByb3BlcnR5TWFwW3RoaXMudG9rZW5dO1xyXG4gICAgaWYgKGNhY2hlZFZhbHVlKSB7XHJcbiAgICAgIHJldHVybiBvZih7IC4uLmNhY2hlZFZhbHVlIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuY29uZmlnLmhvc3R9L2FwaS9kZWZhdWx0UHJvcGVydHlEYXRhP2F1dGhlbnRpY2F0aW9uVG9rZW49JHt0aGlzLnRva2VufWA7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldDxEb2N1bWVudFByb3BlcnR5W10+KHVybCwgdGhpcy5odHRwT3B0aW9ucylcclxuICAgICAgLnBpcGUobWFwKFxyXG4gICAgICAgIChyZXNwb25zZTogRG9jdW1lbnRQcm9wZXJ0eVtdKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmRlZmF1bHRQcm9wZXJ0eU1hcFt0aGlzLnRva2VuXSA9IHsgLi4ucmVzcG9uc2UgfTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9XHJcbiAgICAgICkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFkZE5ld0RvY3VtZW50KGZpbGU6IEZpbGUsIGRvY3VtZW50TWV0YWRhdGE6IERvY3VtZW50RGF0YSk6IE9ic2VydmFibGU8RG9jdW1lbnQ+IHtcclxuICAgIGlmICghdGhpcy50b2tlbikgcmV0dXJuIHRocm93RXJyb3IoXCJQbGVhc2UgY2FsbCBHZXQgQXV0aCBUb2tlbiBiZWZvcmUgbWFraW5nIGFkZGl0aW9uYWwgY2FsbHMgdG8gZXN0YWJsaXNoIGEgc2VjdXJpdHkgdG9rZW5cIik7XHJcblxyXG4gICAgaWYgKGZpbGUuc2l6ZSA8IHRoaXMuY29uZmlnLnVwbG9hZENodW5rVGhyZXNob2xkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnVwbG9hZERvY3VtZW50V2l0aE9uZVJlcXVlc3QoZmlsZSwgZG9jdW1lbnRNZXRhZGF0YSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRoaXMudXBsb2FkRG9jdW1lbnRJblNpbXVsdGFuZW91c0NodW5rcyhmaWxlLCBkb2N1bWVudE1ldGFkYXRhKTtcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwbG9hZERvY3VtZW50SW5TaW11bHRhbmVvdXNDaHVua3MoZmlsZTogRmlsZSwgZG9jdW1lbnRNZXRhZGF0YTogRG9jdW1lbnREYXRhKTogT2JzZXJ2YWJsZTxEb2N1bWVudD4ge1xyXG5cclxuICAgIHJldHVybiBPYnNlcnZhYmxlLmNyZWF0ZShvYnNlcnZlciA9PiB7XHJcbiAgICAgIGNvbnN0IGNvbXBsZXRlQ2FsbGJhY2sgPSAoaWQ6IG51bWJlciwgbmFtZTogc3RyaW5nLCBkb2N1bWVudDogRG9jdW1lbnQsIHhocjogWE1MSHR0cFJlcXVlc3QpOiB2b2lkID0+IHtcclxuICAgICAgICBpZiAoeGhyLnN0YXR1cyAhPSAyMDApIHtcclxuICAgICAgICAgIG9ic2VydmVyLmVycm9yKHhoci5yZXNwb25zZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIubmV4dChkb2N1bWVudCk7XHJcbiAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBjaHVua2luZ1N1Y2Nlc3NPcHRpb25zOiBGaW5lVXBsb2FkZXJDb3JlLlN1Y2Nlc3NPcHRpb25zID0ge1xyXG4gICAgICAgIGVuZHBvaW50OiBgJHt0aGlzLmNvbmZpZy5ob3N0fS9hcGkvY2h1bmtDb21wbGV0ZT9hdXRoZW50aWNhdGlvblRva2VuPSR7dGhpcy50b2tlbn1gLFxyXG4gICAgICAgIGpzb25QYXlsb2FkOiB0cnVlLFxyXG4gICAgICAgIHBhcmFtczogZnVuY3Rpb24gKGZpbGVJZDogbnVtYmVyKSB7XHJcbiAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBkb2N1bWVudE1ldGFkYXRhLFxyXG4gICAgICAgICAgICBpZDogZmluZVVwbG9hZGVyQmFzaWMuZ2V0VXVpZChmaWxlSWQpLFxyXG4gICAgICAgICAgICB0b3RhbFBhcnRzOiAzXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgY2h1bmtpbmdPcHRpb25zOiBGaW5lVXBsb2FkZXJDb3JlLkNodW5raW5nT3B0aW9ucyA9IHtcclxuICAgICAgICBlbmFibGVkOiB0cnVlLFxyXG4gICAgICAgIHBhcnRTaXplOiB0aGlzLmNvbmZpZy51cGxvYWRDaHVua1NpemUsXHJcbiAgICAgICAgY29uY3VycmVudDogeyBlbmFibGVkOiB0cnVlIH0sXHJcbiAgICAgICAgcGFyYW1OYW1lczoge1xyXG4gICAgICAgICAgcGFydEluZGV4OiBcInBhcnRJbmRleFwiLFxyXG4gICAgICAgICAgdG90YWxQYXJ0czogXCJ0b3RhbFBhcnRzXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHN1Y2Nlc3M6IGNodW5raW5nU3VjY2Vzc09wdGlvbnNcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciByZXF1ZXN0T3B0aW9uczogRmluZVVwbG9hZGVyQ29yZS5SZXF1ZXN0T3B0aW9ucyA9IHtcclxuICAgICAgICBjdXN0b21IZWFkZXJzOiB0aGlzLmhlYWRlcnMsXHJcbiAgICAgICAgZW5kcG9pbnQ6IGAke3RoaXMuY29uZmlnLmhvc3R9L2FwaS9jaHVua05ld0RvY3VtZW50P2F1dGhlbnRpY2F0aW9uVG9rZW49JHt0aGlzLnRva2VufWAsXHJcbiAgICAgICAgZmlsZW5hbWVQYXJhbTogJ2ZpbGVuYW1lJyxcclxuICAgICAgICBmb3JjZU11bHRpcGFydDogdHJ1ZSxcclxuICAgICAgICBvbWl0RGVmYXVsdFBhcmFtczogZmFsc2UsXHJcbiAgICAgICAgcGFyYW1zSW5Cb2R5OiB0cnVlLFxyXG4gICAgICAgIHV1aWROYW1lOiBcImlkXCIsXHJcbiAgICAgICAgaW5wdXROYW1lOiBcImZpbGVcIlxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgY2FsbGJhY2tPcHRpb25zOiBGaW5lVXBsb2FkZXJDb3JlLkNvcmVFdmVudHMgPSB7XHJcbiAgICAgICAgb25Db21wbGV0ZTogKGlkOiBudW1iZXIsIG5hbWU6IHN0cmluZywgcmVzcG9uc2VKU09OOiBhbnksIHhocjogWE1MSHR0cFJlcXVlc3QpID0+IGNvbXBsZXRlQ2FsbGJhY2soaWQsIG5hbWUsIHJlc3BvbnNlSlNPTiwgeGhyKSxcclxuICAgICAgICBvbkVycm9yOiAoaWQ6IG51bWJlciwgbmFtZTogc3RyaW5nLCBlcnJvclJlYXNvbjogc3RyaW5nLCB4aHI6IFhNTEh0dHBSZXF1ZXN0KSA9PiB7XHJcbiAgICAgICAgICBkZWJ1Z2dlcjtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHhocikpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIG9wdGlvbnM6IEZpbmVVcGxvYWRlckNvcmUuQ29yZU9wdGlvbnMgPSB7XHJcbiAgICAgICAgbWF4Q29ubmVjdGlvbnM6IDYsXHJcbiAgICAgICAgbXVsdGlwbGU6IGZhbHNlLFxyXG4gICAgICAgIGNodW5raW5nOiBjaHVua2luZ09wdGlvbnMsXHJcbiAgICAgICAgcmVxdWVzdDogcmVxdWVzdE9wdGlvbnMsXHJcbiAgICAgICAgY2FsbGJhY2tzOiBjYWxsYmFja09wdGlvbnMsXHJcbiAgICAgICAgYXV0b1VwbG9hZDogZmFsc2UsXHJcbiAgICAgICAgZGVidWc6IHRydWVcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBmaW5lVXBsb2FkZXJCYXNpYyA9IG5ldyBGaW5lVXBsb2FkZXJDb3JlLkZpbmVVcGxvYWRlckJhc2ljKG9wdGlvbnMpO1xyXG5cclxuICAgICAgZmluZVVwbG9hZGVyQmFzaWMuYWRkRmlsZXMoW2ZpbGVdKTtcclxuICAgICAgZmluZVVwbG9hZGVyQmFzaWMudXBsb2FkU3RvcmVkRmlsZXMoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGxvYWREb2N1bWVudFdpdGhPbmVSZXF1ZXN0KGZpbGU6IEZpbGUsIGRvY3VtZW50TWV0YWRhdGE6IERvY3VtZW50RGF0YSk6IE9ic2VydmFibGU8RG9jdW1lbnQ+IHtcclxuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuY29uZmlnLmhvc3R9L2FwaS9hZGROZXdEb2N1bWVudD9hdXRoZW50aWNhdGlvblRva2VuPSR7dGhpcy50b2tlbn1gO1xyXG4gICAgY29uc3QgZm9ybURhdGE6IEZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XHJcbiAgICBmb3JtRGF0YS5hcHBlbmQoJ2ZpbGUnLCBmaWxlLCBmaWxlLm5hbWUpO1xyXG4gICAgZm9ybURhdGEuYXBwZW5kKFwibWV0YWRhdGFcIiwgSlNPTi5zdHJpbmdpZnkoZG9jdW1lbnRNZXRhZGF0YSkpO1xyXG5cclxuICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQucG9zdDxEb2N1bWVudD4odXJsLCBmb3JtRGF0YSwgdGhpcy5odHRwT3B0aW9ucykucGlwZShtYXAoXHJcbiAgICAgIChyZXNwb25zZTogRG9jdW1lbnQpID0+IHtcclxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgIH0pKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXREb2N1bWVudERvd25sb2FkVXJsKGRvY0lkOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGAke3RoaXMuY29uZmlnLmhvc3R9L2FwaS9kb2N1bWVudC8ke2RvY0lkfT9zdWJzY3JpcHRpb24ta2V5PSR7dGhpcy5jb25maWcuYXBpS2V5fSZhdXRoZW50aWNhdGlvblRva2VuPSR7dGhpcy50b2tlbn1gO1xyXG4gIH1cclxufSJdfQ==