@alauda-fe/common
Version:
Alauda frontend team common codes.
112 lines • 24.8 kB
JavaScript
/**
* @packageDocumentation
* @module permission
*/
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { forkJoin, of, map, switchMap } from 'rxjs';
import { K8sApiResourceService, getApiPrefixParts } from '../api/public-api';
import { K8sResourceAction, API_GATEWAY, ifExist, publishRef, } from '../core/public-api';
import { isAllowed } from './helpers';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common/http";
import * as i2 from "../api/public-api";
export class K8sPermissionService {
constructor(http, k8sApiResource) {
this.http = http;
this.k8sApiResource = k8sApiResource;
this.getAccess = this.getAccess.bind(this);
this.isAllowed = this.isAllowed.bind(this);
}
getAccess(typeOrResourceParams) {
let params;
let group;
let type$;
if ('resource' in typeOrResourceParams) {
const { advanced: resourceAdvanced, project: resourceProject, cluster: resourceCluster, resource, action, } = typeOrResourceParams;
params = {
advanced: resourceAdvanced,
project: resourceProject,
cluster: resourceCluster,
namespace: resource.metadata.namespace,
name: resource.metadata.name,
action,
};
group = getApiPrefixParts(resource.apiVersion).apiGroup;
type$ = this.k8sApiResource.getResourceType(resource, resourceCluster);
}
else {
params = typeOrResourceParams;
const definitionSource = 'definition' in params && params.definition
? params.definition
: params.type;
const { apiGroup, type } = this.k8sApiResource.getDefinition(definitionSource);
group = apiGroup;
type$ = of(type);
}
const { advanced, project, cluster, namespace, name, action, subResource } = params;
const isNameArray = Array.isArray(name);
const isActionArray = Array.isArray(action);
const isArray = isNameArray && isActionArray;
const names = (isNameArray ? name : [name]);
const actions = (isActionArray ? action : [action]);
return type$.pipe(switchMap(type => forkJoin(names.map(name => of(actions).pipe(switchMap(actionList => forkJoin(actionList.map(action => this._getAccess({
action,
project,
cluster,
group,
name,
namespace,
type,
advanced,
subResource,
})))))))), map(accesses => isArray
? accesses
: isActionArray
? accesses[0]
: isNameArray
? accesses.map(accessGroup => accessGroup[0])
: accesses[0][0]), publishRef());
}
isAllowed(typeOrResourceParams) {
if (('name' in typeOrResourceParams &&
Array.isArray(typeOrResourceParams.name)) ||
(typeOrResourceParams.action !== K8sResourceAction.ALL &&
!Array.isArray(typeOrResourceParams.action) &&
typeOrResourceParams.transform == null)) {
typeOrResourceParams.transform = false;
}
// @ts-expect-error
return this.getAccess(typeOrResourceParams).pipe(isAllowed(typeOrResourceParams.transform));
}
// @internal
_getAccess({ action, project, cluster, group, name, namespace, type, advanced, subResource, }) {
return this.http.post(`${API_GATEWAY}${advanced
? '/auth'
: `${ifExist(cluster, `/kubernetes/${cluster}`)}/apis/authorization.k8s.io`}/v1/selfsubjectaccessreviews`, {
apiVersion: 'authorization.k8s.io/v1',
kind: 'SelfSubjectAccessReview',
spec: {
resourceAttributes: {
namespace,
verb: action || (name ? K8sResourceAction.GET : K8sResourceAction.LIST),
group,
resource: type,
name,
cluster: advanced ? cluster : undefined,
project: advanced ? project : undefined,
...(subResource ? { subResource } : {}),
},
},
});
}
static { this.ɵfac = function K8sPermissionService_Factory(t) { return new (t || K8sPermissionService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.K8sApiResourceService)); }; }
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: K8sPermissionService, factory: K8sPermissionService.ɵfac, providedIn: 'root' }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(K8sPermissionService, [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], () => [{ type: i1.HttpClient }, { type: i2.K8sApiResourceService }], null); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiazhzLXBlcm1pc3Npb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvY29tbW9uL3NyYy9wZXJtaXNzaW9uL2s4cy1wZXJtaXNzaW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFjLFFBQVEsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVoRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM3RSxPQUFPLEVBRUwsaUJBQWlCLEVBR2pCLFdBQVcsRUFDWCxPQUFPLEVBQ1AsVUFBVSxHQUNYLE1BQU0sb0JBQW9CLENBQUM7QUFFNUIsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFdBQVcsQ0FBQzs7OztBQXNCdEMsTUFBTSxPQUFPLG9CQUFvQjtJQUMvQixZQUNtQixJQUFnQixFQUNoQixjQUFxQztRQURyQyxTQUFJLEdBQUosSUFBSSxDQUFZO1FBQ2hCLG1CQUFjLEdBQWQsY0FBYyxDQUF1QjtRQUV0RCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQTBERCxTQUFTLENBQ1Asb0JBRXFDO1FBRXJDLElBQUksTUFBa0MsQ0FBQztRQUN2QyxJQUFJLEtBQWEsQ0FBQztRQUNsQixJQUFJLEtBQXlCLENBQUM7UUFDOUIsSUFBSSxVQUFVLElBQUksb0JBQW9CLEVBQUUsQ0FBQztZ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QkFBa0IsRUFBRTtvQkFDbEIsU0FBUztvQkFDVCxJQUFJLEVBQ0YsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQztvQkFDbkUsS0FBSztvQkFDTCxRQUFRLEVBQUUsSUFBSTtvQkFDZCxJQUFJO29CQUNKLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUztvQkFDdkMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTO29CQUN2QyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7aUJBQ3hDO2FBQ0Y7U0FDRixDQUNGLENBQUM7SUFDSixDQUFDO3FGQXRTVSxvQkFBb0I7dUVBQXBCLG9CQUFvQixXQUFwQixvQkFBb0IsbUJBRm5CLE1BQU07O2lGQUVQLG9CQUFvQjtjQUhoQyxVQUFVO2VBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICogQG1vZHVsZSBwZXJtaXNzaW9uXG4gKi9cblxuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGZvcmtKb2luLCBvZiwgbWFwLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgSzhzQXBpUmVzb3VyY2VTZXJ2aWNlLCBnZXRBcGlQcmVmaXhQYXJ0cyB9IGZyb20gJy4uL2FwaS9wdWJsaWMtYXBpJztcbmltcG9ydCB7XG4gIElmRXF1YWwsXG4gIEs4c1Jlc291cmNlQWN0aW9uLFxuICBLdWJlcm5ldGVzUmVzb3VyY2UsXG4gIFNlbGZTdWJqZWN0QWNjZXNzUmV2aWV3LFxuICBBUElfR0FURVdBWSxcbiAgaWZFeGlzdCxcbiAgcHVibGlzaFJlZixcbn0gZnJvbSAnLi4vY29yZS9wdWJsaWMtYXBpJztcblxuaW1wb3J0IHsgaXNBbGxvd2VkIH0gZnJvbSAnLi9oZWxwZXJzJztcbmltcG9ydCB7XG4gIEFsbFBlcm1pc3Npb25zLFxuICBLOHNQZXJtaXNzaW9uVHJhbnNmb3JtYWJsZSxcbiAgSzhzUmVzb3VyY2VQZXJtaXNzaW9uTXVsdGlQYXJhbXMsXG4gIEs4c1Jlc291cmNlUGVybWlzc2lvbk5vbmVQYXJhbXMsXG4gIEs4c1Jlc291cmNlUGVybWlzc2lvblBhcmFtcyxcbiAgSzhzUmVzb3VyY2VQZXJtaXNzaW9uU2luZ2xlUGFyYW1zLFxuICBLOHNSZXNvdXJjZVBlcm1pc3Npb25XaXRoVHJhbnNmb3JtUGFyYW1zLFxuICBLOHNUeXBlUGVybWlzc2lvbkFjdGlvbnNQYXJhbXMsXG4gIEs4c1R5cGVQZXJtaXNzaW9uTWF0cml4UGFyYW1zLFxuICBLOHNUeXBlUGVybWlzc2lvbk11bHRpUGFyYW1zLFxuICBLOHNUeXBlUGVybWlzc2lvbk5hbWVzUGFyYW1zLFxuICBLOHNUeXBlUGVybWlzc2lvbk5vbmVQYXJhbXMsXG4gIEs4c1R5cGVQZXJtaXNzaW9uUGFyYW1zLFxuICBLOHNUeXBlUGVybWlzc2lvblNpbmdsZVBhcmFtcyxcbiAgSzhzVHlwZVBlcm1pc3Npb25XaXRoVHJhbnNmb3JtUGFyYW1zLFxufSBmcm9tICcuL3R5cGVzJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIEs4c1Blcm1pc3Npb25TZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgazhzQXBpUmVzb3VyY2U6IEs4c0FwaVJlc291cmNlU2VydmljZSxcbiAgKSB7XG4gICAgdGhpcy5nZXRBY2Nlc3MgPSB0aGlzLmdldEFjY2Vzcy5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaXNBbGxvd2VkID0gdGhpcy5pc0FsbG93ZWQuYmluZCh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDojrflj5blr7kgSzhzIOi1hOa6kOeahOaTjeS9nOadg+mZkO+8jOS4gOiIrOWSjCBpc0FsbG93ZWQg6YWN5ZCI5L2/55SoXG4gICAqL1xuXG4gIC8qKlxuICAgKiDmoLnmja7lt7LmnIkgSzhzIOi1hOa6kO+8jOS4jeS8oOWFpSBhY3Rpb24g5oiW5Li6IG51bGwg5pe26buY6K6k5Y+WIGdldCDmk43kvZzmnYPpmZBcbiAgICovXG4gIGdldEFjY2VzczxcbiAgICBLIGV4dGVuZHMgS3ViZXJuZXRlc1Jlc291cmNlLFxuICAgIFQgZXh0ZW5kcyBLOHNSZXNvdXJjZUFjdGlvbiA9IEs4c1Jlc291cmNlQWN0aW9uLkdFVCxcbiAgPihcbiAgICBwYXJhbXM6IEs4c1Jlc291cmNlUGVybWlzc2lvbk5vbmVQYXJhbXM8Sz4sXG4gICk6IE9ic2VydmFibGU8U2VsZlN1YmplY3RBY2Nlc3NSZXZpZXc8VD4+O1xuXG4gIC8qKlxuICAgKiDmoLnmja7lt7LmnIkgSzhzIOi1hOa6kO+8jOi/m+ihjOWNleS4quaMh+WumiBhY3Rpb24g5pON5L2c5p2D6ZmQXG4gICAqL1xuICBnZXRBY2Nlc3M8VCBleHRlbmRzIEs4c1Jlc291cmNlQWN0aW9uLCBLIGV4dGVuZHMgS3ViZXJuZXRlc1Jlc291cmNlPihcbiAgICBwYXJhbXM6IEs4c1Jlc291cmNlUGVybWlzc2lvblNpbmdsZVBhcmFtczxLLCBUPixcbiAgKTogT2JzZXJ2YWJsZTxTZWxmU3ViamVjdEFjY2Vzc1JldmlldzxUPj47XG5cbiAgLyoqXG4gICAqIOagueaNruW3suaciSBLOHMg6LWE5rqQ77yM6L+b6KGM5aSa5Liq5oyH5a6aIGFjdGlvbiDmk43kvZzmnYPpmZDliJfooahcbiAgICovXG4gIGdldEFjY2VzczxUIGV4dGVuZHMgSzhzUmVzb3VyY2VBY3Rpb24sIEsgZXh0ZW5kcyBLdWJlcm5ldGVzUmVzb3VyY2U+KFxuICAgIHBhcmFtczogSzhzUmVzb3VyY2VQZXJtaXNzaW9uTXVsdGlQYXJhbXM8SywgVD4sXG4gICk6IE9ic2VydmFibGU8QXJyYXk8U2VsZlN1YmplY3RBY2Nlc3NSZXZpZXc8VD4+PjtcblxuICAvKipcbiAgICog5qC55o2uIEs4cyDotYTmupDnsbvlnovvvIzkuI3kvKDlhaUgYWN0aW9uIOaIluS4uiBudWxsIOaXtum7mOiupOWPliBsaXN0IOaTjeS9nOadg+mZkFxuICAgKi9cbiAgZ2V0QWNjZXNzKFxuICAgIHBhcmFtczogSzhzVHlwZVBlcm1pc3Npb25Ob25lUGFyYW1zLFxuICApOiBPYnNlcnZhYmxlPFNlbGZTdWJqZWN0QWNjZXNzUmV2aWV3PEs4c1Jlc291cmNlQWN0aW9uLkxJU1Q+PjtcblxuICAvKipcbiAgICog5qC55o2uIEs4cyDotYTmupDnsbvlnovlkozlkI3np7Dov5vooYzljZXkuKrmjIflrpogYWN0aW9uIOaTjeS9nOadg+mZkO+8jOm7mOiupOWPliBnZXQg5pON5L2c5p2D6ZmQXG4gICAqL1xuICBnZXRBY2Nlc3M8VCBleHRlbmRzIEs4c1Jlc291cmNlQWN0aW9uID0gSzhzUmVzb3VyY2VBY3Rpb24uR0VUPihcbiAgICBwYXJhbXM6IEs4c1R5cGVQZXJtaXNzaW9uU2luZ2xlUGFyYW1zPFQ+LFxuICApOiBPYnNlcnZhYmxlPFNlbGZTdWJqZWN0QWNjZXNzUmV2aWV3PFQ+PjtcblxuICAvKipcbiAgICog5qC55o2uIEs4cyDotYTmupDnsbvlnovvvIzov5vooYzlpJrkuKrmjIflrpogYWN0aW9uIOaTjeS9nOaIluiAheWkmuS4quWQjeensOeahOadg+mZkOWIl+ihqFxuICAgKi9cbiAgZ2V0QWNjZXNzPFQgZXh0ZW5kcyBLOHNSZXNvdXJjZUFjdGlvbj4oXG4gICAgcGFyYW1zOiBLOHNUeXBlUGVybWlzc2lvbk11bHRpUGFyYW1zPFQ+LFxuICApOiBPYnNlcnZhYmxlPEFycmF5PFNlbGZTdWJqZWN0QWNjZXNzUmV2aWV3PFQ+Pj47XG5cbiAgLyoqXG4gICAqIOagueaNriBLOHMg6LWE5rqQ57G75Z6L77yM6L+b6KGM5aSa5Liq5oyH5a6aIGFjdGlvbiDmk43kvZzlkozlpJrkuKrlkI3np7DnmoTmnYPpmZDkuozkvY3mlbDnu4TliJfooahcbiAgICovXG4gIGdldEFjY2VzczxUIGV4dGVuZHMgSzhzUmVzb3VyY2VBY3Rpb24+KFxuICAgIHBhcmFtczogSzhzVHlwZVBlcm1pc3Npb25NYXRyaXhQYXJhbXM8VD4sXG4gICk6IE9ic2VydmFibGU8QXJyYXk8QXJyYXk8U2VsZlN1YmplY3RBY2Nlc3NSZXZpZXc8VD4+Pj47XG5cbiAgZ2V0QWNjZXNzPFQgZXh0ZW5kcyBLOHNSZXNvdXJjZUFjdGlvbiwgSyBleHRlbmRzIEt1YmVybmV0ZXNSZXNvdXJjZT4oXG4gICAgdHlwZU9yUmVzb3VyY2VQYXJhbXM6XG4gICAgICB8IEs4c1R5cGVQZXJtaXNzaW9uUGFyYW1zPFQ+XG4gICAgICB8IEs4c1Jlc291cmNlUGVybWlzc2lvblBhcmFtczxLLCBUPixcbiAgKSB7XG4gICAgbGV0IHBhcmFtczogSzhzVHlwZVBlcm1pc3Npb25QYXJhbXM8VD47XG4gICAgbGV0IGdyb3VwOiBzdHJpbmc7XG4gICAgbGV0IHR5cGUkOiBPYnNlcnZhYmxlPHN0cmluZz47XG4gICAgaWYgKCdyZXNvdXJjZScgaW4gdHlwZU9yUmVzb3VyY2VQYXJhbXMpIHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgYWR2YW5jZWQ6IHJlc291cmNlQWR2YW5jZWQsXG4gICAgICAgIHByb2plY3Q6IHJlc291cmNlUHJvamVjdCxcbiAgICAgICAgY2x1c3RlcjogcmVzb3VyY2VDbHVzdGVyLFxuICAgICAgICByZXNvdXJjZSxcbiAgICAgICAgYWN0aW9uLFxuICAgICAgfSA9IHR5cGVPclJlc291cmNlUGFyYW1zO1xuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBhZHZhbmNlZDogcmVzb3VyY2VBZHZhbmNlZCxcbiAgICAgICAgcHJvamVjdDogcmVzb3VyY2VQcm9qZWN0LFxuICAgICAgICBjbHVzdGVyOiByZXNvdXJjZUNsdXN0ZXIsXG4gICAgICAgIG5hbWVzcGFjZTogcmVzb3VyY2UubWV0YWRhdGEubmFtZXNwYWNlLFxuICAgICAgICBuYW1lOiByZXNvdXJjZS5tZXRhZGF0YS5uYW1lLFxuICAgICAgICBhY3Rpb24sXG4gICAgICB9IGFzIEs4c1R5cGVQZXJtaXNzaW9uUGFyYW1zPFQ+O1xuICAgICAgZ3JvdXAgPSBnZXRBcGlQcmVmaXhQYXJ0cyhyZXNvdXJjZS5hcGlWZXJzaW9uKS5hcGlHcm91cDtcbiAgICAgIHR5cGUkID0gdGhpcy5rOHNBcGlSZXNvdXJjZS5nZXRSZXNvdXJjZVR5cGUocmVzb3VyY2UsIHJlc291cmNlQ2x1c3Rlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcmFtcyA9IHR5cGVPclJlc291cmNlUGFyYW1zO1xuICAgICAgY29uc3QgZGVmaW5pdGlvblNvdXJjZSA9XG4gICAgICAgICdkZWZpbml0aW9uJyBpbiBwYXJhbXMgJiYgcGFyYW1zLmRlZmluaXRpb25cbiAgICAgICAgICA/IHBhcmFtcy5kZWZpbml0aW9uXG4gICAgICAgICAgOiBwYXJhbXMudHlwZTtcbiAgICAgIGNvbnN0IHsgYXBpR3JvdXAsIHR5cGUgfSA9XG4gICAgICAgIHRoaXMuazhzQXBpUmVzb3VyY2UuZ2V0RGVmaW5pdGlvbihkZWZpbml0aW9uU291cmNlKTtcbiAgICAgIGdyb3VwID0gYXBpR3JvdXA7XG4gICAgICB0eXBlJCA9IG9mKHR5cGUpO1xuICAgIH1cbiAgICBjb25zdCB7IGFkdmFuY2VkLCBwcm9qZWN0LCBjbHVzdGVyLCBuYW1lc3BhY2UsIG5hbWUsIGFjdGlvbiwgc3ViUmVzb3VyY2UgfSA9XG4gICAgICBwYXJhbXM7XG4gICAgY29uc3QgaXNOYW1lQXJyYXkgPSBBcnJheS5pc0FycmF5KG5hbWUpO1xuICAgIGNvbnN0IGlzQWN0aW9uQXJyYXkgPSBBcnJheS5pc0FycmF5KGFjdGlvbik7XG4gICAgY29uc3QgaXNBcnJheSA9IGlzTmFtZUFycmF5ICYmIGlzQWN0aW9uQXJyYXk7XG4gICAgY29uc3QgbmFtZXMgPSAoaXNOYW1lQXJyYXkgPyBuYW1lIDogW25hbWVdKSBhcyBzdHJpbmdbXTtcbiAgICBjb25zdCBhY3Rpb25zID0gKGlzQWN0aW9uQXJyYXkgPyBhY3Rpb24gOiBbYWN0aW9uXSkgYXMgVFtdO1xuICAgIHJldHVybiB0eXBlJC5waXBlKFxuICAgICAgc3dpdGNoTWFwKHR5cGUgPT5cbiAgICAgICAgZm9ya0pvaW4oXG4gICAgICAgICAgbmFtZXMubWFwKG5hbWUgPT5cbiAgICAgICAgICAgIG9mKGFjdGlvbnMpLnBpcGUoXG4gICAgICAgICAgICAgIHN3aXRjaE1hcChhY3Rpb25MaXN0ID0+XG4gICAgICAgICAgICAgICAgZm9ya0pvaW4oXG4gICAgICAgICAgICAgICAgICBhY3Rpb25MaXN0Lm1hcChhY3Rpb24gPT5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2V0QWNjZXNzPFQ+KHtcbiAgICAgICAgICAgICAgICAgICAgICBhY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgICAgcHJvamVjdCxcbiAgICAgICAgICAgICAgICAgICAgICBjbHVzdGVyLFxuICAgICAgICAgICAgICAgICAgICAgIGdyb3VwLFxuICAgICAgICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlLFxuICAgICAgICAgICAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgYWR2YW5jZWQsXG4gICAgICAgICAgICAgICAgICAgICAgc3ViUmVzb3VyY2UsXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICAgIG1hcChhY2Nlc3NlcyA9PlxuICAgICAgICBpc0FycmF5XG4gICAgICAgICAgPyBhY2Nlc3Nlc1xuICAgICAgICAgIDogaXNBY3Rpb25BcnJheVxuICAgICAgICAgICAgPyBhY2Nlc3Nlc1swXVxuICAgICAgICAgICAgOiBpc05hbWVBcnJheVxuICAgICAgICAgICAgICA/IGFjY2Vzc2VzLm1hcChhY2Nlc3NHcm91cCA9PiBhY2Nlc3NHcm91cFswXSlcbiAgICAgICAgICAgICAgOiBhY2Nlc3Nlc1swXVswXSxcbiAgICAgICksXG4gICAgICBwdWJsaXNoUmVmKCksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDmoLnmja7lt7Lnu4/ojrflj5bliLDnmoTmk43kvZzmnYPpmZDlr7nosaHmiJbliJfooajovazljJbkuLrmm7Tmlrnkvr/kvb/nlKjnmoTmnYPpmZAgcmVjb3JkIOaIluaVsOe7hFxuICAgKi9cblxuICAvKipcbiAgICog5qC55o2u5bey5pyJIEs4cyDotYTmupDvvIzkuI3kvKDlhaUgYWN0aW9uIOaIluS4uiBudWxsIOaXtui9rOWMluS4uiBib29sZWFuXG4gICAqL1xuICBpc0FsbG93ZWQ8VCBleHRlbmRzIEs4c1Jlc291cmNlQWN0aW9uLCBLIGV4dGVuZHMgS3ViZXJuZXRlc1Jlc291cmNlPihcbiAgICBwYXJhbXM6XG4gICAgICB8IEs4c1Jlc291cmNlUGVybWlzc2lvbk5vbmVQYXJhbXM8Sz5cbiAgICAgIHwgSzhzUmVzb3VyY2VQZXJtaXNzaW9uU2luZ2xlUGFyYW1zPEssIFQ+LFxuICApOiBPYnNlcnZhYmxlPGJvb2xlYW4+O1xuXG4gIC8qKlxuICAgKiDmoLnmja7lt7LmnIkgSzhzIOi1hOa6kO+8jOWkmuS4qiBhY3Rpb24g6buY6K6k6L2s5Li6IHJlY29yZO+8jGB0cmFuc2Zvcm0gPT09IGZhbHNlYCDml7bovazkuLogYGJvb2xlYW5bXWBcbiAgICovXG4gIGlzQWxsb3dlZDxcbiAgICBUIGV4dGVuZHMgSzhzUmVzb3VyY2VBY3Rpb24sXG4gICAgSyBleHRlbmRzIEt1YmVybmV0ZXNSZXNvdXJjZSxcbiAgICBSIGV4dGVuZHMgYm9vbGVhbiA9IHRydWUsXG4gID4oXG4gICAgcGFyYW1zOiBLOHNSZXNvdXJjZVBlcm1pc3Npb25NdWx0aVBhcmFtczxLLCBUPiAmXG4gICAgICBQYXJ0aWFsPEs4c1Blcm1pc3Npb25UcmFuc2Zvcm1hYmxlPFI+PixcbiAgKTogT2JzZXJ2YWJsZTxJZkVxdWFsPFIsIGZhbHNlLCBib29sZWFuW10sIFJlY29yZDxULCBib29sZWFuPj4+O1xuXG4gIC8qKlxuICAgKiDmoLnmja4gSzhzIOi1hOa6kOexu+Wei++8jOS4jeS8oOWFpSBhY3Rpb24vbmFtZSDmiJbkuLogbnVsbCDml7bvvIzpu5jorqTlj5YgZ2V0IOadg+mZkO+8jOiHquWKqOi9rOWMluS4uiBib29sZWFu77yMYHRyYW5zZm9ybSAhPT0gZmFsc2VgIOaXtui9rOWMluS4uiByZWNvcmRcbiAgICovXG4gIGlzQWxsb3dlZDxcbiAgICBUIGV4dGVuZHMgSzhzUmVzb3VyY2VBY3Rpb24gPSBLOHNSZXNvdXJjZUFjdGlvbi5HRVQsXG4gICAgSyBleHRlbmRzIGJvb2xlYW4gPSBmYWxzZSxcbiAgPihcbiAgICBwYXJhbXM6IEs4c1R5cGVQZXJtaXNzaW9uTm9uZVBhcmFtcyAmXG4gICAgICBQYXJ0aWFsPEs4c1Blcm1pc3Npb25UcmFuc2Zvcm1hYmxlPEs+PixcbiAgKTogT2JzZXJ2YWJsZTxJZkVxdWFsPEssIGZhbHNlLCBib29sZWFuLCBSZWNvcmQ8VCwgYm9vbGVhbj4+PjtcblxuICAvKipcbiAgICog5qC55o2uIEs4cyDotYTmupDnsbvlnovvvIzkvKDlhaXljZXkuKogYWN0aW9uIOaIliBuYW1lIOaXtu+8jGBhY3Rpb24gPT09IEFMTCgqKWAg5pe26Ieq5Yqo6L2s5YyW5Li65omA5pyJ5p2D6ZmQ55qEIHJlY29yZO+8jOWQpuWImei9rOWMluS4uiBgYm9vbGVhbmBcbiAgICovXG4gIGlzQWxsb3dlZDxUIGV4dGVuZHMgSzhzUmVzb3VyY2VBY3Rpb24+KFxuICAgIHBhcmFtczogSzhzVHlwZVBlcm1pc3Npb25TaW5nbGVQYXJhbXM8VD4sXG4gICk6IE9ic2VydmFibGU8SWZFcXVhbDxULCBLOHNSZXNvdXJjZUFjdGlvbi5BTEwsIEFsbFBlcm1pc3Npb25zLCBib29sZWFuPj47XG5cbiAgLyoqXG4gICAqIOagueaNriBLOHMg6LWE5rqQ57G75Z6L77yM5Lyg5YWl5Y2V5LiqIGFjdGlvbiDmiJYgbmFtZSDml7bvvIzoh6rliqjovazljJbkuLogcmVjb3Jk77yMYHRyYW5zZm9ybSA9PT0gZmFsc2VgIOaXtui9rOWMluS4uiBgYm9vbGVhbmBcbiAgICovXG4gIGlzQWxsb3dlZDxUIGV4dGVuZHMgSzhzUmVzb3VyY2VBY3Rpb24sIEsgZXh0ZW5kcyBib29sZWFuPihcbiAgICBwYXJhbXM6IEs4c1R5cGVQZXJtaXNzaW9uU2luZ2xlUGFyYW1zPFQ+ICYgSzhzUGVybWlzc2lvblRyYW5zZm9ybWFibGU8Sz4sXG4gICk6IE9ic2VydmFibGU8XG4gICAgSWZFcXVhbDxcbiAgICAgIEssXG4gICAgICBmYWxzZSxcbiAgICAgIGJvb2xlYW4sXG4gICAgICBJZkVxdWFsPFQsIEs4c1Jlc291cmNlQWN0aW9uLkFMTCwgQWxsUGVybWlzc2lvbnMsIFJlY29yZDxULCBib29sZWFuPj5cbiAgICA+XG4gID47XG5cbiAgLyoqXG4gICAqIOagueaNriBLOHMg6LWE5rqQ57G75Z6L77yM5Lyg5YWl5aSa5LiqIGFjdGlvbiDml7bvvIzoh6rliqjovazljJbkuLogcmVjb3Jk77yMYHRyYW5zZm9ybSA9PT0gZmFsc2VgIOaXtui9rOWMluS4uiBgYm9vbGVhbltdYFxuICAgKi9cbiAgaXNBbGxvd2VkPFQgZXh0ZW5kcyBLOHNSZXNvdXJjZUFjdGlvbiwgSyBleHRlbmRzIGJvb2xlYW4gPSB0cnVlPihcbiAgICBwYXJhbXM6IEs4c1R5cGVQZXJtaXNzaW9uQWN0aW9uc1BhcmFtczxUPiAmXG4gICAgICBQYXJ0aWFsPEs4c1Blcm1pc3Npb25UcmFuc2Zvcm1hYmxlPEs+PixcbiAgKTogT2JzZXJ2YWJsZTxJZkVxdWFsPEssIGZhbHNlLCBib29sZWFuW10sIFJlY29yZDxULCBib29sZWFuPj4+O1xuXG4gIC8qKlxuICAgKiDmoLnmja4gSzhzIOi1hOa6kOexu+Wei++8jOS8oOWFpeWkmuS4qiBuYW1lIOaXtu+8jOiHquWKqOi9rOWMluS4uiBgYm9vbGVhbltdYFxuICAgKi9cbiAgaXNBbGxvd2VkPFQgZXh0ZW5kcyBLOHNSZXNvdXJjZUFjdGlvbj4oXG4gICAgcGFyYW1zOiBLOHNUeXBlUGVybWlzc2lvbk5hbWVzUGFyYW1zPFQ+LFxuICApOiBPYnNlcnZhYmxlPGJvb2xlYW5bXT47XG5cbiAgaXNBbGxvd2VkPFxuICAgIFQgZXh0ZW5kcyBLOHNSZXNvdXJjZUFjdGlvbixcbiAgICBLIGV4dGVuZHMgS3ViZXJuZXRlc1Jlc291cmNlLFxuICAgIFIgZXh0ZW5kcyBib29sZWFuID0gdHJ1ZSxcbiAgPihcbiAgICB0eXBlT3JSZXNvdXJjZVBhcmFtczpcbiAgICAgIHwgSzhzVHlwZVBlcm1pc3Npb25XaXRoVHJhbnNmb3JtUGFyYW1zPFQsIFI+XG4gICAgICB8IEs4c1Jlc291cmNlUGVybWlzc2lvbldpdGhUcmFuc2Zvcm1QYXJhbXM8SywgVCwgUj4sXG4gICk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgaWYgKFxuICAgICAgKCduYW1lJyBpbiB0eXBlT3JSZXNvdXJjZVBhcmFtcyAmJlxuICAgICAgICBBcnJheS5pc0FycmF5KHR5cGVPclJlc291cmNlUGFyYW1zLm5hbWUpKSB8fFxuICAgICAgKHR5cGVPclJlc291cmNlUGFyYW1zLmFjdGlvbiAhPT0gSzhzUmVzb3VyY2VBY3Rpb24uQUxMICYmXG4gICAgICAgICFBcnJheS5pc0FycmF5KHR5cGVPclJlc291cmNlUGFyYW1zLmFjdGlvbikgJiZcbiAgICAgICAgdHlwZU9yUmVzb3VyY2VQYXJhbXMudHJhbnNmb3JtID09IG51bGwpXG4gICAgKSB7XG4gICAgICB0eXBlT3JSZXNvdXJjZVBhcmFtcy50cmFuc2Zvcm0gPSBmYWxzZSBhcyBSO1xuICAgIH1cbiAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgcmV0dXJuIHRoaXMuZ2V0QWNjZXNzKHR5cGVPclJlc291cmNlUGFyYW1zKS5waXBlKFxuICAgICAgaXNBbGxvd2VkKHR5cGVPclJlc291cmNlUGFyYW1zLnRyYW5zZm9ybSksXG4gICAgKTtcbiAgfVxuXG4gIC8vIEBpbnRlcm5hbFxuICBwcml2YXRlIF9nZXRBY2Nlc3M8VCBleHRlbmRzIEs4c1Jlc291cmNlQWN0aW9uPih7XG4gICAgYWN0aW9uLFxuICAgIHByb2plY3QsXG4gICAgY2x1c3RlcixcbiAgICBncm91cCxcbiAgICBuYW1lLFxuICAgIG5hbWVzcGFjZSxcbiAgICB0eXBlLFxuICAgIGFkdmFuY2VkLFxuICAgIHN1YlJlc291cmNlLFxuICB9OiB7XG4gICAgYWN0aW9uOiBUO1xuICAgIHByb2plY3Q/OiBzdHJpbmc7XG4gICAgY2x1c3Rlcj86IHN0cmluZztcbiAgICBncm91cD86IHN0cmluZztcbiAgICBuYW1lPzogc3RyaW5nO1xuICAgIG5hbWVzcGFjZT86IHN0cmluZztcbiAgICB0eXBlPzogc3RyaW5nO1xuICAgIGFkdmFuY2VkPzogYm9vbGVhbjtcbiAgICBzdWJSZXNvdXJjZT86IHN0cmluZztcbiAgfSkge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDxTZWxmU3ViamVjdEFjY2Vzc1JldmlldzxUPj4oXG4gICAgICBgJHtBUElfR0FURVdBWX0ke1xuICAgICAgICBhZHZhbmNlZFxuICAgICAgICAgID8gJy9hdXRoJ1xuICAgICAgICAgIDogYCR7aWZFeGlzdChcbiAgICAgICAgICAgICAgY2x1c3RlcixcblxuICAgICAgICAgICAgICBgL2t1YmVybmV0ZXMvJHtjbHVzdGVyfWAsXG4gICAgICAgICAgICApfS9hcGlzL2F1dGhvcml6YXRpb24uazhzLmlvYFxuICAgICAgfS92MS9zZWxmc3ViamVjdGFjY2Vzc3Jldmlld3NgLFxuICAgICAge1xuICAgICAgICBhcGlWZXJzaW9uOiAnYXV0aG9yaXphdGlvbi5rOHMuaW8vdjEnLFxuICAgICAgICBraW5kOiAnU2VsZlN1YmplY3RBY2Nlc3NSZXZpZXcnLFxuICAgICAgICBzcGVjOiB7XG4gICAgICAgICAgcmVzb3VyY2VBdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICBuYW1lc3BhY2UsXG4gICAgICAgICAgICB2ZXJiOlxuICAgICAgICAgICAgICBhY3Rpb24gfHwgKG5hbWUgPyBLOHNSZXNvdXJjZUFjdGlvbi5HRVQgOiBLOHNSZXNvdXJjZUFjdGlvbi5MSVNUKSxcbiAgICAgICAgICAgIGdyb3VwLFxuICAgICAgICAgICAgcmVzb3VyY2U6IHR5cGUsXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgY2x1c3RlcjogYWR2YW5jZWQgPyBjbHVzdGVyIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgcHJvamVjdDogYWR2YW5jZWQgPyBwcm9qZWN0IDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgLi4uKHN1YlJlc291cmNlID8geyBzdWJSZXNvdXJjZSB9IDoge30pLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICk7XG4gIH1cbn1cbiJdfQ==